Generate static Storyblok site with dynamic pages (Nuxt.js) | Double Marvellous
Back to Blog
Development Oct 14, 2024 4 min read

Generate static Storyblok site with dynamic pages (Nuxt.js)

Generate static Storyblok site with dynamic pages (Nuxt.js)

Heyo - so got stuck on this one last night and thought I would share.

When generating a site that takes content from Storyblok in Nuxt, I noticed initially that the pages weren’t being built out. I had run into this with Gatsby/GraphCMS before, and it makes sense. The framework (Gatsby or Nuxt or whatever) needs to know what pages you have before it can generate them and fill them with your content.

Anywho, I looked at the docs and they initially didn’t work, so I thought I would share how I got it working here:

Before I added this, I made sure I had installed axios. So I ran yarn add @nuxtjs/axios

Here’s my nuxt.config.js

export default {

  target: 'static',

  head: {
    title: 'Site name',
    htmlAttrs: {
      lang: 'en'
    },
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: '' },
      { name: 'format-detection', content: 'telephone=no' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },

  css: [
  '~assets/css/bulma.css',
  ],

  plugins: [
  '~/plugins/components'
  ],

  components: true,

  buildModules: [
  ],

  // Modules: here's where I you add your modules for storyblok and axio
  modules: [
  '@nuxtjs/axios',    //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< add axios module in here
      ['storyblok-nuxt',
      {
        accessToken: 'YOUR STORYBLOK TOKEN GOES HERE',
        cacheProvider: 'memory'
      },]
  ],

//some options for axios go here if you have them
axios: {
    // extra config e.g
    // BaseURL: 'https://link-to-API'
  },

  build: {
  },

//what follows is the generate function from the docs. But change where axios is called! Otherwise it cries when you generate...

generate: {
  routes: function (callback) {
    const token = `YOUR STORYBLOK TOKEN GOES HERE`
    const axios = require('axios'); //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< add this in here
    const per_page = 10
    const version = 'published'
    let cache_version = 0
 
    let page = 1
 
    // other routes that are not in Storyblok with their slug.
    let routes = ['/'] // adds home directly but with / instead of /home
 
    // Load space and receive latest cache version key to improve performance
    axios.get(`https://api.storyblok.com/v1/cdn/spaces/me?token=${token}`).then((space_res) => {
 
      // timestamp of latest publish
      cache_version = space_res.data.space.version
 
      // Call first Page of the Stories
      axios.get(`https://api.storyblok.com/v1/cdn/stories?token=${token}&version=${version}&per_page=${per_page}&page=${page}&cv=${cache_version}`).then((res) => {
 
        res.data.stories.forEach((story) => {
          if (story.full_slug != 'home') {
            routes.push('/' + story.full_slug)
          }
        })
 
        // Check if there are more pages available otherwise execute callback with current routes.
        const total = res.headers.total
        const maxPage = Math.ceil(total / per_page)
        if (maxPage <= 1) {
          callback(null, routes)
          return;
        }
 
        // Since we know the total we now can pregenerate all requests we need to get all stories
        let contentRequests = []
        for (let page = 2; page <= maxPage; page++) {
          contentRequests.push(axios.get(`https://api.storyblok.com/v1/cdn/stories?token=${token}&version=${version}&per_page=${per_page}&page=${page}`))
        }
 
        // Axios allows us to exectue all requests using axios.spread we will than generate our routes and execute the callback
        axios.all(contentRequests).then(axios.spread((...responses) => {
          responses.forEach((response) => {
            response.data.stories.forEach((story) => {
              if (story.full_slug != 'home') {
                routes.push('/' + story.full_slug)
              }
            })
          })
 
          callback(null, routes)
        })).catch(callback)
      })
    })
  }
}

}

//Hope that helps someone!

Double Marvellous

AI Chatbot

Double Marvellous.