J.Whiting.

Generating Sitemap Entries For Nuxt Content

Whilst launching my new site (hope you like it by the way!) I chose to use Nuxt Content for managing my blog posts, works, and other content. However, when generating the sitemap I noticed that any content created from @nuxt/content was not being added to my sitemap. In this article, we are going to look at how to solve this and get all of your entries listed.

Setup

Before we can do anything we need to make sure we have the @nuxtjs/sitemap module installed. Open up your project in the terminal and run the following.

yarn add @nuxtjs/sitemap

In your nuxt.config.js add the sitemap to your modules.

export default {
  modules: ['@nuxt/content', '@nuxtjs/sitemap']
}
This should always go after any other modules you've included to ensure all routes are caught.

Next, add some defaults for the sitemap configuration - add a hostname and set up an empty function which we will use later to fetch and return the paths of our content.

export default {
  sitemap: {
    hostname: process.env.BASE_URL || 'YOURSITEURL',
    routes: async () => {}
  }
}

For a full list of sitemap options, you can check out the readme.

Adding Your Routes

The way you have set up your content structure may be unique, you may use unique URLs, you may have multiple folders or only want to include one folder. Each of these may change how you need to define your routes, so I have included a few examples below which should let you get set up and run.

Adding Routes From One Directory

routes: async () => {
  const { $content } = require('@nuxt/content')

  const posts = await $content('posts')
    .only(['path'])
    .fetch()

  return posts.map((p) => p.path)
}

Adding Routes From Multiple Directories

routes: async () => {
  const { $content } = require('@nuxt/content')

  const posts = await $content('posts')
    .only(['path'])
    .fetch()
  const works = await $content('works')
    .only(['path'])
    .fetch()

  // Map and concatenate the routes and return the array.
  return []
    .concat(...works.map((w) => w.path))
    .concat(...posts.map((p) => p.path))
}

Expanding Routes With More Information

Sometimes you may want to add lastmod, priority, or other details to your sitemap - we can expand on our included routes by looping around them and adding additional properties.

routes: async () => {
  const { $content } = require('@nuxt/content')

  const posts = await $content('posts').fetch()
  const works = await $content('works').fetch()

  // Setup an empty array we will push to.
  const routes = []

  // Add an entry for the item including lastmod and priorty
  works.forEach((w) =>
    routes.push({
      url: w.path,
      priority: 0.8,
      lastmod: w.updatedAt
    })
  )

  posts.forEach((p) =>
    routes.push({
      url: p.path,
      priority: 0.8,
      lastmod: p.updatedAt
    })
  )

  // return all routes
  return routes
}

Testing Everything Out

After adding your routes to the nuxt.config.js file you can run yarn dev in your terminal. Once everything starts to compile, visit http://localhost:3000/sitemap.xml in your browser you should see all of the content entries listed.

If you don't want to compile your sitemap.xml every time you run yarn dev you can wrap the function in a conditional.

routes: async () => {
  if (process.env.NODE_ENV !== 'production') return

  // rest of the function here
}

I hope this article helped you. If you've found any issues with the content feel free to reach out to me on Twitter (@jackabox).