Security News
Bun 1.2 Released with 90% Node.js Compatibility and Built-in S3 Object Support
Bun 1.2 enhances its JavaScript runtime with 90% Node.js compatibility, built-in S3 and Postgres support, HTML Imports, and faster, cloud-first performance.
next-sitemap
Advanced tools
The next-sitemap npm package is a tool designed to generate sitemaps and robots.txt files for Next.js projects. It simplifies the process of creating these files, which are essential for SEO and ensuring that search engines can efficiently crawl and index your website.
Generate Sitemap
This feature allows you to generate a sitemap for your Next.js project. By specifying the siteUrl and other options, you can create a sitemap that helps search engines understand the structure of your website.
module.exports = {
siteUrl: 'https://example.com',
generateRobotsTxt: true, // (optional)
// ...other options
}
Custom Robots.txt
This feature allows you to generate a custom robots.txt file. You can specify different policies for different user agents, which helps control how search engines crawl your site.
module.exports = {
siteUrl: 'https://example.com',
generateRobotsTxt: true,
robotsTxtOptions: {
policies: [
{ userAgent: '*', allow: '/' },
{ userAgent: 'Googlebot', disallow: '/nogoogle' },
],
},
}
Additional Paths
This feature allows you to add additional paths to your sitemap that are not automatically included. This is useful for including dynamically generated pages or other custom routes.
module.exports = {
siteUrl: 'https://example.com',
generateRobotsTxt: true,
additionalPaths: async (config) => [
await config.transform(config, '/additional-page')
],
}
Exclude Paths
This feature allows you to exclude specific paths from your sitemap. This is useful for preventing certain pages, such as admin or login pages, from being indexed by search engines.
module.exports = {
siteUrl: 'https://example.com',
generateRobotsTxt: true,
exclude: ['/admin/*', '/login'],
}
The sitemap package is a general-purpose sitemap generator for Node.js. It provides more flexibility and can be used with any Node.js project, not just Next.js. However, it requires more configuration and does not integrate as seamlessly with Next.js as next-sitemap.
The next-seo package is primarily focused on managing SEO metadata for Next.js projects, but it also includes functionality for generating sitemaps. While it offers a broader range of SEO features, its sitemap generation capabilities are not as specialized or feature-rich as those of next-sitemap.
The react-sitemap-generator package is designed to generate sitemaps for React applications. It can be used with Next.js, but it is not specifically tailored for it, making it less convenient than next-sitemap for Next.js projects.
yarn add next-sitemap
next-sitemap
requires a basic config file (next-sitemap.config.js
) under your project root
ā
next-sitemap
will load environment variables from.env
files by default.
/** @type {import('next-sitemap').IConfig} */
module.exports = {
siteUrl: process.env.SITE_URL || 'https://example.com',
generateRobotsTxt: true, // (optional)
// ...other options
}
Add next-sitemap as your postbuild script
{
"build": "next build",
"postbuild": "next-sitemap"
}
You can also use a custom config file instead of next-sitemap.config.js
. Just pass --config <your-config-file>.js
to build command (Example: custom-config-file)
{
"build": "next build",
"postbuild": "next-sitemap --config awesome.config.js"
}
When using pnpm you need to create a .npmrc
file in the root of your project if you want to use a postbuild step:
//.npmrc
enable-pre-post-scripts=true
š£ From next-sitemap
v2.x onwards, sitemap.xml
will be Index Sitemap. It will contain urls of all other generated sitemap endpoints.
Index sitemap generation can be turned off by setting generateIndexSitemap: false
in next-sitemap config file. (This is useful for small/hobby sites which does not require an index sitemap) (Example: no-index-sitemaps)
Define the sitemapSize
property in next-sitemap.config.js
to split large sitemap into multiple files.
/** @type {import('next-sitemap').IConfig} */
module.exports = {
siteUrl: 'https://example.com',
generateRobotsTxt: true,
sitemapSize: 7000,
}
Above is the minimal configuration to split a large sitemap. When the number of URLs in a sitemap is more than 7000, next-sitemap
will create sitemap (e.g. sitemap-0.xml, sitemap-1.xml) and index (e.g. sitemap.xml) files.
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 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.
/** @type {import('next-sitemap').IConfig} */
module.exports = {
transform: async (config, path) => {
// custom function to ignore the path
if (customIgnoreFunction(path)) {
return null
}
// only create changefreq along with path
// returning partial properties will result in generation of XML field with only returned values.
if (customLimitedField(path)) {
// This returns `path` & `changefreq`. Hence it will result in the generation of XML field with `path` and `changefreq` properties only.
return {
loc: path, // => this will be exported as http(s)://<config.siteUrl>/<path>
changefreq: 'weekly',
}
}
// Use default transformation for all other cases
return {
loc: path, // => this will be exported as http(s)://<config.siteUrl>/<path>
changefreq: config.changefreq,
priority: config.priority,
lastmod: config.autoLastmod ? new Date().toISOString() : undefined,
alternateRefs: config.alternateRefs ?? [],
}
},
}
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.
/** @type {import('next-sitemap').IConfig} */
module.exports = {
additionalPaths: async (config) => {
const result = []
// required value only
result.push({ loc: '/additional-page-1' })
// all possible values
result.push({
loc: '/additional-page-2',
changefreq: 'yearly',
priority: 0.7,
lastmod: new Date().toISOString(),
// acts only on '/additional-page-2'
alternateRefs: [
{
href: 'https://es.example.com',
hreflang: 'es',
},
{
href: 'https://fr.example.com',
hreflang: 'fr',
},
],
})
// using transformation from the current configuration
result.push(await config.transform(config, '/additional-page-3'))
return result
},
}
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.
/** @type {import('next-sitemap').IConfig} */
const config = {
transform: async (config, path) => {
return {
loc: path, // => this will be exported as http(s)://<config.siteUrl>/<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
Here's an example next-sitemap.config.js
configuration with all options
/** @type {import('next-sitemap').IConfig} */
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',
},
],
// Default transformation function
transform: async (config, path) => {
return {
loc: path, // => this will be exported as http(s)://<config.siteUrl>/<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
next-sitemap
now provides two APIs to generate server side sitemaps. This will help to dynamically generate index-sitemap
(s) and sitemap
(s) by sourcing data from CMS or custom source.
getServerSideSitemapIndex
: Generates index sitemaps based on urls provided and returns application/xml
response. Supports next13+ route.{ts,js} file.
getServerSideSitemapIndexLegacy
instead.getServerSideSitemap
: Generates sitemap based on field entires and returns application/xml
response. Supports next13+ route.{ts,js} file.
getServerSideSitemapLegacy
instead.Here's a sample script to generate index-sitemap on server side.
Create app/server-sitemap-index.xml/route.ts
file.
// app/server-sitemap-index.xml/route.ts
import { getServerSideSitemapIndex } from 'next-sitemap'
export async function GET(request: Request) {
// Method to source urls from cms
// const urls = await fetch('https//example.com/api')
return getServerSideSitemapIndex([
'https://example.com/path-1.xml',
'https://example.com/path-2.xml',
])
}
Create pages/server-sitemap-index.xml/index.tsx
file.
// pages/server-sitemap-index.xml/index.tsx
import { getServerSideSitemapIndexLegacy } from 'next-sitemap'
import { GetServerSideProps } from 'next'
export const getServerSideProps: GetServerSideProps = async (ctx) => {
// Method to source urls from cms
// const urls = await fetch('https//example.com/api')
return getServerSideSitemapIndexLegacy(ctx, [
'https://example.com/path-1.xml',
'https://example.com/path-2.xml',
])
}
// Default export to prevent next.js errors
export default function SitemapIndex() {}
Now, next.js
is serving the dynamic index-sitemap from http://localhost:3000/server-sitemap-index.xml
.
List the dynamic sitemap page in robotsTxtOptions.additionalSitemaps
and exclude this path from static sitemap list.
// next-sitemap.config.js
/** @type {import('next-sitemap').IConfig} */
module.exports = {
siteUrl: 'https://example.com',
generateRobotsTxt: true,
exclude: ['/server-sitemap-index.xml'], // <= exclude here
robotsTxtOptions: {
additionalSitemaps: [
'https://example.com/server-sitemap-index.xml', // <==== Add here
],
},
}
In this way, next-sitemap
will manage the sitemaps for all your static pages and your dynamic index-sitemap
will be listed on robots.txt.
Here's a sample script to generate sitemaps on server side.
Create app/server-sitemap.xml/route.ts
file.
// app/server-sitemap.xml/route.ts
import { getServerSideSitemap } from 'next-sitemap'
export async function GET(request: Request) {
// Method to source urls from cms
// const urls = await fetch('https//example.com/api')
return getServerSideSitemap([
{
loc: 'https://example.com',
lastmod: new Date().toISOString(),
// changefreq
// priority
},
{
loc: 'https://example.com/dynamic-path-2',
lastmod: new Date().toISOString(),
// changefreq
// priority
},
])
}
Create pages/server-sitemap.xml/index.tsx
file.
// pages/server-sitemap.xml/index.tsx
import { getServerSideSitemapLegacy } from 'next-sitemap'
import { GetServerSideProps } from 'next'
export const getServerSideProps: GetServerSideProps = async (ctx) => {
// Method to source urls from cms
// const urls = await fetch('https//example.com/api')
const fields = [
{
loc: 'https://example.com', // Absolute url
lastmod: new Date().toISOString(),
// changefreq
// priority
},
{
loc: 'https://example.com/dynamic-path-2', // Absolute url
lastmod: new Date().toISOString(),
// changefreq
// priority
},
]
return getServerSideSitemapLegacy(ctx, fields)
}
// Default export to prevent next.js errors
export default function Sitemap() {}
Now, next.js
is serving the dynamic sitemap from http://localhost:3000/server-sitemap.xml
.
List the dynamic sitemap page in robotsTxtOptions.additionalSitemaps
and exclude this path from static sitemap list.
// next-sitemap.config.js
/** @type {import('next-sitemap').IConfig} */
module.exports = {
siteUrl: 'https://example.com',
generateRobotsTxt: true,
exclude: ['/server-sitemap.xml'], // <= exclude here
robotsTxtOptions: {
additionalSitemaps: [
'https://example.com/server-sitemap.xml', // <==== Add here
],
},
}
In this way, next-sitemap
will manage the sitemaps for all your static pages and your dynamic sitemap will be listed on robots.txt.
Add the following line of code in your next-sitemap.config.js
for nice typescript autocomplete! š
/** @type {import('next-sitemap').IConfig} */
module.exports = {
// YOUR CONFIG
}
All PRs are welcome :)
FAQs
Sitemap generator for next.js
The npm package next-sitemap receives a total of 284,262 weekly downloads. As such, next-sitemap popularity was classified as popular.
We found that next-sitemap demonstrated a not healthy version release cadence and project activity because the last version was released a year ago.Ā It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Bun 1.2 enhances its JavaScript runtime with 90% Node.js compatibility, built-in S3 and Postgres support, HTML Imports, and faster, cloud-first performance.
Security News
Biden's executive order pushes for AI-driven cybersecurity, software supply chain transparency, and stronger protections for federal and open source systems.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.