Custom error page in nuxt.js

Nuxt makes it really easy to handle errors with a couple of small gotchas. This is my setup to get good error handling in a nuxt static site that is hosted on netlify and uses the nuxt content module to handle the content.

First thing we need to do is to create a layouts/error.vue file. This file will be handling the error messages you show your users.

layouts/error.vue
<template>
  <div>
    <h1>You are in layouts/error.vue</h1>
    <h1 v-if="error.statusCode === 404">Page not found</h1>
    <h1 v-else>An error occurred</h1>
    <nuxt-link to="/">Click to visit Home page</nuxt-link>
  </div>
</template>

<script>
export default {
  props: {
    error: {
      type: [Object, Error],
      default: () => {},
    },
  },
}
</script>

So far, so obvious. Think of this more as a component than a layout. You don't need to include any components you normally have in your default layout as this layout will be used here. You can specify a custom layout if you want to. Read more about this special layout in the docs.

This works fine already in your development setup but will not work when you deploy to netlify. Netlify already comes with a very simple 404 page out of the box. and If you want to use your own, you just need to create a file called 404.html. To do this in nuxt you can add the following to your config file.

nuxt.config.js
generate: {
    fallback: true,
},

This makes a 404.html page when you run nuxt generate.

This works great for all normal pages. But with the nuxt content module you need to make sure that you wrap your asyncData to throw an error, if the markdown file is not found. Here is what that looks like in my post template.

posts/_slug.vue
...
async asyncData({ $content, params, error }) {
    try {
        const article = await $content('articles', params.slug).fetch();
        return { article };
    } catch (err) {
        error({
            statusCode: 404,
            message: 'Page could not be found',
        });
    }
}
...

Now this simply sends a 404 if something is wrong. You could easily build it out to check on the error and do more specific handling if you need to.