Nuxt 3 dynamic routes example
In Nuxt 3, dynamic routes are formatted as follows: /pages/users/index.vue for /users, /pages/users/[user].vue for /users/some-user-name, /pages/users/[user]/edit.vue for /users/some-user-name/edit, and /pages/users/[...slug].vue for /users/anything-else.
Pages directory optional for single-page apps
Nuxt 3 ships with an optional vue-router integration triggered by the existence of an app/pages/ directory in your source directory. If you only have a single page, you may consider instead moving it to app.vue for a lighter build.
useRoute and useRouter composables replace this.$route and this.$router
In Nuxt 3, migrate from this.$route and this.$router to use the useRoute() and useRouter() composables instead, especially when using the Composition API.
Replace Nuxt component with slot in layouts
In Nuxt 3, layouts use slots instead of the <Nuxt> component. Replace <Nuxt /> with <slot /> in your layout files. This allows advanced use cases with named and scoped slots.
definePageMeta to select layout for pages
Use the definePageMeta compiler macro to select the layout used by a page. Layouts will be kebab-cased, so app/layouts/customLayout.vue becomes 'custom-layout' when referenced in definePageMeta({ layout: 'custom-layout' }).
Dynamic routes syntax change from _id to [id]
In Nuxt 3, dynamic route parameters use [id] format instead of _id. For example, /pages/users/_user.vue becomes /pages/users/[user].vue, and the parameter is accessed via params.user.
Nuxt 3 validate hook migration example
This example shows how to migrate the validate hook from Nuxt 2 to Nuxt 3 definePageMeta:
Nuxt 2:
```ts
export default {
async validate({ params }) {
return /^\d+$/.test(params.id)
}
}
```
Nuxt 3:
```vue
<script setup>
definePageMeta({
validate: async (route) => {
const nuxtApp = useNuxtApp()
return /^\d+$/.test(route.params.id)
}
})
</script>
```
validate hook signature in Nuxt 3
In Nuxt 3, the validate hook accepts a single argument, the route, instead of an object with params. It returns a boolean value. If false is returned and another match cannot be found, this results in a 404. You can also directly return an object with status/statusText to respond immediately with an error without checking other matches.
definePageMeta() must be used in page components only
The definePageMeta() macro must be called directly at the top level of a page component's <script setup> block. It cannot be used inside composables, conditionals, or non-page components because it is a compile-time transformation that does not execute at runtime.
abortNavigation() context requirements
abortNavigation() must be called within a route middleware handler to work correctly. It cannot be used in components, plugins, composables, or in callbacks that have lost the middleware context.
E2005 example: correct middleware route access
export default defineNuxtRouteMiddleware((to, from) => {
// use `to` / `from` instead of useRoute()
})
E4016 alternative resolution: restructure pages directory
If you did not intend to create a nested route, restructure the pages/ directory so the page no longer has child routes to avoid the E4016 error.
E4016 error directory structure example
The E4016 error happens with a directory structure like: pages/parent/child.vue and pages/parent.vue, when parent.vue does not contain <NuxtPage />.
E4016 resolution: add NuxtPage to parent component
To fix the E4016 error, add <NuxtPage /> to the parent page component so the child route can render inside it.
Route rules statusCode renamed to status
In Nitro v3, route rules redirect property name changed from `statusCode` to `status`. Update from `redirect: { to: '/new-page', statusCode: 302 }` to `redirect: { to: '/new-page', status: 302 }`.
Case-sensitive routing in Nuxt 5
With `compatibilityVersion: 5`, page routes match URLs case-sensitively, consistent with Nitro. For example, `/About` no longer matches `pages/about.vue`. To keep case-insensitive matching, set `router.options.sensitive: false` in nuxt.config.ts.
Typed pages enabled by default in Nuxt 5
With `compatibilityVersion: 5`, `experimental.typedPages` is enabled by default. Nuxt generates typed route names and paths from `pages/` directory. Composables like `useRoute`, `navigateTo`, `<NuxtLink>`, and `router.push` are type-checked against actual routes, catching broken links at type-check time. If referencing non-existent routes, fix the reference or extend generated route types. Disable with `experimental.typedPages: false`.
ssrContext._renderResponse legacy fallback removed
`ssrContext._renderResponse` is no longer checked as a fallback in Nuxt 5. Only the internal `ssrContext['~renderResponse']` (set by Nuxt's router composable) is used. If setting `ssrContext._renderResponse` directly, use `ssrContext['~renderResponse']` instead. The Nuxt router composable already uses the new property, so no changes needed if going through `navigateTo` or route middleware.
Conditional middleware code execution using import.meta
Nuxt middleware runs on both the server and the client. To run certain code in specific environments, use import.meta.client for the client and import.meta.server for the server.
Server middleware executes for every request
Middleware under server/middleware/ is executed for every request. Middleware can be used for tasks such as authentication, logging, or request transformation. Returning a value from middleware will terminate the request and send the returned value as the response.
Route validation in server lifecycle
After initializing plugins and before executing middleware, Nuxt calls the validate method if it is defined in the definePageMeta function. The validate method can be synchronous or asynchronous and should return true if the parameters are valid, or false or an object containing status and/or statusText to terminate the request.
Three types of middleware in Nuxt
Nuxt has three types of middleware: global route middleware, named route middleware, and anonymous (inline) route middleware. Global middleware executes on initial page load and before any client-side navigation. Named and anonymous middleware execute only on routes specified in the middleware property of page meta.
Server-side redirection creates Location header
Any redirection on the server results in a Location: header being sent to the browser, which then makes a fresh request to the new location. All application state will be reset when this happens unless persisted in a cookie.