Nuxt
Nuxt is the meta-framework on top of Vue: server-side rendering, file-based routing, server endpoints, data fetching, hybrid rendering modes (SSR / SSG / ISR / SPA), and a module ecosystem. Reach for Nuxt when you build a real Vue app and want SEO, fast TTFB, and a clean server story.
A small Nuxt app: pages, fetch, server route, layout
EXAMPLE
// 1) Scaffold
// npx nuxi@latest init shop
// cd shop && npm install
// npm run dev
// 2) File-based routing — pages/ becomes routes
// pages/
// ├── index.vue -> /
// ├── products/
// │ ├── index.vue -> /products
// │ └── [sku].vue -> /products/:sku
// └── account/
// └── orders/[id].vue -> /account/orders/:id
// 3) Layout
// layouts/default.vue
<template>
<div>
<header class='border-b p-3'>
<NuxtLink to='/'>Shop</NuxtLink>
<NuxtLink to='/products' class='ml-4'>Products</NuxtLink>
</header>
<main class='p-4'>
<slot />
</main>
</div>
</template>
// pages/index.vue
<template>
<h1>Welcome</h1>
<p>Featured today: {{ featured.name }}</p>
</template>
<script setup>
// Data fetched on the SERVER for SSR, on the CLIENT for navigation
const { data: featured } = await useFetch('/api/featured');
</script>
// 4) Server endpoints — file-based, run on Node (or edge)
// server/api/featured.get.ts
export default defineEventHandler(async () => {
return { id: 'p1', name: 'Wool Jacket', price: 19900 };
});
// server/api/products/index.get.ts
export default defineEventHandler(async (event) => {
const query = getQuery(event);
const status = String(query.status ?? 'active');
// hit your DB here
return [{ sku: 'p1', name: 'Wool Jacket', status }];
});
// server/api/products/[sku].get.ts
export default defineEventHandler(async (event) => {
const sku = getRouterParam(event, 'sku');
// hit your DB here
if (!sku) throw createError({ statusCode: 400, message: 'sku required' });
return { sku, name: 'Wool Jacket', price: 19900 };
});
// 5) Dynamic page with data fetching
// pages/products/[sku].vue
<template>
<h1>{{ product.name }}</h1>
<p>{{ product.price / 100 }}</p>
</template>
<script setup>
const route = useRoute();
const { data: product, error } = await useFetch('/api/products/' + route.params.sku);
if (error.value) throw createError({ statusCode: 404, message: 'Not found' });
</script>
// 6) Composable for shared logic
// composables/useCart.ts
import { ref, computed } from 'vue';
const items = ref<{ sku: string; qty: number; priceCents: number }[]>([]);
export const useCart = () => ({
items,
count: computed(() => items.value.reduce((s, i) => s + i.qty, 0)),
add(sku: string, priceCents: number, qty = 1) {
const found = items.value.find((i) => i.sku === sku);
if (found) found.qty += qty;
else items.value.push({ sku, qty, priceCents });
},
});
// 7) Middleware (auth gate)
// middleware/auth.global.ts
export default defineNuxtRouteMiddleware((to) => {
if (to.path.startsWith('/account')) {
const user = useState('user');
if (!user.value) return navigateTo('/login?next=' + encodeURIComponent(to.fullPath));
}
});
// 8) Rendering modes per route
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true }, // SSG
'/blog/**': { isr: 3600 }, // ISR (revalidate hourly)
'/products/**': { swr: 600 }, // SWR
'/api/**': { cors: true },
'/account/**': { ssr: true, headers: { 'cache-control': 'no-store' } },
},
});
// 9) Modules — the Nuxt ecosystem
// npm install @nuxtjs/tailwindcss @nuxt/image @nuxtjs/i18n @nuxtjs/seo @sidebase/nuxt-auth
// nuxt.config.ts -> modules: ['@nuxtjs/tailwindcss', '@nuxt/image']
// 10) Deploy
// Vercel / Netlify / Cloudflare Pages: auto-detect Nuxt
// Self-host: 'nuxt build' -> output/ + start with 'node .output/server/index.mjs'
// Static: 'nuxt generate' -> dispatch/' static files for any CDN
// 11) Pitfalls
// - Using browser-only APIs in setup() that runs on the server
// -> guard with process.client or use onMounted
// - Calling fetch() instead of useFetch -> no server-side execution
// - Big bundles from missing route-level code splitting (Nuxt does it by default; verify)
// - Setting cookies via document.cookie (set them via the server response instead)
// 12) Decision matrix
// - SEO matters? SSR via Nuxt
// - Static content? Nuxt + prerender
// - Need server endpoints? Nuxt server/api
// - Edge runtime? Nuxt + Cloudflare deploy
// - Just a SPA? Nuxt is overkill; vue create + vite
Why it matters
Nuxt is the Vue equivalent of Next.js in 2026 — file-based routing, SSR by default, hybrid render modes per route, and a clean server/api story. Reach for it whenever the app is more than a small SPA; the SEO + TTFB win + the developer experience pay for the framework cost within a week.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
// pages/index.vue
<script setup>
const { data } = await useFetch('/api/users');
</script>
<template>
<ul><li v-for="u in data" :key="u.id">{{ u.name }}</li></ul>
</template>
Try it Yourself »
Discussion
Loading…