How routes works with Nuxt.js
When we program with pure Vue.js, we need to define all routes in one file, eg (router.js). Using Nuxt, everything is done automatically, we just need to understand how it works so we don't get lost and manage to create the routes in the desired way.
Tags
How routes works with Nuxt.js
April 25, 2023
When we program with pure Vue.js, we need to define all routes in one file, eg (router.js). Using Nuxt, everything is done automatically, we just need to understand how it works so we don't get lost and manage to create the routes in the desired way.
Every Vue file inside the pages/
directory creates a corresponding URL (or route) that display the content of the file. By using the dynamic imports for each page, Nuxt leverages code-splitting to ship the minimum amount of JS for the requested route.
Pages
Below, we can see first the conventional way to create dynamic and nested routes and then how to create it using nuxt.js.
{
routes: [
{
path: '/about',
component: 'pages/about.vue'
},
{
path: '/',
component: 'pages/index.vue'
},
{
path: '/posts/:id',
component: 'pages/posts/[id].vue'
}
}
To create routes with Nuxt, we need to just apply some structure as desired.
pages/
--| about.vue
--| index.vue
--| posts/
----| [id].vue
Above, we have the same result!
Navigation
In conventional vue-router we uses the <RouterLink>
component to link pages between them. Using the Nuxt, it's similar! We can do the same thing using the <NuxtLink>
. It renders an <a>
tag with the href
attribute set to the route of the page. Once the application is loaded, page transitions are performed in JavaScript by using the browser URL. This presents full-page refreshes and allows for animated transitions.
When a <NuxtLink>
enters the viewport on the client side, Nuxt will automatically prefetch components and payload (generated pages) of the linked pages ahead of time, resulting in faster navigation.
<template>
<header>
<nav>
<ul>
<li><NuxtLink to="/about">About</NuxtLink></li>
<li><NuxtLink to="/posts/1">Post 1</NuxtLink></li>
<li><NuxtLink to="/posts/2">Post 2</NuxtLink></li>
</ul>
</nav>
</header>
</template>
Route Parameters
The useRoute()
composable can be used in a <script setup>
block or a setup()
method of a Vue component to access the current route details.
<script setup>
const route = useRoute()
// When accessing /posts/1, route.params.id will be 1
console.log(route.params.id)
</script>
Route Middleware
Nuxt provides a customizable route middleware framework you can use throughout your application, ideal for extracting code that you want to run before navigating to a particular route.
There are three kinds of route middleware:
- Anonymous (or inline) route middleware, which are defined directly in the pages where they are used.
<script>
import Vue from 'vue'
import { isAuthenticated, navigateTo } from 'helpers/route'
export default Vue.extend({
name: 'IndexPage',
middleware(to, from) {
if (!isAuthenticated()) {
return navigateTo('/login')
}
})
})
</script>
- Named route middleware, which are placed in the middleware/ directory and will be automatically loaded via asynchronous import when used on a page. (Note: The route middleware name is normalized to kebab-case, so someMiddleware becomes some-middleware.)
<script>
import Vue from 'vue'
export default Vue.extend({
name: 'IndexPage',
middleware: ['auth']
})
</script>
- Global route middleware, which are placed in the middleware/ directory (with a .global suffix) and will be automatically run on every route change.
// nuxt.config.js
export default {
router: {
middleware: ['auth', () => { alert('It will run to all routes.') }]
}
}
Route Validation
Nuxt offers route validation via the validate
property in definePageMeta
in each page you wish to validate.
The validate
property accepts the route
as an argument. You can return a boolean value to determine whether or not this is a valid route to be rendered with this page. If you return false
, and another match can't be found, this will cause a 404 error. You can also directly return an object with statusCode
/statusMessage
to respond immediately with an error (other matches will not be checked).
If you have a more complex use case, then you can use anonymous route middleware instead.s
If you have a more complex use case, then you can use anonymous route middleware instead.
<script setup>
definePageMeta({
validate: async (route) => {
// Check if the id is made up of digits
return /^\d+$/.test(route.params.id)
}
})
</script>