@houxiaohou/nuxt-simple-sitemap
v2.5.4
Published
The simplest way to add XML Sitemaps to your Nuxt 3 site.
Downloads
2
Readme
ℹ️ Looking for a complete SEO solution? Check out Nuxt SEO Kit.
Features
- 📦 Multi-sitemap support (automatic and manual chunking)
- 🤖 Dynamic runtime URL support
- 🎨 Styled XML for easier debugging
- 😌 Automatic lastmod and image discovery
- 🔄 Route config using route rules
- 🏞️ Handle trailing slashes
Zero Config Integrations
Adds all entries automatically with generated lastmod
. Images are included from any <img>
tags
Sitemap entries will be included automatically.
Will automatically add hreflang
alternatives for each non-default locale.
Demos
Install
npm install --save-dev nuxt-simple-sitemap
# Using yarn
yarn add --dev nuxt-simple-sitemap
Setup
nuxt.config.ts
export default defineNuxtConfig({
modules: [
'nuxt-simple-sitemap',
],
})
Set Site URL (required when prerendering)
For prerendered sitemaps, you'll need to provide the URL of your site in order to generate the sitemap.xml.
export default defineNuxtConfig({
// Recommended
runtimeConfig: {
public: {
siteUrl: process.env.NUXT_PUBLIC_SITE_URL || 'https://example.com',
}
},
// OR
sitemap: {
siteUrl: 'https://example.com',
},
})
How it works
This module has been built to provide as simple of configuration as possible.
To do this, it collects all possible sitemap URLs from the following sources:
- All files in the pages directory match routes (can be disabled with
inferStaticPagesAsRoutes: false
) - Prerendered routes (see Zero Config Prerendering)
- User provided dynamic routes (see Handling dynamic URLs)
It then will filter these URLs based on the following rules:
- Module Config / Sitemap Entry:
exclude
- Array of glob patterns to exclude from the sitemap - Module Config / Sitemap Entry:
include
- Array of glob patterns to include in the sitemap - Route Rules:
index
- Whether a specific page can be indexed, not indexable pages are excluded from the sitemap
Usage
Zero Config Prerendering (optional)
While not required, this module is simplest to use when full prerendering is enabled, as it will automatically discover all prerendered routes.
For each discovered prerendered route it will auto-discover all pages <image:image>
entries as well as the lastmod
date
(when autoLastmod
isn't disabled).
To ensure images are discovered for the sitemap, make sure you main site content is wrapped with a <main>
tag.
You can make sure this behaviour is enabled with the following config:
export default defineNuxtConfig({
nitro: {
prerender: {
crawlLinks: true,
routes: [
'/',
]
}
}
})
Multiple Sitemap Support
By default, the sitemap module will generate a single sitemap.xml file.
If you want to generate multiple sitemaps, you can use the sitemaps
option.
- Automatic Chunking:
true
This will automatically chunk your sitemap into multiple-sitemaps for every 1000 URLs, using the 0-sitemap.xml
, 1-sitemap.xml
naming convention.
You should avoid using this if you have less than 1000 URLs.
export default defineNuxtConfig({
sitemap: {
// automatically chunk into multiple sitemaps
sitemaps: true,
},
})
- Manual chunking
You can manually chunk your sitemap into multiple sitemaps by providing filter options.
export default defineNuxtConfig({
sitemap: {
// manually chunk into multiple sitemaps
sitemaps: {
posts: {
include: [
'/blog/**',
],
// example: give blog posts slightly higher priority (this is optional)
defaults: { priority: 0.7 },
},
pages: {
exclude: [
'/blog/**',
]
},
},
},
})
For each sitemaps entry, you can provide the following options:
include
- Array of glob patterns to include in the sitemapexclude
- Array of glob patterns to exclude from the sitemapdefaults
- Sitemap default values such aslastmod
,changefreq
, orpriority
urls
- Array of static URLs to include in the sitemap. You should avoid using this option if you have a lot of URLs, instead see below Handling dynamic URLs
Handling dynamic URLs
For Nuxt apps where all the pages aren't prerendered, you may want to provide the list of dynamic routes to be included in the sitemap.xml.
The recommended approach is to create your own api endpoint that returns the list of all dynamic routes.
By default, the module will check for a server/api/_sitemap-urls.ts
endpoint.
An example of URLs might look like this:
export default cachedEventHandler(async () => {
const [
posts,
pages,
products
] = await Promise.all([
$fetch('/api/posts'),
$fetch('/api/pages'),
$fetch('/api/products')
])
return [...posts, ...pages, ...products].map(p => {
return { loc: p.url, lastmod: p.updatedAt }
})
}, {
name: 'sitemap-dynamic-urls',
maxAge: 60 * 10 // cache URLs for 10 minutes
})
Hint: While not required, it's recommended to use the cacheEventHandler
and set an appropriate maxAge
, 10 minutes is a good default.
This API endpoint will be called by the sitemap module to fetch the list of dynamic URLs whenever a sitemap is generated.
If you'd prefer to use a different endpoint, you can configure the dynamicUrlsApiEndpoint
option.
export default defineNuxtConfig({
sitemap: {
dynamicUrlsApiEndpoint: '/__sitemap',
},
})
With the above config you would create a server/routes/__sitemap.ts
file.
Start-time dynamic URLs
If you prefer a simpler config, you can provide the dynamic URLs at start-time using the urls
config.
Note that this approach may not be suitable for large sites.
export default defineNuxtConfig({
sitemap: {
// provide dynamic URLs to be included
urls: async () => {
const blogPages = await getBlogPages()
return blogPages.map((page) => ({
loc: `/blog/${page.slug}`,
lastmod: page.updatedAt,
changefreq: 'daily',
priority: 0.8,
}))
},
},
})
Auto Lastmod
By default, the sitemap module will automatically detect the lastmod
date for each URL.
This is done by looking at the mtime
of the page file associated with a route.
If a route can't be associated with a page file then the current date will be used.
You can disable this behaviour by setting autoLastmod: false
.
export default defineNuxtConfig({
sitemap: {
autoLastmod: false,
},
})
Route Rules Config
To change the behavior of sitemap.xml entries, you can use Nitro route rules.
nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
// Don't add any /secret/** URLs to the sitemap.xml
'/secret/**': { index: false },
// modify the sitemap.xml entry for specific URLs
'/about': { sitemap: { changefreq: 'daily', priority: 0.3 } }
}
})
See sitemaps.org for all available options.
Sitemap Entry Schema
The sitemap entry schema mostly follows the sitemap specification, the following options are supported:
loc
- URL of the page.lastmod
- The date of last modification of the filechangefreq
- How frequently the page is likely to change.priority
- The priority of this URL relative to other URLs on your site.images
- An array of images to include in the sitemap entry as<image:image>
.video
- An array of videos to include in the sitemap entry as<video:video>
.news
- An array of news to include in the sitemap entry as<news:news>
.alternatives
- An array of alternatives to include in the sitemap entry as<xhtml:link rel="alternate" ...>
.
Nuxt Hooks
sitemap:prerender
Type: async (ctx: { urls: SitemapConfig; sitemapName: string }) => void | Promise<void>
This hook allows you to modify the sitemap(s) urls when they're prerendered.
Note: For dynamic runtime sitemaps this hook won't do anything.
export default defineNuxtConfig({
hooks: {
'sitemap:prerender': (ctx) => {
// single sitemap example - just add the url directly
ctx.urls.push({
loc: '/my-secret-url',
changefreq: 'daily',
priority: 0.8,
})
// multi sitemap example - filter for a sitemap name
if (ctx.sitemapName === 'posts') {
ctx.urls.push({
loc: '/posts/my-post',
changefreq: 'daily',
priority: 0.8,
})
}
},
},
})
Nitro Hooks
sitemap:sitemap-xml
Type: async (ctx: { urls: SitemapConfig; sitemapName: string }) => void | Promise<void>
This hook allows you to modify the sitemap.xml as runtime before it is sent to the client.
Note: For prerendered sitemaps this hook won't do anything.
import { defineNitroPlugin } from 'nitropack/runtime/plugin'
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('sitemap:sitemap-xml', async (ctx) => {
// single sitemap example - just add the url directly
ctx.urls.push({
loc: '/my-secret-url',
changefreq: 'daily',
priority: 0.8,
})
// multi sitemap example - filter for a sitemap name
if (ctx.sitemapName === 'posts') {
ctx.urls.push({
loc: '/posts/my-post',
changefreq: 'daily',
priority: 0.8,
})
}
})
})
Module Config
If you need further control over the sitemap.xml URLs, you can provide config on the sitemap
key.
siteUrl
- Type:
string
- Default:
undefined
- Required:
true
The host of your site. This is required to generate the sitemap.xml. Example: https://example.com
trailingSlash
- Type:
boolean
- Default:
false
Whether to add a trailing slash to the URLs in the sitemap.xml.
autoLastmod
- Type:
boolean
- Default:
true
Whether to automatically detect the lastmod
date for each URL.
If the lastmod
date can't be inferred from a route page file it will use the current Date.
sitemaps
- Type:
SitemapConfig[] | boolean
- Default:
false
Whether to generate multiple sitemaps.
See Multiple Sitemap Support for details.
enabled
- Type:
boolean
- Default:
true
Whether to generate the sitemap.xml.
defaults
- Type:
object
- Default:
{}
Default values for the sitemap.xml entries. See sitemaps.org for all available options.
urls
- Type:
() => MaybePromise<SitemapEntry[]> | MaybePromise<SitemapEntry[]>
- Default:
[]
Provide custom URLs to be included in the sitemap.xml.
include
- Type:
string[]
- Default:
['/**']
Filter routes that match the given rules.
export default defineNuxtConfig({
sitemap: {
include: [
'/my-hidden-url'
]
}
})
exclude
- Type:
string[]
- Default:
undefined
Filter routes that match the given rules.
export default defineNuxtConfig({
sitemap: {
exclude: [
'/my-secret-section/**'
]
}
})
Additional config extends sitemap.js.
inferStaticPagesAsRoutes
- Type:
boolean
- Default:
true
Will generate routes from your static page files. Useful to disable if you're using the i18n module with custom routes.
xsl
- Type: `string | false
- Default:
/__sitemap__/style.xsl
The path to the XSL stylesheet for the sitemap.xml. Set to false
to disable.
discoverImages
- Type:
boolean
- Default:
true
Whether to discover images from routes when prerendering.
autoAlternativeLangPrefixes
- Type:
undefined | false | string[]
- Default:
undefined
Automatically add alternative language prefixes for each entry with the given prefixes. Set to false
to disable.
When using the @nuxtjs/i18n module, this will automatically be set to the configured locales
when left undefined
.
dynamicUrlsApiEndpoint
- Type:
string
- Default:
/api/_sitemap-urls
The API endpoint should be checked for dynamic sitemap entries. When left as the default it will check if the API endpoint exists before fetching it.
By providing a non-default value, it will always fetch the API endpoint.
Sponsors
License
MIT License © 2022-PRESENT Harlan Wilton