Generating Sitemap Entries For Nuxt Content
Tags: nuxt, vue, sitemap
Published: 2020-09-03 16:13:10

Whilst launching my new site ([https://jackwhiting.co.uk](https://jackwhiting.co.uk/)) I chose to use [Nuxt Content](https://content.nuxtjs.org/) for managing my blog posts, works, and other content. Whilst 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`](https://www.npmjs.com/package/@nuxtjs/sitemap) module installed. Open up your project in the terminal and run the following.

```bash
yarn add @nuxtjs/sitemap
```

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

```js
export default {
  modules: ['@nuxt/content', '@nuxtjs/sitemap']
}
```

<blockquote class="info">This should always go after any other modules you've included to ensure all routes are caught. </blockquote>

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.

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

For a full list of sitemap options, you can check out the [readme](https://www.npmjs.com/package/@nuxtjs/sitemap).

## 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

```js
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

```js
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.

```js
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.

```js
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](https://twitter.com/jackabox)).