Nuxt.js
Standard full-stack framework in Vue.js ecosystem. Strongly supports large-scale application development with Composition API and TypeScript integration.
GitHub Overview
nuxt/nuxt
The Intuitive Vue Framework.
Repository:https://github.com/nuxt/nuxt
Homepage:https://nuxt.com
Stars57,911
Watchers787
Forks5,339
Created:October 26, 2016
Language:TypeScript
License:MIT License
Topics
csrframeworkfull-stackhacktoberfesthybridnodenuxtserver-renderingssgssrstatic-site-generatoruniversalvue
Star History
Data as of: 8/13/2025, 01:43 AM
Framework
Nuxt.js
Overview
Nuxt.js is a free and open-source full-stack web framework built on Vue.js. It's designed for creating type-safe, performant, and production-grade web applications and websites. The framework aims to simplify web development by providing conventions and automation, allowing developers to focus on features.
Details
Key Features
- Multiple Rendering Modes: Supports various rendering strategies including Server-Side Rendering (SSR) by default, Static Site Generation (SSG), Hybrid Rendering, and Edge-Side Rendering
- File-based Routing: Routes are automatically generated based on the structure of your
pages/
directory, simplifying route configuration - Code Splitting: Automatically splits code into smaller chunks to reduce initial load times
- Auto-imports: Vue composables, components, and utilities can be used without explicit imports, benefiting from tree-shaking and optimized JS bundles
- Data Fetching Utilities: Provides composables for SSR-compatible data fetching
- Zero-config TypeScript Support: Built-in TypeScript support with auto-generated types
- Configured Build Tools: Uses Vite by default for hot module replacement (HMR) in development and optimized production builds. Also supports Webpack and Rspack as alternative bundlers
- Server Engine (Nitro): A server engine that enables full-stack capabilities, API routes, serverless support, and cross-platform deployment
Architecture
Nuxt.js adopts a modular architecture, allowing you to select and use only the features you need. The framework's core integrates proven tools such as Vue.js, Vue Router, Vite/Webpack, h3, and Nitro.
Pros and Cons
Benefits
- Excellent SEO: Server-side rendering allows search engines to better index pages as HTML content is immediately available
- Faster Initial Page Load Time: SSR sends a fully rendered HTML page to the browser, improving perceived load time and user experience
- Better Performance on Low-Powered Devices: Reduces the amount of JavaScript needed on the client-side
- Better Accessibility: Content is immediately available, aiding assistive technologies
- Easier Caching: Pages can be cached on the server-side, further improving performance
- Developer Experience: Automation, conventions, and features like auto-imports and zero-config TypeScript enhance development speed
- Full-stack Capabilities: With its
server/
directory and Nitro engine, Nuxt allows building both frontend and backend functionalities within a single framework - Flexible Rendering: Fine-grained control over performance and deployment with universal rendering (SSR), client-side rendering (CSR), hybrid rendering with route rules, and edge-side rendering
Drawbacks
- Development Constraints: Writing code that runs seamlessly on both server and browser environments can be tricky due to differing APIs
- Cost: Running a server for on-the-fly rendering adds a monthly cost, though this can be mitigated by leveraging edge-side rendering
- Learning Curve: Need to learn Nuxt.js-specific concepts and conventions in addition to Vue.js
- Over-engineering: Might be too feature-rich for simple SPAs
Key Links
Code Examples
Hello World
<!-- pages/index.vue -->
<template>
<div>
<h1>{{ title }}</h1>
<p>Welcome to Nuxt!</p>
</div>
</template>
<script setup>
// Composition API with auto-import
const title = 'Hello Nuxt!'
// Meta management
useHead({
title: 'Home',
meta: [
{ name: 'description', content: 'My amazing site.' }
]
})
</script>
Page Routing and Navigation
<!-- pages/about.vue -->
<template>
<div>
<h1>About Page</h1>
<NuxtLink to="/">Back to Home</NuxtLink>
<NuxtLink to="/products">Product List</NuxtLink>
</div>
</template>
<!-- pages/products/[id].vue - Dynamic Route -->
<template>
<div>
<h1>Product: {{ $route.params.id }}</h1>
<button @click="$router.back()">Back</button>
</div>
</template>
<script setup>
// Get parameters
const route = useRoute()
const productId = route.params.id
</script>
Data Fetching
<template>
<div>
<h1>User List</h1>
<div v-if="pending">Loading...</div>
<div v-else-if="error">Error: {{ error }}</div>
<ul v-else>
<li v-for="user in data" :key="user.id">
{{ user.name }} - {{ user.email }}
</li>
</ul>
<button @click="refresh()">Refresh</button>
</div>
</template>
<script setup>
// useFetch - SSR-compatible data fetching
const { data, pending, error, refresh } = await useFetch('/api/users')
// useLazyFetch - Asynchronous fetching
const { data: posts } = await useLazyFetch('/api/posts')
// $fetch - Manual fetching
const submitForm = async (formData) => {
try {
const result = await $fetch('/api/submit', {
method: 'POST',
body: formData
})
console.log('Submit success:', result)
} catch (error) {
console.error('Submit error:', error)
}
}
</script>
State Management (Pinia)
// stores/counter.js
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
function increment() {
count.value++
}
function reset() {
count.value = 0
}
return { count, doubleCount, increment, reset }
})
<!-- pages/counter.vue -->
<template>
<div>
<h1>Counter: {{ counter.count }}</h1>
<p>Double: {{ counter.doubleCount }}</p>
<button @click="counter.increment()">+1</button>
<button @click="counter.reset()">Reset</button>
</div>
</template>
<script setup>
const counter = useCounterStore()
</script>
Server API
// server/api/users.js
export default defineEventHandler(async (event) => {
const method = getMethod(event)
if (method === 'GET') {
// Get user list
return await getUsersFromDatabase()
}
if (method === 'POST') {
// Create new user
const body = await readBody(event)
return await createUser(body)
}
})
// server/api/users/[id].js
export default defineEventHandler(async (event) => {
const id = getRouterParam(event, 'id')
const method = getMethod(event)
if (method === 'GET') {
return await getUserById(id)
}
if (method === 'PUT') {
const body = await readBody(event)
return await updateUser(id, body)
}
if (method === 'DELETE') {
return await deleteUser(id)
}
})
Middleware and Authentication
// middleware/auth.js
export default defineNuxtRouteMiddleware((to, from) => {
const user = useAuthUser()
if (!user.value) {
return navigateTo('/login')
}
})
// middleware/admin.global.js - Global Middleware
export default defineNuxtRouteMiddleware((to) => {
if (to.path.startsWith('/admin')) {
const user = useAuthUser()
if (!user.value?.isAdmin) {
throw createError({
statusCode: 403,
statusMessage: 'Access Denied'
})
}
}
})
<!-- pages/profile.vue -->
<script setup>
// Apply middleware at page level
definePageMeta({
middleware: 'auth'
})
</script>