Nuxt Prerendering
Introduction
When prerendering routes using Nuxt through either nuxi generate
or using the prerender options, the module
will extract data from the generated HTML and add it to the sitemap.
This can be useful if you have dynamic routes that you want to be included in the sitemap and want to minimise your configuration.
Extracted HTML Data
The following data can be extracted from the raw HTML.
images
- Adds image entries<image:image>
.
Passes any <img>
tags within the <main>
tag. Opt-out by disabling discoverImages
.
videos
- Adds video entries<video:video>
.
Passes any <video>
tags within the <main>
tag. Opt-out by disabling discoverVideos
.
lastmod
- Adds lastmod date<lastmod>
.
Uses the opengraph article:modified_time
and article:published_time
meta tag.
Enabling Nuxt Prerendering
You will need to use configuration to enable this feature.
export default defineNuxtConfig({
nitro: {
prerender: {
// enabled by default with nuxt generate, not required
crawlLinks: true,
// add any routes to prerender
routes: ['/']
}
}
})
You can also use route rules to enable prerendering for specific routes.
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true }
}
})
Prerendering the Sitemap on Build
If you're using nuxi build
and want to prerender the sitemap on build, you can add the sitemap path to the nitro.prerender.routes
option.
export default defineNuxtConfig({
nitro: {
prerender: {
routes: ['/sitemap.xml']
}
}
})
Customizing the prerender data
If needed, you can customize the prerender data by using the Nitro hooks.
Here is a simple recipe that will extract YouTube video iframes and add them to the sitemap.
import type { ResolvedSitemapUrl } from '#sitemap/types'
export default defineNuxtConfig({
modules: [
// run this before the sitemap moduke
(_, nuxt) => {
nuxt.hooks.hook('nitro:init', async (nitro) => {
nitro.hooks.hook('prerender:generate', async (route) => {
const html = route.contents
// check for youtube video iframes and append to the videos array
const matches = html.match(/<iframe.*?youtube.com\/embed\/(.*?)".*?<\/iframe>/g)
if (matches) {
const sitemap = route._sitemap || {} as ResolvedSitemapUrl
sitemap.videos = sitemap.videos || []
for (const match of matches) {
const videoId = match.match(/youtube.com\/embed\/(.*?)" /)[1]
sitemap.videos.push({
title: 'YouTube Video',
description: 'A video from YouTube',
content_loc: `https://www.youtube.com/watch?v=${videoId}`,
thumbnail_loc: `https://img.youtube.com/vi/${videoId}/0.jpg`,
})
}
// the sitemap module should be able to pick this up
route._sitemap = sitemap
}
})
})
},
],
})