Styled Sitemap Generator
Creating stylized sitemaps for next.js applications. Based on the next-sitemap package
Getting started
yarn add styled-sitemap-generator
Create config file
styled-sitemap-generator requires a basic config file (next-sitemap.config.js) under your project root
module.exports = {
siteUrl: process.env.SITE_URL || 'https://example.com',
generateRobotsTxt: true,
}
Building sitemaps
Add styled-sitemap-generator as your postbuild script
{
"build": "next build",
"postbuild": "styled-sitemap-generator"
}
Creating default styles for sitemap
Add styled-sitemap-generator-xsl as your scripts
{
"create-xsl": "styled-sitemap-generator-xsl",
}
Building sitemaps with styles
Add styled-sitemap-generator as your postbuild script
{
"build": "next build",
"postbuild": "styled-sitemap-generator && styled-sitemap-generator-update"
}
styled-sitemap-generator
requires a basic config file (next-sitemap.config.js
) under your project root
Configuration Options
property | description | type |
---|
siteUrl | Base url of your website | string |
output (optional) | Next.js output modes. Check documentation. | standalone , export |
changefreq (optional) | Change frequency. Default daily | string |
priority (optional) | Priority. Default 0.7 | number |
sitemapBaseFileName (optional) | The name of the generated sitemap file before the file extension. Default "sitemap" | string |
alternateRefs (optional) | Denote multi-language support by unique URL. Default [] | AlternateRef[] |
sitemapSize(optional) | Split large sitemap into multiple files by specifying sitemap size. Default 5000 | number |
autoLastmod (optional) | Add <lastmod/> property. Default true | true |
exclude (optional) | Array of relative paths (wildcard pattern supported) to exclude from listing on sitemap.xml or sitemap-*.xml . e.g.: ['/page-0', '/page-*', '/private/*'] .
Apart from this option next-sitemap also offers a custom transform option which could be used to exclude urls that match specific patterns | string[] |
sourceDir (optional) | next.js build directory. Default .next | string |
outDir (optional) | All the generated files will be exported to this directory. Default public | string |
transform (optional) | A transformation function, which runs for each relative-path in the sitemap. Returning null value from the transformation function will result in the exclusion of that specific path from the generated sitemap list. | async function |
additionalPaths (optional) | Async function that returns a list of additional paths to be added to the generated sitemap list. | async function |
generateIndexSitemap | Generate index sitemaps. Default true | boolean |
generateRobotsTxt (optional) | Generate a robots.txt file and list the generated sitemaps. Default false | boolean |
robotsTxtOptions.transformRobotsTxt (optional) | Custom robots.txt transformer function. (Example: custom-robots-txt-transformer)
Default: async(config, robotsTxt)=> robotsTxt | async function |
robotsTxtOptions.policies (optional) | Policies for generating robots.txt .
Default:
[{ userAgent: '*', allow: '/' }] | IRobotPolicy[] |
robotsTxtOptions.additionalSitemaps (optional) | Options to add additional sitemaps to robots.txt host entry | string[] |
robotsTxtOptions.includeNonIndexSitemaps (optional) | From v2.4x onwards, generated robots.txt will only contain url of index sitemap and custom provided endpoints from robotsTxtOptions.additionalSitemaps . This is to prevent duplicate url submission (once through index-sitemap -> sitemap-url and once through robots.txt -> HOST)
Set this option true to add all generated sitemap endpoints to robots.txt
Default false (Recommended) | boolean |
Custom transformation function
Custom transformation provides an extension method to add, remove or exclude path
or properties
from a url-set. Transform function runs for each relative path
in the sitemap. And use the key
: value
object to add properties in the XML.
Returning null
value from the transformation function will result in the exclusion of that specific relative-path
from the generated sitemap list.
module.exports = {
transform: async (config, path) => {
if (customIgnoreFunction(path)) {
return null
}
if (customLimitedField(path)) {
return {
loc: path,
changefreq: 'weekly',
}
}
return {
loc: path,
changefreq: config.changefreq,
priority: config.priority,
lastmod: config.autoLastmod ? new Date().toISOString() : undefined,
alternateRefs: config.alternateRefs ?? [],
}
},
}
Additional paths function
additionalPaths
this function can be useful if you have a large list of pages, but you don't want to render them all and use fallback: true. Result of executing this function will be added to the general list of paths and processed with sitemapSize
. You are free to add dynamic paths, but unlike additionalSitemap
, you do not need to split the list of paths into different files in case there are a lot of paths for one file.
If your function returns a path that already exists, then it will simply be updated, duplication will not happen.
module.exports = {
additionalPaths: async (config) => {
const result = []
result.push({ loc: '/additional-page-1' })
result.push({
loc: '/additional-page-2',
changefreq: 'yearly',
priority: 0.7,
lastmod: new Date().toISOString(),
alternateRefs: [
{
href: 'https://es.example.com',
hreflang: 'es',
},
{
href: 'https://fr.example.com',
hreflang: 'fr',
},
],
})
result.push(await config.transform(config, '/additional-page-3'))
return result
},
}
Google News, image and video sitemap
Url set can contain additional sitemaps defined by google. These are
Google News sitemap,
image sitemap or
video sitemap.
You can add the values for these sitemaps by updating entry in transform
function or adding it with
additionalPaths
. You have to return a sitemap entry in both cases, so it's the best place for updating
the output. This example will add an image and news tag to each entry but IRL you would of course use it with
some condition or within additionalPaths
result.
const config = {
transform: async (config, path) => {
return {
loc: path,
changefreq: config.changefreq,
priority: config.priority,
lastmod: config.autoLastmod ? new Date().toISOString() : undefined,
images: [{ loc: 'https://example.com/image.jpg' }],
news: {
title: 'Article 1',
publicationName: 'Google Scholar',
publicationLanguage: 'en',
date: new Date(),
},
}
},
}
export default config
Full configuration example
Here's an example next-sitemap.config.js
configuration with all options
module.exports = {
siteUrl: 'https://example.com',
changefreq: 'daily',
priority: 0.7,
sitemapSize: 5000,
generateRobotsTxt: true,
exclude: ['/protected-page', '/awesome/secret-page'],
alternateRefs: [
{
href: 'https://es.example.com',
hreflang: 'es',
},
{
href: 'https://fr.example.com',
hreflang: 'fr',
},
],
transform: async (config, path) => {
return {
loc: path,
changefreq: config.changefreq,
priority: config.priority,
lastmod: config.autoLastmod ? new Date().toISOString() : undefined,
alternateRefs: config.alternateRefs ?? [],
}
},
additionalPaths: async (config) => [
await config.transform(config, '/additional-page'),
],
robotsTxtOptions: {
policies: [
{
userAgent: '*',
allow: '/',
},
{
userAgent: 'test-bot',
allow: ['/path', '/path-2'],
},
{
userAgent: 'black-listed-bot',
disallow: ['/sub-path-1', '/path-2'],
},
],
additionalSitemaps: [
'https://example.com/my-custom-sitemap-1.xml',
'https://example.com/my-custom-sitemap-2.xml',
'https://example.com/my-custom-sitemap-3.xml',
],
},
}
Above configuration will generate sitemaps based on your project and a robots.txt
like this.
# *
User-agent: *
Allow: /
# test-bot
User-agent: test-bot
Allow: /path
Allow: /path-2
# black-listed-bot
User-agent: black-listed-bot
Disallow: /sub-path-1
Disallow: /path-2
# Host
Host: https://example.com
# Sitemaps
Sitemap: https://example.com/sitemap.xml # Index sitemap
Sitemap: https://example.com/my-custom-sitemap-1.xml
Sitemap: https://example.com/my-custom-sitemap-2.xml
Sitemap: https://example.com/my-custom-sitemap-3.xml