404 page for Nuxt dynamic nested routes
Although NuxtJS routing is based on the file system, it also supports dynamic routes that are unknown in advance and based on an external data source. Unknown dynamic nested routes even allow this for arbitrary nesting depths. I've already written about using middleware to implement redirects. But what about displaying a 404 page for invalid routes?
If you're using server-side rendering, error responses should have a proper status code, just like redirects. This means that, again, this must be done in the middleware. To display an error page with a specific status code, the error
function from the Nuxt context should be used:
import { Context } from "@nuxt/types";
import { isUrlValid } from "~/services/validateRoute";
export default async function (context: Context) {
if (!(await isUrlValid(context.route.path))) {
context.error({
statusCode: 404,
message: `Invalid route: ${context.route.path}`,
});
}
}
I decided to implement it as named middleware. To make it work, I had to link it to the page corresponding to the dynamic route:
import Vue from "vue";
import Component from "vue-class-component";
@Component({
middleware: "validateRoute",
})
export default class RedirectPage extends Vue {}
The error
function renders the default Nuxt error page, which you can further customize to suit your needs. If needed, you can check the error details (such as the status code) to have several different pages for different errors.
Although the error.vue
file containing the page is located in the layouts
folder, it resembles a page rather than a layout. The only difference from a normal page seems to be the lack of support for the asyncData
hook. Instead, you must use the fetch
hook to retrieve data on the server.
You can find a working example application showing a 404 page for some dynamic routes in my GitHub repository.
Whenever you need to return different status codes for server-side rendered pages in Nuxt, you need to use middleware. Just as there is a redirect
function in the Nuxt context to redirect to a different route, there is also an error
function to return standard error pages.