The recipes are the docs' worked examples for things every real app needs, and the best-practices pages are the docs' own checklists. Interviewers like them because they have a canonical answer: "how would you add auth to a Nuxt app" has a documented recipe, and answering with it (then improving on it) is the ideal shape.
router.options.ts (routes(defaultRoutes) returning a new array), with the pages:extend hook in nuxt.config (push, filter or rename route records), or from a module with extendPages. Router options: router.options.ts (full Vue Router options, functions allowed) or router.options in nuxt.config (JSON-serialisable only: hashMode, scrollBehaviorType: 'smooth', linkActiveClass, strict, sensitive). Hash mode only makes sense with ssr: false; smooth scrolling to hash links via scrollBehaviorType.$fetch.create({ baseURL, onRequest (adds the Authorizationheader from the session), onResponseError (401 →navigateTo('/login')) }) and provides it as $api; a useAPI composable wraps useFetch(url, { ...options, $fetch: useNuxtApp().$api }). The newer macro form is export const useAPI = createUseFetch({ baseURL }) in composables/.routeRules: { '/**': { prerender: true, noScripts: true } } prerenders everything and ships no JavaScript; NuxtLink then renders plain anchors (full page loads between script-free routes); islands (.server.vue) for server-rendered widgets; lazy hydration for the few interactive parts on routes that keep scripts.npx nuxt module add auth-utils; set NUXT_SESSION_PASSWORD (32+ characters; generated in dev); a login route server/api/login.post.ts validates the body (readValidatedBody with zod) and calls setUserSession(event, { user }); the login page uses useUserSession() (loggedIn, user, fetch, clear); protect API routes with requireUserSession(event) (401) and app routes with middleware redirecting when !loggedIn.value. Sessions are sealed, encrypted cookies.vite.plugins in nuxt.config; in a module use addVitePlugin.<NuxtRouteAnnouncer> (and <NuxtAnnouncer> for in-page changes), a page title per page (useHead/useSeoMeta), semantic links with <NuxtLink>, focus management on navigation, and scroll behaviour that respects users; resources include the WAI-ARIA authoring practices and the a11y module ecosystem..devcontainer/devcontainer.json with a Node image, forwarded port 3000 and a postCreateCommand installing dependencies; open via the VS Code prompt, the command palette, or the devcontainer CLI.NuxtLink prefetching, hybrid rendering, Lazy components, lazy hydration, data fetching with pick/transform; the core modules @nuxt/image, @nuxt/fonts, @nuxt/scripts; profile with nuxt analyze, Nuxt DevTools and Chrome DevTools.parallel so they do not block the rest.https://nuxt.com/llms.txt (index) and https://nuxt.com/llms-full.txt (everything), plus .md on any docs URL or Accept: text/markdown; add them to Cursor, Windsurf or any tool that accepts documentation URLs.https://nuxt.com/mcp (streamable HTTP) with tools for documentation search, blog, deployment guides, modules and changelog, resources and prompts; setup snippets for ChatGPT, Claude Code, Claude Desktop and Cursor; tools can be limited per client.The auth recipe end to end, compressed:
import { z } from 'zod'
const body = z.object({ email: z.string().email(), password: z.string().min(8) })
export default defineEventHandler(async (event) => {
const { email, password } = await readValidatedBody(event, body.parse)
const user = await verifyCredentials(email, password) // your own lookup + verifyPassword
if (!user) throw createError({ status: 401, statusText: 'Bad credentials' })
await setUserSession(event, { user: { id: user.id, name: user.name } })
return {}
})
export default defineEventHandler(async (event) => {
const { user } = await requireUserSession(event) // 401 when missing
return useDb().accounts.forUser(user.id)
})
export default defineNuxtRouteMiddleware(() => {
const { loggedIn } = useUserSession()
if (!loggedIn.value) return navigateTo('/login')
})
The custom fetch recipe in its macro form, and the mostly-static configuration:
export const useAPI = createUseFetch({
baseURL: '/api',
onResponseError({ response }) {
if (response.status === 401) navigateTo('/login')
},
})
export default defineNuxtConfig({
routeRules: {
'/**': { prerender: true, noScripts: true }, // static HTML, zero JS
'/app/**': { prerender: false, noScripts: false }, // the interactive part keeps its scripts
},
})
On a route rendered with noScripts, there is no router in the browser, so NuxtLink renders a plain anchor and navigation is a full page load. Mixing script-free and interactive routes therefore costs a reload at the boundary, which the docs call out as the trade-off to accept deliberately.
The current nuxt-auth-utils API names in the recipe (setUserSession, requireUserSession, useUserSession) and the session password requirement.
curl and confirm the 401.$api recipe to createUseFetch and compare the generated types of both composables.<script> tags."I would start from the documented recipe with nuxt-auth-utils: a sealed, encrypted cookie session keyed by NUXT_SESSION_PASSWORD, a login API route that validates the body and calls setUserSession, useUserSession on the client for loggedIn, user and clear, requireUserSession inside every protected server route so the API is the real gate, and a route middleware that redirects anonymous users for the user experience. From there I would add password hashing with the module's helpers or an OAuth provider, forward cookies during SSR with useRequestFetch, and make sure no personalised route is cached with swr."
Nothing yet. Notes filed here show up on this page and the section overview.
Going further
The Going Further chapters — Experimental Features and their flags, Features and the future namespace, How Nuxt Works, Runtime Config, the Nightly Release Channel, Lifecycle Hooks, Layers, NuxtApp, Debugging, Custom Events, Server Imports, Kit and Builders.
API — components
Every built-in Nuxt component from the API reference with its props, slots and rules — ClientOnly, DevOnly, NuxtClientFallback, NuxtPage, NuxtLayout, NuxtLink, NuxtLoadingIndicator, NuxtErrorBoundary, NuxtIsland, NuxtRouteAnnouncer, NuxtAnnouncer, NuxtTime, NuxtImg, NuxtPicture, NuxtWelcome and Teleport.