docs/4.api/3.utils/define-page-meta.md
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>
:read-more{to="/docs/4.x/directory-structure/app/pages#page-metadata"}
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[]
groups?: string[]
pageTransition?: boolean | TransitionProps
layoutTransition?: boolean | TransitionProps
viewTransition?: ViewTransitionPageOptions['enabled'] | ViewTransitionPageOptions
key?: false | string | ((route: RouteLocationNormalizedLoaded) => string)
keepalive?: boolean | KeepAliveProps
layout?: false | LayoutKey | Ref<LayoutKey> | ComputedRef<LayoutKey> | { name?: LayoutKey | false, props?: Record<string, unknown> /* or the selected layout's props */ }
middleware?: MiddlewareKey | NavigationGuard | Array<MiddlewareKey | NavigationGuard>
scrollToTop?: boolean | ((to: RouteLocationNormalizedLoaded, from: RouteLocationNormalizedLoaded) => boolean)
[key: string]: unknown
}
metaType: PageMeta
An object accepting the following page metadata:
name
Type: string
You may define a name for this page's route. By default, name is generated based on path inside the app/pages/ directory.
path
Type: string
You may define a custom regular expression if you have a more complex pattern than can be expressed with the file name.
props
Type: RouteRecordRaw['props']
Allows accessing the route params as props passed to the page component.
alias
Type: string | string[]
Aliases for the record. Allows defining extra paths that will behave like a copy of the record. Allows having paths shorthands like /users/:id and /u/:id. All alias and path values must share the same params.
groups
Type: string[]
Route groups the page belongs to, based on the folder structure. Automatically populated for pages within route groups.
keepalive
Type: boolean | KeepAliveProps
Set to true when you want to preserve page state across route changes or use the KeepAliveProps for a fine-grained control.
key
Type: false | string | ((route: RouteLocationNormalizedLoaded) => string)
Set key value when you need more control over when the <NuxtPage> component is re-rendered.
layout
Type: false | LayoutKey | Ref<LayoutKey> | ComputedRef<LayoutKey> | { name?: LayoutKey | false; props?: Record<string, unknown> /* or the selected layout's props */ }
Set a static or dynamic name of the layout for each route. This can be set to false in case the default layout needs to be disabled.
You can also pass an object with name and props to pass typed props to your layout component. When your layout defines props with defineProps, they will be fully typed in definePageMeta.
layoutTransition
Type: boolean | TransitionProps
Set name of the transition to apply for current layout. You can also set this value to false to disable the layout transition.
middleware
Type: MiddlewareKey | NavigationGuard | Array<MiddlewareKey | NavigationGuard>
Define anonymous or named middleware directly within definePageMeta. Learn more about route middleware.
pageTransition
Type: boolean | TransitionProps
Set name of the transition to apply for current page. You can also set this value to false to disable the page transition.
viewTransition
Type: boolean | 'always' | ViewTransitionPageOptions
Experimental feature, only available when enabled in your nuxt.config file</br>
Enable/disable View Transitions for the current page.
If set to true, Nuxt will not apply the transition if the users browser matches prefers-reduced-motion: reduce (recommended). If set to always, Nuxt will always apply the transition.
You can also pass a ViewTransitionPageOptions object to configure view transition types:
enabled: boolean | 'always' - enable/disable the transitiontypes: string[] | (to, from) => string[] - types applied to any transition involving this pagetoTypes: string[] | (to, from) => string[] - types applied only when navigating to this pagefromTypes: string[] | (to, from) => string[] - types applied only when navigating from this pageredirect
Type: RouteRecordRedirectOption
Where to redirect if the route is directly matched. The redirection happens before any navigation guard and triggers a new navigation with the new target location.
validate
Type: (route: RouteLocationNormalized) => boolean | Promise<boolean> | Partial<NuxtError> | Promise<Partial<NuxtError>>
Validate whether a given route can validly be rendered with this page. Return true if it is valid, or false if not. If another match can't be found, this will mean a 404. You can also directly return an object with status/statusText to respond immediately with an error (other matches will not be checked).
scrollToTop
Type: boolean | (to: RouteLocationNormalized, from: RouteLocationNormalized) => boolean
Tell Nuxt to scroll to the top before rendering the page or not. Navigation is independent from rendering, so scroll behavior is always triggered even when the page doesn't re-render (e.g. when using a fixed key). Set scrollToTop: false to disable scrolling in such cases. If you want to overwrite the default scroll behavior of Nuxt, you can do so in ~/router.options.ts (see custom routing) for more info.
[key: string]
Type: any
Apart from the above properties, you can also set custom metadata. You may wish to do so in a type-safe way by augmenting the type of the meta 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>
You can pass props to a layout by using the object syntax for layout. If your layout defines props with defineProps, the props will be fully typed.
::code-group
<script setup lang="ts">
definePageMeta({
layout: {
name: 'panel',
props: {
sidebar: true,
title: 'Dashboard',
},
},
})
</script>
<script setup lang="ts">
const props = defineProps<{
sidebar?: boolean
title?: string
}>()
</script>
<template>
<div>
<aside v-if="sidebar">
Sidebar
</aside>
<main>
<h1>{{ title }}</h1>
<slot />
</main>
</div>
</template>
::
::tip
Layout props set via definePageMeta are fully typed based on the layout's defineProps. You'll get autocomplete and type-checking in your editor.
::
:read-more{to="/docs/4.x/directory-structure/app/layouts#passing-props-to-layouts"}