Nuxt error page for Netlify

written on April 9, 2024

Netlify and Nuxt combined is a good choice for fast prototyping or even final web applications. I recently tried to find the easiest way to have a proper 404 page generated by Nuxt for Netlify deployments. As it was a bit of up and down and delicate configurations, I document it here to my future self how to do it.

Setup

In short, I'm using the Nuxt v3 (currently 3.11.0), Nuxt content module v2 (currently 2.12.1) and deploying to Netlify. I use the command npm run build as recommended instead of older generate command and use the netlify-static preset (by setting SERVER_PRESET = "netlify-static" env var) so that the server side does not consume netlify function calls.

My goal was to:

  • have a custom error page for all kinds of error, even though technically seen we are only dealing with 400s in this setup and probably only 404, 403 and 401
  • use that same page for Netlify's error page (meaning to render same page for 404.html)
  • use that same page for client side errors (when something goes wrong after hydration, for example while navigating beyond first page)
  • finally (as always) to have the least configuration or changes for this to work

Context

Netlify does pickup a file named 404.html if such exists and shows that for errors.

Nuxt itself has a default error page even though I wanted to change this due to other reasons, but functionally seen this was already given.

Also, Nuxt content does generate the static 404.html file in default setup, however the file was showing an empty page when site was "built" using that mentioned preset and not that Nuxt error page. This proved to be major part of the problem.

In dev mode (npm run dev) it was working all fine.

Solution

In order to have a custom error page, one should create error.vue and customize it. You can follow the great tutorial here to understand it in details.

Next step is to configure the nitro prerenderer (which Nuxt is using to generate static files) to also crawl and render the 404.html page. This is done by adding/changing the following section in nuxt.config.ts (or its equivalent .js file):

// nuxt.config.ts
export default defineNuxtConfig({
  //... other config options
  nitro: {
    preset: 'netlify-static',   // this can be ommited if set as env variable
    prerender: {
      crawlLinks: true,
      routes: [
        '/',
        '/404.html'             // this enforces the crawling
      ]
    }
  },
  //... other config options
})

Up until here one can build and deploy to Netlify and will see his/her custom error page in cases of not found paths. However, one small piece is still missing. Now if in any page you have a logic that can still be triggered on client side and result in an error case, you will not see the error page. In fact, I was just seeing the error in console and nothing changed on the UI, totally missing the error situation as an end user.

As an example of such a case, let say on each page's setup you want to do an API call and if it returns an error, you want to show an error. You want this call to be done on client side (not at generation/build time). A simplified example would look like:

<!-- pages/somepage.vue -->
<script setup lang="ts">
const {data, error} = await doSomethingAsync(/*...*/)

if (error.value || !data.value) {
  throw createError({
    fatal: true,                        // this is the highlight of the show!
    statusCode: 404,
    statusMessage: 'Product Not Found'
  })
}
</script>

Using createError is documented on Nuxt docs but what is important here is adding fatal: true, as otherwise this error will not redirect to error page.

Having all these in place, the build results and Netlify play well together and you will see your custom error page even in case of (fatal!) client side errors.

Comments

Leave a comment

Previous comments

published on https://naghavi.me/blog/nuxt-error-page-on-netlify
all rights reserved for Mohammad Naghavi