DEV Community

Verity Stothard
Verity Stothard

Posted on • Originally published at veritystothard.com

How to setup dynamic routes in Nuxt.js

When working with dynamic pages in Nuxt, such as when we have a CMS with blog posts, we soon find that we need a way to generate routes for each post, e.g. www.veritystothard.com/blog/a-post/.

I came across this issue when building my own website using Contentful. My dynamic pages worked a treat on first load; the post slug passed in the <nuxt-link /> allowed me to pre-render the required post using the asyncData method, and a call to Contentful returned an entry of type blogPost with a slug matching that in the URL. However, when I refreshed the page, it was gone.

This issue occurred because I had not defined the routes I needed Nuxt to generate for my dynamic page in the config file, so when nuxt generate ran, no routes were created.

A quick fix for the issue is to simply add the route for each post to the routes array in the nuxt.config.js file,

    export default {
    ...
      generate: {
          routes: [
              '/blog/a-post',
              '/blog/another-one'
          ]
      }
    ...
    }

but that approach would soon become tedious and inefficient when adding new posts in the future.

A better approach is to generate an array of routes depending on your entries. For this example, I will be using entries of type blogPost pulled from Contentful, but the concept could apply to various CMS / data sources.

First, I set up my client and did a call to Contentful to return the slug of all entries with the type blogPost. I then formatted each slug to suit the folder structure of my website and pushed it to the routes array (e.g. the slug a-post became /blog/a-post).

    require('dotenv').config()

    const contentful = require('contentful')
    const config = {
      space: process.env.CONTENTFUL_SPACE_ID,
      accessToken: process.env.CONTENTFUL_ACCESS_TOKEN
    }
    const client = contentful.createClient(config)

    export default {
        generate: {
          routes: async function () {
            const entries = await client.getEntries({ content_type: "blogPost" });
            const routes = []
            entries.items.forEach(item => {
              routes.push(`blog/${item.fields.slug}`)
            })
            return routes
          }
       }
    }

To test my solution, I ran yarn generate and saw that a route for each of my pages and posts were logged in the console. I then deployed my changes to my Netlify project and saw that on page refresh, my content persisted 🙌

This post was originally published on veritystothard.com

Top comments (0)