11. Example [nuxt-08]: Routing middleware
In this example, we introduce the concept of routing middleware, scripts executed whenever a route changes.
Example [nuxt-08] is initially created by cloning the [nuxt-01] project:

Routing middleware must be placed in a folder named [middleware] [2]. There can be two-level routing:
- routing applied to every navigation. This is then declared in the [nuxt.config.js] file;
- routing applied to a specific page, when that page is the routing target. This routing is then declared in that target page;
11.1. General Routing
The [middleware/routing.js] file will handle general routing. It is declared as follows in the [nuxt.config.js] file:
router: {
base: '/nuxt-08/',
middleware: ['routing']
},
General routing middleware is a property of the router (line 1). There can be multiple routing middleware components. That is why, on line 3, the value of the [middleware] property is an array. Note that we do not use a path to specify the middleware. It will be automatically searched for in the project’s [middleware] folder;
The [routing] middleware only logs here:
/* eslint-disable no-undef */
/* eslint-disable no-console */
export default function(...args) {
// Who is executing this code?
console.log('[routing], process.server=', process.server, 'process.client=', process.client)
const who = process.server ? 'server' : 'client'
const routing = '[routing ' + who + ']'
// number of arguments
console.log(routing + ', there are', args.length, 'argument(s)')
// 1st argument
const context = args[0]
// context keys
dumpkeys(routing + ', context', context)
// the application
dumpkeys(routing + ', context.app', context.app)
// the route
dumpkeys(routing + ', context.route', context.route)
console.log(routing + ', context.route=', context.route)
// the router
dumpkeys(routing + ', context.app.router', context.app.router)
// router.options.routes
dumpkeys(routing + ', context.app.router.options.routes', context.app.router.options.routes)
console.log(routing + ', context.app.router.options.routes=', context.app.router.options.routes)
}
function dumpkeys(message, object) {
// list of keys from [object]
const line = 'List of keys [' + message + ']'
console.log(line)
// list of keys
if (object) {
console.log(Object.keys(object))
}
}
- line 3: we will see that the middleware receives an argument: the executor’s context (server or client);
- lines 4–25: we display the properties of various objects to determine what is usable. We will find that the middleware context is nearly identical to the plugin context;
11.2. Routing for a specific page
We want to control how users arrive at the [index] page. To do this, we need to add the [middleware] property to this [index] page:
<script>
/* eslint-disable no-undef */
/* eslint-disable no-console */
/* eslint-disable nuxt/no-env-in-hooks */
import Navigation from '@/components/navigation'
import Layout from '@/components/layout'
export default {
name: 'Home',
// components used
components: {
Layout,
Navigation
},
// lifecycle
beforeCreate() {
// client and server
console.log('[home beforeCreate]')
},
created() {
// client and server
console.log('[home created]')
},
beforeMount() {
// client only
console.log('[home beforeMount]')
},
mounted() {
// client only
console.log('[home mounted]')
},
// routing
middleware: ['index-routing']
}
</script>
- line 34: the [middleware] property lists the scripts to be executed whenever the next page displayed is the [index] page. Again, these scripts will be searched for in the project's [middleware] folder;
The [index-routing] middleware is as follows:
/* eslint-disable no-undef */
/* eslint-disable no-console */
export default function(...args) {
// Who is executing this code?
console.log('[index-routing], process.server=', process.server, 'process.client=', process.client)
const who = process.server ? 'server' : 'client'
const indexRouting = '[index-routing ' + who + ']'
// number of arguments
console.log(indexRouting + ', there are', args.length, 'argument(s)')
// 1st argument
const context = args[0]
// context keys
dumpkeys(indexRouting + ', context', context)
// the application
dumpkeys(indexRouting + ', context.app', context.app)
// the route
dumpkeys(indexRouting + ', context.route', context.route)
console.log(indexRouting + ', context.route=', context.route)
// the router
dumpkeys(indexRouting + ', context.app.router', context.app.router)
// router.options.routes
dumpkeys(indexRouting + ', context.app.router.options.routes', context.app.router.options.routes)
console.log(indexRouting + ', context.app.router.options.routes=', context.app.router.options.routes)
// where are we coming from?
if (context.from) {
console.log('from=', context.from)
}
}
function dumpkeys(message, object) {
// list of keys from [object]
const line = 'List of keys [' + message + ']'
console.log(line)
// list of keys
if (object) {
console.log(Object.keys(object))
}
}
The code for [index-routing] is identical to that of [routing] and produces the same results. What interests us is seeing when these two middlewares are executed.
11.3. Running the project
We run the project. The logs are as follows:
The [routing] script is executed first by the server:
This is the same result we got with the plugins.
- line 15: the [redirect] property is often used in middleware; it allows you to change the target of the current routing;
Then, because the page to be displayed is the [index] page, the server executes the [index-routing] script and displays the following logs:
The results obtained with the [index-routing] script are similar to those obtained with the [routing] script.
Once the [index] page is received by the client browser, the client scripts take over. The logs become as follows:
We can see, therefore, that when the application starts, the client does not execute any middleware. This means that this will happen every time the user forces a request to the server. Middleware is only executed by the client when navigating within the client. For example, let’s navigate to the [page1] page (we are currently on the [index] page) using the [Page 1] link. The logs are then as follows:
- line 2: the [routing] middleware is executed by the client;
- line 4: note the [from] property: this is the route we came from;
- line 9: [context.route] is the route we are going to;
- lines 15–18: display of the [page1] page;
Now let’s return to the [index] page using the [Home] link. The logs are then as follows:
- lines 1-15: the client executes the [routing] middleware. This is normal. It is executed every time the route changes;
- lines 16–29: the client executes the [index-routing] middleware, because:
- [index] is the target of the current route (see line 23);
- the [index] page has defined a middleware named [index-routing];
We can see, then, that general routing middleware is executed by the client before the middleware attached to the pages.