'Nuxt: Generate does not create html for every route in static target

I wish to generate html files for static deployment.

The package.json dependencies are as follows

  "dependencies": {
    "@nuxt/content": "^1.15.1",
    "@nuxtjs/markdownit": "^2.0.0",
    "core-js": "^3.19.3",
    "nuxt": "^2.15.8",
    "vue": "^2.6.14",
    "vue-server-renderer": "^2.6.14",
    "vue-template-compiler": "^2.6.14",
    "webpack": "^4.46.0"
  },

The content directory is:

content
  blogs
     blog1
        cover.png  // image used as cover
        content.md // content of blog
     blog2
        cover.png
        content.md
     ...

The pages directory is:

pages
   blogs
     _slug.vue
   index.vue

The nuxt.config.js is:

export default {
  target: 'static',
  generate: {
    fallback: '404.html',    
  },

When I run npm run generate, this only creates a index.html in the dist directory. I would like a dist directory structure like:

dist
  _nuxt (dir)
  blogs
    blog1.html
  index.html
  ...

The following have been my observations:

  1. If I add ssr:true or ssr:false in nuxt.config.js it seems to make no difference to the dist directory output.
  2. If I add routes to the generate settings, it generates the output as desired
  generate: {
    ...
    routes: ['blogs/blog1']
  }

From the documentation I thought that nuxt automatically crawled for all routes and generated them.

Is there a way to get what I desire? Can I generate the routes by some looping logic? Thanks



Solution 1:[1]

If you need to generate all pages

you must say which routes Nuxt should generate. There's no way it could know every dynamic route to be generated. Its crawler doesn't have your backend/api data so you must give it manually like you did, or by writing some looping logic that queries it.

Nuxt docs give some examples on how to achieve this:

import axios from 'axios'

export default {
  generate: {
    routes() {
      return axios.get('https://my-api/blogs').then(res => {
        return res.data.map(blog => {
          return '/blogs/' + blog.id
        })
      })
    }
  }
}

Reference: https://nuxtjs.org/docs/configuration-glossary/configuration-generate/#function-which-returns-a-promise

If you don't need to generate all pages

You can simply use Nuxt's fallback page for when a route (like blogs/blog32) doesn't exist. This way it tries to build the page via frontend routing, using your _slug.vue component.

To achieve this behavior, add a fallback: true to your generate settings

export default {
  generate: {
    fallback: '404.html' //or true
  }
}

After that you should make sure that the webserver that the project is deployed on redirects to your 404.html. Some servers do this automatically, but others don't.

In my case (apache) I had to add to my dist/.htaccess file the following line for the redirect to happen

ErrorDocument 404 /404.html

Reference: https://nuxtjs.org/docs/configuration-glossary/configuration-generate/#fallback

Solution 2:[2]

It now seems to work. The following seems to work:

  1. Added ssr:true in nuxt.config.js
//nuxt.config.js
export default {
  target: 'static',
  
  ssr: true,

  generate: {
    fallback: '404.html',    
  },
  ...

Then,

  1. Then, npm run build

  2. Followed by, npm run generate

Now I notice that all the blog pages are getting generated in the dist directory

  1. To confirm run, npm run start

Solution 3:[3]

From the documentation (https://content.nuxtjs.org/advanced#static-site-generation):

Since Nuxt 2.14+, nuxt generate has a crawler feature integrated which will crawl all your links and generate your routes based on those links.

So Nuxt will generate pages that has a link within your site.

If you want to create a page for all your markdown files you can use this in your configuration:

generate: {
  async routes () {
    const { $content } = require('@nuxt/content')
    const files = await $content({ deep: true })
      .where({ extension: { $eq: '.md' } })
      .only(['path']).fetch()

    return files.map(file => file.path === '/index' ? '/' : file.path)
  }
},

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 José
Solution 2 RmR
Solution 3 Fernando González