AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
Nuxt is a full-stack Vue framework designed for universal deployment. This skill provides essential guidance on Nuxt 5, covering its directory structure, file-based routing, server-side rendering, and Nitro-based server engine. It includes best practices for data fetching, state management, and modular architecture, helping developers leverage features like auto-imports and hybrid rendering.
What it does
- Explains the Nuxt 5 directory structure and configuration conventions.
- Details file-based routing, including typed and case-sensitive routes.
- Provides guidance on data fetching using useFetch and $fetch.
- Covers server-side rendering, hybrid rendering, and Nitro server integration.
- Explains how to extend applications using Nuxt Layers and modules.
- Outlines lifecycle hooks for build-time and runtime customization.
When to use it
- When starting a new full-stack project with Vue and Nuxt.
- When migrating existing projects to Nuxt 5 and Nitro v3.
- When implementing server-side rendering or hybrid rendering strategies.
- When creating reusable application layers or custom Nuxt modules.
- When optimizing data fetching patterns and state management in SSR environments.
Advantages
- Provides standardized patterns for Nuxt 5 development.
- Simplifies complex concepts like Nitro server integration and lifecycle hooks.
- Offers clear guidance on project structure and file-based routing.
- Supports efficient code reuse through the Nuxt Layers system.
Usage examples
- “How do I structure my Nuxt 5 project directory?”
- The agent explains the default app/ directory structure for Vue code and the root-level placement for server/, public/, and nuxt.config.ts files.
- “Explain how to use layers to share components between projects.”
- The agent provides instructions on using the extends property in nuxt.config.ts to import layers from local directories, git repositories, or npm packages.
- “How do I hook into the page navigation lifecycle?”
- The agent shows how to use nuxtApp.hook('page:finish', ...) within a plugin to execute code after navigation completes.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/antfu/nuxt/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip nuxt.zip -d .agents/skills
Documentation by Anthony Fu
Nuxt is a full-stack Vue framework that provides server-side rendering, file-based routing, auto-imports, and a powerful module system. It uses Nitro as its server engine for universal deployment across Node.js, serverless, and edge platforms.
The skill is based on Nuxt 5.x (
5.0.0-0), generated at 2026-11-05.
Directory layout: the default
srcDirisapp/— Vue app code (app.vue,components/,composables/,pages/, etc.) lives underapp/, whileserver/,shared/,public/,modules/,layers/andnuxt.config.tsstay at the project root. The~/@aliases point atapp/; use~~/@@for the root.
Nuxt 5 note: Nuxt 5 makes many former experimental flags the default. The biggest shifts for agents: server code moves to Nitro v3 (h3 v2, Web-standard
Request/Response), server utilities import fromnuxt/serverand are no longer auto-imported by default,$fetch/useFetchare typed from generated route types, routing is case-sensitive and typed by default, and the bundler is Vite 8 (Rolldown). Nuxt 5 requires Node22.19/24.11+. A Nitro v2 compatibility layer (nitroLegacy) keeps older server code building during migration. See individual references for details.
Core
| Topic | Description | Reference |
|---|---|---|
| Directory Structure | Nuxt 4 app/ srcDir, shared/, aliases, conventions | core-directory-structure |
| Configuration | nuxt.config.ts, app.config.ts, aliases, Nuxt 5 defaults, jiti removal, experimental | core-config |
| CLI Commands | Dev server, build, generate, preview, and utility commands | core-cli |
| Routing | File-based routing, case-sensitive + typed routes, named views, layout props, middleware | core-routing |
| Data Fetching | useFetch, useAsyncData, $fetch, typed routes, createUseFetch factories, caching | core-data-fetching |
| Modules | Creating and using Nuxt modules, Nuxt Kit utilities | core-modules |
| Deployment | Platform-agnostic deployment with Nitro, Vercel, Netlify, Cloudflare | core-deployment |
Features
| Topic | Description | Reference |
|---|---|---|
| Composables Auto-imports | Vue/Nuxt composables, custom composables, shared/, useAnnouncer | features-composables |
| Components Auto-imports | Component naming, lazy loading, hydration strategies | features-components-autoimport |
| Built-in Components | NuxtLink, NuxtPage, NuxtLayout, NuxtAnnouncer, ClientOnly, and more | features-components |
| State Management | useState composable, SSR-friendly state, Pinia integration | features-state |
| Server Routes | API routes, nuxt/server imports, Nitro v3 (h3 v2), sessions, middleware | features-server |
Rendering
| Topic | Description | Reference |
|---|---|---|
| Rendering Modes | Universal (SSR), client-side (SPA), hybrid rendering, route rules | rendering-modes |
Best Practices
| Topic | Description | Reference |
|---|---|---|
| Data Fetching Patterns | Efficient fetching, caching, parallel requests, error handling | best-practices-data-fetching |
| SSR & Hydration | Avoiding context leaks, hydration mismatches, composable patterns | best-practices-ssr |
Advanced
| Topic | Description | Reference |
|---|---|---|
| Layers | Extending applications with reusable layers | advanced-layers |
| Lifecycle Hooks | Build-time, runtime, and server hooks | advanced-hooks |
| Module Authoring | Publishable modules with Nuxt Kit, keyed composables, dependencies | advanced-module-authoring |
Files
- ATTRIBUTION.mdAdded by AutoGineer889 B
- GENERATION.md134 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md4.5 KiB
- references/advanced-hooks.md7.2 KiB
- references/advanced-layers.md5.1 KiB
- references/advanced-module-authoring.md16.5 KiB
- references/best-practices-data-fetching.md9.2 KiB
- references/best-practices-ssr.md7.5 KiB
- references/core-cli.md4.8 KiB
- references/core-config.md10.5 KiB
- references/core-data-fetching.md11.4 KiB
- references/core-deployment.md5.1 KiB
- references/core-directory-structure.md9.8 KiB
- references/core-modules.md5.4 KiB
- references/core-routing.md6.8 KiB
- references/features-components-autoimport.md5.9 KiB
- references/features-components.md6.1 KiB
- references/features-composables.md7.2 KiB
- references/features-server.md11.1 KiB
- references/features-state.md3.9 KiB
- references/rendering-modes.md5.5 KiB
references/core-routing.md
name: routing description: File-based routing, dynamic routes, navigation, and middleware in Nuxt
Routing
Nuxt uses file-system routing based on vue-router. Files in app/pages/ automatically create routes.
Nuxt 5 Routing Defaults
Case-sensitive matching (
router.options.sensitive: true) —/Aboutno longer matchespages/about.vue. Match link casing to file names, or setrouter: { options: { sensitive: false } }.sensitivecan only be set innuxt.config(the build fails ifapp/router.options.tssets it). Withsensitive: false, route rules match lower-cased paths, so regex constraints in rule patterns must be written for lower-case ([a-z], not[A-Z]).Typed pages on by default (
experimental.typedPages) —useRoute,navigateTo,<NuxtLink :to>, androuter.pushare type-checked against your real routes. Referencing a route that doesn't exist is a type error. Opt out withexperimental.typedPages: false.Normalized page component names — a page is named after its route, not its filename (
pages/foo/index.vue→foo, notindex). Update any<KeepAlive :include>filters to route names, or setexperimental.normalizePageNames: false.Serializable page meta extracted at build time — every JSON-serializable
definePageMeta()property is written into the generated route record; only non-serializable values (functions, refs, spreads) resolve at runtime.Route rule patterns use URLPattern -
'/blog/*'now matches nested paths (/blog/2026/hello); use'/blog/:slug'for one segment. Only one*/**per key (use/:post/comments/**). Regex constraints cannot match%or percent-encoded chars, or use\b. Rules also supportproxy: 'https://api.example.com/**'.Unmatched client navigations load as a full document (
experimental.serverPathFallback) so<NuxtLink to="/file.pdf">reachespublic/files or server routes.Build-time link check -
experimental.templateDiagnosticswarns (NUXT_B4025) when a static<NuxtLink to>matches no page route.
Basic Routing
pages/
├── index.vue → /
├── about.vue → /about
└── posts/
├── index.vue → /posts
└── [id].vue → /posts/:idDynamic Routes
Use brackets for dynamic segments:
pages/
├── users/
│ └── [id].vue → /users/:id
├── posts/
│ └── [...slug].vue → /posts/* (catch-all)
└── [[optional]].vue → /:optional? (optional param)Access route parameters:
<script setup lang="ts">
const route = useRoute()
// /posts/123 → route.params.id = '123'
console.log(route.params.id)
</script>Navigation
NuxtLink Component
<template>
<nav>
<NuxtLink to="/">Home</NuxtLink>
<NuxtLink to="/about">About</NuxtLink>
<NuxtLink :to="{ name: 'posts-id', params: { id: 1 } }">Post 1</NuxtLink>
</nav>
</template>NuxtLink automatically prefetches linked pages when they enter the viewport.
Programmatic Navigation
<script setup lang="ts">
const router = useRouter()
function goToPost(id: number) {
navigateTo(`/posts/${id}`)
// or
router.push({ name: 'posts-id', params: { id } })
}
</script>Route Middleware
Named Middleware
// middleware/auth.ts
export default defineNuxtRouteMiddleware((to, from) => {
const isAuthenticated = false // Your auth logic
if (!isAuthenticated) {
return navigateTo('/login')
}
})Apply to pages:
<script setup lang="ts">
definePageMeta({
middleware: 'auth',
// or multiple: middleware: ['auth', 'admin']
})
</script>Global Middleware
Name files with .global suffix:
// middleware/logging.global.ts
export default defineNuxtRouteMiddleware((to, from) => {
console.log('Navigating to:', to.path)
})Inline Middleware
<script setup lang="ts">
definePageMeta({
middleware: [
function (to, from) {
// Inline middleware logic
},
],
})
</script>Page Meta
Configure page-level options:
<script setup lang="ts">
definePageMeta({
title: 'My Page',
layout: 'custom',
middleware: 'auth',
validate: (route) => {
// Return false for 404, or object with status/statusText
return /^\d+$/.test(route.params.id as string)
},
})
</script>Route Validation
<script setup lang="ts">
definePageMeta({
validate: (route) => {
// Must return boolean or object with status
return typeof route.params.id === 'string' && /^\d+$/.test(route.params.id)
},
})
</script>Layouts
Define layouts in app/layouts/:
<!-- layouts/default.vue -->
<template>
<div>
<header>Header</header>
<slot />
<footer>Footer</footer>
</div>
</template><!-- layouts/admin.vue -->
<template>
<div class="admin">
<AdminSidebar />
<main>
<slot />
</main>
</div>
</template>Use in pages:
<script setup lang="ts">
definePageMeta({
layout: 'admin',
})
</script>Dynamic layout:
<script setup lang="ts">
const layout = ref('default')
function enableAdmin() {
setPageLayout('admin')
}
</script>Passing Props to Layouts (Nuxt 4.4+)
Use the object syntax for layout to pass typed props to the layout component:
<!-- app/pages/dashboard.vue -->
<script setup lang="ts">
definePageMeta({
layout: { name: 'panel', props: { sidebar: true, title: 'Dashboard' } },
})
</script><!-- app/layouts/panel.vue -->
<script setup lang="ts">
const props = defineProps<{ sidebar?: boolean, title?: string }>()
</script>Props are fully typed from the layout's defineProps. Also works dynamically: setPageLayout('panel', { sidebar: true }).
Named Views
A route can render into multiple <NuxtPage> outlets. Add named view files with the [email protected] convention next to the default route file:
pages/
├── parent.vue
└── parent/
├── child.vue → default <NuxtPage />
└── [email protected] → <NuxtPage name="sidebar" /><!-- pages/parent.vue -->
<template>
<NuxtPage />
<aside><NuxtPage name="sidebar" /></aside>
</template>definePageMeta is read from the default route file only.
Navigation Hooks
<script setup lang="ts">
onBeforeRouteLeave((to, from) => {
// Confirm before leaving
const answer = window.confirm('Leave?')
if (!answer) return false
})
onBeforeRouteUpdate((to, from) => {
// Called when route changes but component is reused
})
</script><!-- Source references: - https://nuxt.com/docs/getting-started/routing - https://nuxt.com/docs/directory-structure/app/pages - https://nuxt.com/docs/directory-structure/app/middleware - https://nuxt.com/docs/api/utils/define-page-meta - https://nuxt.com/docs/getting-started/upgrade - https://nuxt.com/docs/guide/recipes/custom-routing - https://nuxt.com/docs/guide/concepts/rendering -->
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
What our scanner noticed· Low risk
- Instructions that use the network
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Anthony Fu
- Publisher
- Anthony Fu (Community)
- Source
- antfu/skills · skills/nuxt · commit f63e9ec
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE.md)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Anthony Fu or Anthony Fu.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download nuxt.zip