Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Comprehensive Nuxt 3.x reference covering SSR, file-based routing, auto-imports, server routes, and Nitro deployment.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/core-routing.md
1---2name: routing3description: File-based routing, dynamic routes, navigation, and middleware in Nuxt4---56# Routing78Nuxt uses file-system routing based on vue-router. Files in `app/pages/` automatically create routes.910## Basic Routing1112```13pages/14├── index.vue → /15├── about.vue → /about16└── posts/17├── index.vue → /posts18└── [id].vue → /posts/:id19```2021## Dynamic Routes2223Use brackets for dynamic segments:2425```26pages/27├── users/28│ └── [id].vue → /users/:id29├── posts/30│ └── [...slug].vue → /posts/* (catch-all)31└── [[optional]].vue → /:optional? (optional param)32```3334Access route parameters:3536```vue37<script setup lang="ts">38const route = useRoute()39// /posts/123 → route.params.id = '123'40console.log(route.params.id)41</script>42```4344## Navigation4546### NuxtLink Component4748```vue49<template>50<nav>51<NuxtLink to="/">Home</NuxtLink>52<NuxtLink to="/about">About</NuxtLink>53<NuxtLink :to="{ name: 'posts-id', params: { id: 1 } }">Post 1</NuxtLink>54</nav>55</template>56```5758NuxtLink automatically prefetches linked pages when they enter the viewport.5960### Programmatic Navigation6162```vue63<script setup lang="ts">64const router = useRouter()6566function goToPost(id: number) {67navigateTo(`/posts/${id}`)68// or69router.push({ name: 'posts-id', params: { id } })70}71</script>72```7374## Route Middleware7576### Named Middleware7778```ts79// middleware/auth.ts80export default defineNuxtRouteMiddleware((to, from) => {81const isAuthenticated = false // Your auth logic8283if (!isAuthenticated) {84return navigateTo('/login')85}86})87```8889Apply to pages:9091```vue92<script setup lang="ts">93definePageMeta({94middleware: 'auth',95// or multiple: middleware: ['auth', 'admin']96})97</script>98```99100### Global Middleware101102Name files with `.global` suffix:103104```ts105// middleware/logging.global.ts106export default defineNuxtRouteMiddleware((to, from) => {107console.log('Navigating to:', to.path)108})109```110111### Inline Middleware112113```vue114<script setup lang="ts">115definePageMeta({116middleware: [117function (to, from) {118// Inline middleware logic119},120],121})122</script>123```124125## Page Meta126127Configure page-level options:128129```vue130<script setup lang="ts">131definePageMeta({132title: 'My Page',133layout: 'custom',134middleware: 'auth',135validate: (route) => {136// Return false for 404, or object with status/statusText137return /^\d+$/.test(route.params.id as string)138},139})140</script>141```142143## Route Validation144145```vue146<script setup lang="ts">147definePageMeta({148validate: (route) => {149// Must return boolean or object with status150return typeof route.params.id === 'string' && /^\d+$/.test(route.params.id)151},152})153</script>154```155156## Layouts157158Define layouts in `app/layouts/`:159160```vue161<!-- layouts/default.vue -->162<template>163<div>164<header>Header</header>165<slot />166<footer>Footer</footer>167</div>168</template>169```170171```vue172<!-- layouts/admin.vue -->173<template>174<div class="admin">175<AdminSidebar />176<main>177<slot />178</main>179</div>180</template>181```182183Use in pages:184185```vue186<script setup lang="ts">187definePageMeta({188layout: 'admin',189})190</script>191```192193Dynamic layout:194195```vue196<script setup lang="ts">197const layout = ref('default')198199function enableAdmin() {200setPageLayout('admin')201}202</script>203```204205### Passing Props to Layouts (Nuxt 4.4+)206207Use the object syntax for `layout` to pass typed props to the layout component:208209```vue210<!-- app/pages/dashboard.vue -->211<script setup lang="ts">212definePageMeta({213layout: { name: 'panel', props: { sidebar: true, title: 'Dashboard' } },214})215</script>216```217218```vue219<!-- app/layouts/panel.vue -->220<script setup lang="ts">221const props = defineProps<{ sidebar?: boolean, title?: string }>()222</script>223```224225Props are fully typed from the layout's `defineProps`. Also works dynamically: `setPageLayout('panel', { sidebar: true })`.226227## Named Views228229A route can render into multiple `<NuxtPage>` outlets. Add named view files with the `[email protected]` convention next to the default route file:230231```232pages/233├── parent.vue234└── parent/235├── child.vue → default <NuxtPage />236└── [email protected] → <NuxtPage name="sidebar" />237```238239```vue240<!-- pages/parent.vue -->241<template>242<NuxtPage />243<aside><NuxtPage name="sidebar" /></aside>244</template>245```246247`definePageMeta` is read from the default route file only.248249## Navigation Hooks250251```vue252<script setup lang="ts">253onBeforeRouteLeave((to, from) => {254// Confirm before leaving255const answer = window.confirm('Leave?')256if (!answer) return false257})258259onBeforeRouteUpdate((to, from) => {260// Called when route changes but component is reused261})262</script>263```264265<!--266Source references:267- https://nuxt.com/docs/4.x/getting-started/routing268- https://nuxt.com/docs/4.x/directory-structure/app/pages269- https://nuxt.com/docs/4.x/directory-structure/app/middleware270- https://nuxt.com/docs/4.x/api/utils/define-page-meta271-->272