definePageMeta is a compiler macro that you can use to set metadata for your page components located in the app/pages/ directory (unless set otherwise). This way you can set custom metadata for each static or dynamic route of your Nuxt application.
<script setup lang="ts">
definePageMeta({
layout: 'default',
})
</script>
export function definePageMeta (meta: PageMeta): void
interface PageMeta {
validate?: ((route: RouteLocationNormalized) => boolean | Promise<boolean> | Partial<NuxtError> | Promise<Partial<NuxtError>>)
redirect?: RouteRecordRedirectOption
name?: string
path?: string
props?: RouteRecordRaw['props']
alias?: string | string[]
pageTransition?: boolean | TransitionProps
layoutTransition?: boolean | TransitionProps
viewTransition?: boolean | 'always'
key?: false | string | ((route: RouteLocationNormalizedLoaded) => string)
keepalive?: boolean | KeepAliveProps
layout?: false | LayoutKey | Ref<LayoutKey> | ComputedRef<LayoutKey>
middleware?: MiddlewareKey | NavigationGuard | Array<MiddlewareKey | NavigationGuard>
scrollToTop?: boolean | ((to: RouteLocationNormalizedLoaded, from: RouteLocationNormalizedLoaded) => boolean)
[key: string]: unknown
}
metaPageMetanamestringapp/pages/ directory.pathstringpropsRouteRecordRaw['props']params as props passed to the page component.aliasstring | string[]/users/:id and /u/:id. All alias and path values must share the same params.keepaliveboolean | KeepAlivePropstrue when you want to preserve page state across route changes or use the KeepAliveProps for a fine-grained control.keyfalse | string | ((route: RouteLocationNormalizedLoaded) => string)key value when you need more control over when the <NuxtPage> component is re-rendered.layoutfalse | LayoutKey | Ref<LayoutKey> | ComputedRef<LayoutKey>false in case the default layout needs to be disabled.layoutTransitionboolean | TransitionPropsfalse to disable the layout transition.middlewareMiddlewareKey | NavigationGuard | Array<MiddlewareKey | NavigationGuard>definePageMeta. Learn more about route middleware.pageTransitionboolean | TransitionPropsfalse to disable the page transition.viewTransitionboolean | 'always'prefers-reduced-motion: reduce (recommended). If set to always, Nuxt will always apply the transition.redirectRouteRecordRedirectOptionvalidate(route: RouteLocationNormalized) => boolean | Promise<boolean> | Partial<NuxtError> | Promise<Partial<NuxtError>>statusCode/statusMessage to respond immediately with an error (other matches will not be checked).scrollToTopboolean | (to: RouteLocationNormalized, from: RouteLocationNormalized) => boolean~/router.options.ts (see custom routing) for more info.[key: string]anymeta object.The example below demonstrates:
key can be a function that returns a value;keepalive property makes sure that the <modal> component is not cached when switching between multiple components;pageType as a custom property:<script setup lang="ts">
definePageMeta({
key: route => route.fullPath,
keepalive: {
exclude: ['modal'],
},
pageType: 'Checkout',
})
</script>
The example below shows how the middleware can be defined using a function directly within the definePageMeta or set as a string that matches the middleware file name located in the app/middleware/ directory:
<script setup lang="ts">
definePageMeta({
// define middleware as a function
middleware: [
function (to, from) {
const auth = useState('auth')
if (!auth.value.authenticated) {
return navigateTo('/login')
}
if (to.path !== '/checkout') {
return navigateTo('/checkout')
}
},
],
// ... or a string
middleware: 'auth',
// ... or multiple strings
middleware: ['auth', 'another-named-middleware'],
})
</script>
A custom regular expression is a good way to resolve conflicts between overlapping routes, for instance:
The two routes "/test-category" and "/1234-post" match both [postId]-[postSlug].vue and [categorySlug].vue page routes.
To make sure that we are only matching digits (\d+) for postId in the [postId]-[postSlug] route, we can add the following to the [postId]-[postSlug].vue page template:
<script setup lang="ts">
definePageMeta({
path: '/:postId(\\d+)-:postSlug',
})
</script>
For more examples see Vue Router's Matching Syntax.
You can define the layout that matches the layout's file name located (by default) in the app/layouts/ directory. You can also disable the layout by setting the layout to false:
<script setup lang="ts">
definePageMeta({
// set custom layout
layout: 'admin',
// ... or disable a default layout
layout: false,
})
</script>