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.
Top comments (0)