8.4 KiB
icon | title | head.title |
---|---|---|
IconDirectory | pages | Pages directory |
Pages directory
Nuxt provides a file-based routing to create routes within your web application using Vue Router under the hood.
::alert{type="info"}
This directory is optional, meaning that vue-router
won't be included if you only use app.vue, reducing your application's bundle size.
::
Usage
Pages are Vue components and can have the .vue
, .js
, .jsx
, .ts
or .tsx
extension.
::code-group
<template>
<h1>Index page</h1>
</template>
// https://vuejs.org/guide/extras/render-function.html
export default defineComponent({
render () {
return h('h1', 'Index page')
}
})
// https://vuejs.org/guide/extras/render-function.html#jsx-tsx
export default defineComponent({
render () {
return <h1>Index page</h1>
}
})
::
The pages/index.vue
file will be mapped to the /
route of your application.
If you are using app.vue, make sure to use the <NuxtPage/>
component to display the current page:
<template>
<div>
<!-- Markup shared across all pages, ex: NavBar -->
<NuxtPage />
</div>
</template>
::alert{type=warning} Note that pages must have a single root element to allow route transitions between pages. ::
Dynamic Routes
If you place anything within square brackets, it will be turned into a dynamic route parameter. You can mix and match multiple parameters and even non-dynamic text within a file name or directory.
Example
-| pages/
---| index.vue
---| users-[group]/
-----| [id].vue
Given the example above, you can access group/id within your component via the $route
object:
<template>
<p>{{ $route.params.group }} - {{ $route.params.id }}</p>
</template>
Navigating to /users-admins/123
would render:
<p>admins - 123</p>
If you want to access the route using Composition API, there is a global useRoute
function that will allow you to access the route just like this.$route
in the Options API.
<script setup>
const route = useRoute()
if (route.params.group === 'admins' && !route.params.id) {
console.log('Warning! Make sure user is authenticated!')
}
</script>
Catch all route
If you need a catch-all route, you create it by using a file named like [...slug].vue
. This will match all routes under that path.
<template>
<p>{{ $route.params.slug }}</p>
</template>
Navigating to /hello/world
would render:
<p>["hello", "world"]</p>
Nested Routes
It is possible to display nested routes with <NuxtPage>
.
Example:
-| pages/
---| parent/
------| child.vue
---| parent.vue
This file tree will generate these routes:
[
{
path: '/parent',
component: '~/pages/parent.vue',
name: 'parent',
children: [
{
path: 'child',
component: '~/pages/parent/child.vue',
name: 'parent-child'
}
]
}
]
To display the child.vue
component, you have to insert the <NuxtPage>
component inside pages/parent.vue
:
<template>
<div>
<h1>I am the parent view</h1>
<NuxtPage :foobar="123" />
</div>
</template>
Child route keys
If you want more control over when the <NuxtPage>
component is re-rendered (for example, for transitions), you can either pass a string or function via the pageKey
prop, or you can define a key
value via definePageMeta
:
<template>
<div>
<h1>I am the parent view</h1>
<NuxtPage :page-key="someKey" />
</div>
</template>
Or alternatively:
<script setup>
definePageMeta({
key: route => route.fullPath
})
</script>
Page Metadata
You might want to define metadata for each route in your app. You can do this using the definePageMeta
macro, which will work both in <script>
and in <script setup>
:
<script setup>
definePageMeta({
title: 'My home page'
})
</script>
This data can then be accessed throughout the rest of your app from the route.meta
object.
<script setup>
const route = useRoute()
console.log(route.meta.title) // My home page
</script>
If you are using nested routes, the page metadata from all these routes will be merged into a single object. For more on route meta, see the vue-router docs.
Much like defineEmits
or defineProps
(see Vue docs), definePageMeta
is a compiler macro. It will be compiled away so you cannot reference it within your component. Instead, the metadata passed to it will be hoisted out of the component. Therefore, the page meta object cannot reference the component (or values defined on the component). However, it can reference imported bindings.
<script setup>
import { someData } from '~/utils/example'
const title = ref('')
definePageMeta({
title, // This will create an error
someData
})
</script>
Special Metadata
Of course, you are welcome to define metadata for your own use throughout your app. But some metadata defined with definePageMeta
has a particular purpose:
keepalive
Nuxt will automatically wrap your page in the Vue <KeepAlive>
component if you set keepalive: true
in your definePageMeta
. This might be useful to do, for example, in a parent route which has dynamic child routes, if you want to preserve page state across route changes. You can also set props to be passed to <KeepAlive>
(see a full list here).
key
layout
You can define the layout used to render the route. This can be either false (to disable any layout), a string or a ref/computed, if you want to make it reactive in some way. More about layouts.
middleware
You can define middleware to apply before loading this page. It will be merged with all the other middleware used in any matching parent/child routes. It can be a string, a function (an anonymous/inlined middleware function following the global before guard pattern), or an array of strings/functions. More about named middleware.
layoutTransition
and pageTransition
You can define transition properties for the <transition>
components that wraps your pages and layouts, or pass false
to disable the <transition>
wrapper for that route. You can see a list of options that can be passed here or read more about how transitions work.
Navigation
To navigate between pages of your app, you should use the <NuxtLink>
component.
This component is included with Nuxt and therefore you don't have to import it as you do with other components.
A simple link to the index.vue
page in your pages
folder:
<template>
<NuxtLink to="/">Home page</NuxtLink>
</template>
::alert{type="info"}
Learn more about <NuxtLink>
usage.
::
Router options
It is possible to set default vue-router options.
Note: history
and routes
options will be always overriden by Nuxt.
Using app/router.options
This is the recommaned way to specify router options.
import type { RouterOptions } from '@nuxt/schema'
// https://router.vuejs.org/api/#routeroptions
export default <RouterOptions>{
}
Using nuxt.config
Note: Only JSON serializable options are configurable:
linkActiveClass
linkExactActiveClass
end
sensitive
strict
export default defineNuxtConfig({
router: {
// https://router.vuejs.org/api/#routeroptions
options: {}
}
})