How to create a Sitemap in Nuxt Content
Michaล Kuncio
Posted on October 11, 2023
Nuxt Content is an amazing tool that makes working with markdown content on Nuxt projects a breeze. Thanks to the power of Nuxt server routes, it's really easy to create a sitemap of our pages.
Let's take a look at the code.
import { SitemapStream, streamToPromise } from 'sitemap';
import { serverQueryContent } from '#content/server';
export default defineEventHandler(async (event) => {
const docs = await serverQueryContent(event).find();
const staticSites = [
{
_path: '/'
},
{
_path: '/about'
},
{
_path: '/open-source'
}
];
const sitemapElements = [...staticSites, ...docs];
const sitemap = new SitemapStream({
hostname: import.meta.env.VITE_BASE_URL as string
});
for (const doc of sitemapElements) {
sitemap.write({
url: doc._path,
changefreq: 'monthly'
});
}
sitemap.end();
return streamToPromise(sitemap);
});
First of all, let's create a new API route inside api/routes directory by creating a new file called 'sitemap.ts'. Thanks to that, the RRS feed will be available on your-domain.com/sitemap.xml.
Next, inside our defineEventHandler, we have to fetch all articles by using serverQyeryContent:
const docs = await serverQueryContent(event).find();
If you have any other static pages like for example contact or about, you can create an array with those pages:
const staticSites = [
{
_path: '/'
},
{
_path: '/about'
},
{
_path: '/open-source'
}
];
And now, we can combine our articles with static pages:
const sitemapElements = [...staticSites, ...docs];
Next up, let's create a sitemap stream by using the utility function from the 'sitemap' package:
const sitemap = new SitemapStream({
hostname: import.meta.env.VITE_BASE_URL as string
});
Now when we have a sitemap stream, we can iterate over our sitemap elements and write them to the sitemap stream:
for (const doc of sitemapElements) {
sitemap.write({
url: doc._path,
changefreq: 'monthly'
});
}
Next, we have to fetch all the documents we want to include inside our RRS feed. We can make use of the serverQueryContent function from '#content/server':
const docs = await serverQueryContent(event)
.sort({ date: -1 })
.where({ _partial: false })
.find();
Next up, we have to iterate over our docs and put every one of them to our previously created feed object:
for (const doc of docs) {
feed.item({
title: doc.title ?? '-',
url: `${BASE_URL}${doc._path}`,
date: doc.date,
description: doc.description
});
}
Finally, we have to end the stream and return our sitemap stream as a Promise by using the streamToPromise function from the 'sitemap' package.
sitemap.end();
return streamToPromise(sitemap);
Alternatively, if you would like to prerender the sitemap all you have to do is to specify prerender routes in nuxt config:
export default defineNuxtConfig({
// ...
nitro: {
prerender: {
routes: ['/sitemap.xml']
}
},
});
And that's all! I love how simple this solution is thanks to Nuxt server routes and nitro prerendering.
Posted on October 11, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.