Generate a sitemap using the Nuxt 3 Content module

If you're using Nuxt 3 and looking to generate a sitemap for your site, you may have run into some challenges finding a solution that works. I recently encountered this issue myself and spent some time searching for a solution that would work with Nuxt 3 and the Nuxt Content module.

Creating a Nuxt 3 sitemap for your website is a big task, especially if you're new to the framework or transitioning from Nuxt 2. The challenge becomes even more pronounced when you're trying to use the Nuxt Content module. I found myself in this exact situation not too long ago, and after much experimentation, I managed to find a solution that worked perfectly. In this blog post, I'll share this solution with you, providing a detailed, step-by-step guide on how to generate a sitemap using the Nuxt 3 Content module.

The Nuxt Content Module Fork: A Brief Overview

My journey to finding the perfect solution started with a fork of the @nuxt/content module. While the original module is quite powerful, the fork offered additional features that were particularly useful for my project. If you're interested, you can explore the fork on its GitHub - sitemap-module-nuxt-3 Fork. However, the described method should work with the original module as well.

Setting the Stage: Sitemap Configuration in nuxt.config.ts

The first step in the process is to set up the sitemap configuration in your nuxt.config.ts file. This is where you'll define the basic parameters for your sitemap, such as the hostname, cache time, and default values for the frequency of changes, priority, and last modification date. Here's what the code looks like:

import blogRoutes from './helpers/blogRoutes'

// ...

sitemap: {
hostname: 'http://localhost',
cacheTime: 1000 * 60 * 15,
routes: blogRoutes,
defaults: {
changefreq: 'weekly',
priority: 1,
lastmod: new Date().toISOString()

We're importing a helper function, blogRoutes in this code block that we'll define later. The sitemap object contains the configuration for our sitemap. The hostname is the base URL of your site, cacheTime is the time in milliseconds that the sitemap will be cached, and routes is a function or array that will provide the routes for the sitemap. The defaults object contains default values for each route in the sitemap.

Building the Bridge: Constructing the API Route in helpers/blogRoutes.js

Next, we need to construct our API route. This is a crucial step because we can't use imports in this context. Instead, we'll fetch our routes from an API endpoint that can use import. Here's the code you'll need to add to your helpers/blogRoutes.js file:

* We can't use imports here, so instead we just fetch
* our routes from an API endpoint that can use import.
export default async () => {
return await $fetch('/api/blog_routes', {
method: 'POST',
headers: {
'Content-Type': 'application/json',

In this block, we're defining an asynchronous function that fetches our blog routes from the /api/blog_routes endpoint. We're using the $fetch method, a universal way to fetch data in Nuxt. The method: 'POST' part specifies that we're making a POST request, and the headers object sets the content type of our request to JSON.

The Final Piece: Fetching Blog Posts in api/blog_routes.js

The last step in the process is to fetch all your blog posts and return an array of routes for the sitemap. We'll use the serverQueryContent function in our api/blog_routes.js file to do this. Here's the code:

import { eventHandler } from 'h3'
import { serverQueryContent } from '#content/server'

export default eventHandler(async event => {
const { req, res } = event
if (req.method !== 'POST') {
res.statusCode = 405

// const config = useRuntimeConfig()
const docs = await serverQueryContent(event).find()
return => {
return { url: item._path }

In this code block, we're importing the eventHandler function from the h3 library and the serverQueryContent function from the Nuxt Content module. The eventHandler function is used to handle HTTP events, and serverQueryContent is used to query content on the server side. We're defining an asynchronous function that handles an event and checks if the request method is POST, and if not, it sends a 405 status code and ends the response. If the request method is POST, it fetches all documents (in this case, blog posts) and returns an array of routes for the sitemap.


And that's it! You now have a detailed guide on how to generate a sitemap using the Nuxt 3 Content module. I hope this guide helps you, whether you're working on your first Nuxt 3 project or an experienced developer looking for a refresher.

Remember, the world of web development is constantly evolving, and staying up-to-date with the latest trends and technologies is key to staying ahead of the curve. So, keep learning, experimenting, and, most importantly, coding!

Further Reading and Resources

If you're interested in learning more about Nuxt 3, sitemaps, or web development in general, here are some resources that you might find helpful:

a web designers face on a laptop screen

Schedule a free call -we'd love to talk about your web design project

We'll talk for around 10 minutes on phone or video about what you're looking to do. Free, no sales.

Leed's web design - transform your business

We help you imagine, create, market and evolve an effective digital presence for your business or brand. Leveraging creative technology to deliver high performance, cost effective digital marketing and design.

Leeds Local Business: Exploring ideas together