Custom Routing
Adding custom routes
In Nuxt 3, your routing is defined by the structure of your files inside the pages directory. However, since it uses vue-router under the hood, Nuxt offers you several ways to add custom routes in your project.
Router Config
Using router options, you can optionally override or extend your routes using a function that accepts the scanned routes and returns customized routes.
If it returns null
or undefined
, Nuxt will fall back to the default routes (useful to modify input array).
import type { RouterConfig } from '@nuxt/schema'
export default <RouterConfig> {
// https://router.vuejs.org/api/interfaces/routeroptions.html#routes
routes: (_routes) => [
{
name: 'home',
path: '/',
component: () => import('~/pages/home.vue').then(r => r.default || r)
}
],
}
routes
function with metadata defined in definePageMeta
of the component you provide. If you want that to happen, you should use the pages:extend
hook which is called at build-time.Pages Hook
You can add, change or remove pages from the scanned routes with the pages:extend
nuxt hook.
For example, to prevent creating routes for any .ts
files:
export default defineNuxtConfig({
hooks: {
'pages:extend' (pages) {
// add a route
pages.push({
name: 'profile',
path: '/profile',
file: '~/extra-pages/profile.vue'
})
// remove routes
function removePagesMatching (pattern: RegExp, pages: NuxtPage[] = []) {
const pagesToRemove = []
for (const page of pages) {
if (pattern.test(page.file)) {
pagesToRemove.push(page)
} else {
removePagesMatching(pattern, page.children)
}
}
for (const page of pagesToRemove) {
pages.splice(pages.indexOf(page), 1)
}
}
removePagesMatching(/\.ts$/, pages)
}
}
})
Nuxt Module
If you plan to add a whole set of pages related with a specific functionality, you might want to use a Nuxt module.
The Nuxt kit provides a few ways to add routes:
extendPages
(callback: pages => void)extendRouteRules
(route: string, rule: NitroRouteConfig, options: ExtendRouteRulesOptions)
Router Options
On top of customizing options for vue-router
, Nuxt offers additional options to customize the router.
Using app/router.options
This is the recommended way to specify router options.
import type { RouterConfig } from '@nuxt/schema'
export default <RouterConfig> {
}
It is possible to add more router options files by adding files within the pages:routerOptions
hook. Later items in the array override earlier ones.
optional
is set, in which case it will only apply when page-based routing is already enabled.export default defineNuxtConfig({
hooks: {
'pages:routerOptions' ({ files }) {
const resolver = createResolver(import.meta.url)
// add a route
files.push({
path: resolver.resolve('./runtime/app/router-options'),
optional: true
})
}
}
})
Using nuxt.config
Note: Only JSON serializable options are configurable:
linkActiveClass
linkExactActiveClass
end
sensitive
strict
hashMode
scrollBehaviorType
export default defineNuxtConfig({
router: {
options: {}
}
})
Hash Mode (SPA)
You can enable hash history in SPA mode using the hashMode
config. In this mode, router uses a hash character (#) before the actual URL that is internally passed. When enabled, the URL is never sent to the server and SSR is not supported.
export default defineNuxtConfig({
ssr: false,
router: {
options: {
hashMode: true
}
}
})
Scroll Behavior for hash links
You can optionally customize the scroll behavior for hash links. When you set the config to be smooth
and you load a page with a hash link (e.g. https://example.com/blog/my-article#comments
), you will see that the browser smoothly scrolls to this anchor.
export default defineNuxtConfig({
router: {
options: {
scrollBehaviorType: 'smooth'
}
}
})
Custom History (advanced)
You can optionally override history mode using a function that accepts the base URL and returns the history mode. If it returns null
or undefined
, Nuxt will fallback to the default history.
import type { RouterConfig } from '@nuxt/schema'
import { createMemoryHistory } from 'vue-router'
export default <RouterConfig> {
// https://router.vuejs.org/api/interfaces/routeroptions.html
history: base => import.meta.client ? createMemoryHistory(base) : null /* default */
}