Use a netlify build plugin to generate your nuxt routes

unsplash-logoMatt Artz

The Problem

I use Directus as my headless CMS of choice for several projects now. I recently added a blog to my agencies nuxt website: webmarken. Since several people are supposed to write content eventually I set it up with Directus as the CMS. Directus has a very convenient webhook feature so triggering the deploy at netlify whenever an article is changed or created was easy to set up.

The problem: even though I create the routes file on each nuxt build, netlify would always use the one in the git repository. Hence new blog posts did not show up in the sitemap. You could navigate to them one the website, but directl loading them caused a 404.

After several fruitless attempts to fix it with nuxt settings and build hooks I discovered netlify build plugins - and that solved the issue for me in about 30 min. Here is the brief rundown.

Setting up the build webhooks between Directus and netlify

With the new directus this really is easy as. Just go to Settings > Webhooks and create two new webhooks for your collection: create and update. Both webhooks should POST to your Netlify build webhook address.

You can easily create one here: https://app.netlify.com/sites/YOURSITE/settings/deploys#build-hooks

old site speed

The Netlify Build Plugin for dynamic Nuxt Routes

Netlify Plugins are pretty straight forward. All you need is a folder in your project root - for example ./build-plugins/routes - with two files:

  • index.js
  • manifest.yml

You can find out more about Netlify Build Plugins in their Documentation

The manifest simply contains the name of your plugin:

name: netlify-create-routes

The index.js file exports a function in nodejs style. For this case we use the onPreBuild hook:

module.exports = {
  onPreBuild: async () => {
    ...
  },
}

The logic I'm using couldn't be simpler. I'm basically reusing what I already have in my this.nuxt.hook('build:before', async (builder) => {}. Of course you'd need to define your own API fetch and route array generation to your needs:

const fetchData = require('../../server/fetchData')
const createRoutes = require('../../server/createRoutes')

module.exports = {
  onPreBuild: async () => {
    console.log('/----------ROUTES--------/')

    // Fetch all posts data from Directus API
    const { posts } = await fetchData()
    console.log('Fetched Content')

    // Create routes array from dynamic pages from posts
    // Store array in ./static/routes.json
    await createRoutes(posts)
    console.log('New Routes created & saved')

    console.log('/---------/ROUTES--------/')
  },
}

Tell Netlify to use the plugin

The last step to make this work is to tell Netlify to use your Plugin while building the project. For this either create or simply add the following to your netlify.toml file in your root directory:

[[plugins]]
  package = "/build-plugins/routes"

Use the routes file in nuxt

You can then go ahead and simply use the routes file in nuxt.config.js like so to get everything running and generation smoothly:

const routes = require('./static/routes.json')
module.exports = {
  ...
  generate: {
    routes
  },
  sitemap: {
    routes
  }
  ...
}