Nuxt: The Vue Full-Stack Framework

Nuxt is the open-source full-stack framework for Vue: file-based routing, SSR, static generation and the Nitro server. How it works and what Nuxt 4 is.

What is Nuxt?

Nuxt is the open-source full-stack framework built on Vue.js. Vue is the UI library; Nuxt adds what a production app needs around it: file-based routing, server-side rendering, static generation, server API endpoints, build tooling and deployment. It plays the same role for Vue that Next.js plays for React and SvelteKit for Svelte.

Nuxt 4 is the current stable major version: it was released on 15 July 2025. It is built on Vue 3, Vite and the Nitro server engine, and keeps application code in an app/ directory by default. Nitro can output a Node.js server or a build for several hosting platforms, selected with a preset.

How Nuxt works

A request reaches a Nitro server. For a page, Nuxt renders the Vue component to HTML on the server (server-side rendering), sends it, and the browser then hydrates it into an interactive app. The same project can also pre-render routes at build time (static site generation) or run as a client-only single page app, and you can mix these per route.

Project structure

my-app/
├── app/
│   ├── pages/            # file-based routing
│   │   ├── index.vue     # /
│   │   └── blog/[slug].vue  # /blog/:slug
│   ├── components/       # auto-imported
│   ├── composables/      # auto-imported
│   ├── layouts/default.vue
│   └── app.vue
├── server/
│   └── api/posts.get.ts  # GET /api/posts
├── public/
└── nuxt.config.ts

Routing and data fetching

Every .vue file in pages/ becomes a route; [slug] makes a dynamic parameter. Data loading uses composables that work on both server and client:

<script setup lang="ts">
const route = useRoute();
const { data: post } = await useFetch(`/api/posts/${route.params.slug}`);
</script>
ComposableUse case
useFetchFetch a URL during render, with SSR and caching handled for you
useAsyncDataWrap any async function with the same caching
$fetchPlain HTTP call, no render integration; use for events and actions
useStateSSR-safe shared state

Server API routes

Files under server/api/ become endpoints, and the HTTP method comes from the file name (posts.get.ts, posts.post.ts, [id].delete.ts). You do not need a separate Express server for a typical backend.

// server/api/posts/[slug].get.ts
export default defineEventHandler(async (event) => {
  const slug = getRouterParam(event, 'slug');
  const post = await db.post.findUnique({ where: { slug } });
  if (!post) throw createError({ statusCode: 404, message: 'Not found' });
  return post;
});

Rendering modes

Nuxt renders on the server by default (universal rendering). Set ssr: false for client-only rendering, or choose per route with routeRules. For a fully static site run nuxt generate.

// nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true },          // built once, served static
    '/dashboard/**': { ssr: false },   // client-side only
    '/blog/**': { isr: 60 }            // ISR: CDN-cached where the host supports it
  }
});

Nuxt vs Next.js vs SvelteKit

NuxtNext.jsSvelteKit
Based onVue 3ReactSvelte
Server engineNitroNext.js runtimeAdapters
Auto-importsYes, by defaultNoNo
File-based routingYesYesYes

All three cover the same ground, so the real choice is the UI library your team already knows.

Common mistakes

  • Fetching with $fetch during render. The server fetches, the client fetches again and the page flickers or double-loads. Use useFetch or useAsyncData for render-time data.
  • Using browser-only APIs on the server. window and localStorage do not exist during SSR; guard them or run them in onMounted.
  • Hydration mismatches. Random values, dates or locale-dependent output that differ between server and client produce warnings and extra work.
  • Uncached SSR on hot pages. Rendering on every request is CPU work. Cache with routeRules (swr, isr) or prerender what does not change.

Load testing a Nuxt app

SSR moves rendering onto your server, so traffic costs CPU there, not only bandwidth. Test the rendered pages and the /api routes separately, with a ramp that matches real traffic, and watch response time percentiles rather than averages. LoadFocus load testing runs JMeter and k6 scripts from 25+ cloud regions; for the client-heavy side see load testing single page applications.

FAQ: Nuxt

Should I use Nuxt 4 or Nuxt 3?

Start new projects on Nuxt 4, stable since 15 July 2025. Existing Nuxt 3 apps can migrate step by step; the main changes are the app/ directory layout and data-fetching behavior, and the official upgrade guide covers both.

Nuxt or plain Vue?

Plain Vue fits a single page app you control end to end. Choose Nuxt when you need server rendering, static generation, SEO-critical pages or ready-made conventions.

Can Nuxt run on Cloudflare Workers?

Yes. Nitro has Cloudflare presets (cloudflare_module for Workers, cloudflare_pages for Pages), set with nitro.preset or the NITRO_PRESET variable at build time.

Can I build a static site with Nuxt?

Yes. Run nuxt generate to pre-render routes into static files.

What is the difference between useFetch and $fetch?

useFetch integrates with rendering: it fetches once on the server, passes the result to the client and caches it. $fetch is a plain call without that handling.

Does Nuxt support TypeScript?

Yes, with generated types for routes and server APIs.

How fast is your website?

Elevate its speed and SEO seamlessly with our Free Speed Test.

Free Website Speed Test

Analyze your website's load speed and improve its performance with our free page speed checker.