Generate dynamic sitemap.xml
for Next.js projects following the example of Google!
nextjs.config.js
Checkout the examples folder for source code.
Open a Terminal in the project root and run:
npm install @sergeymyssak/nextjs-sitemap
or
yarn add @sergeymyssak/nextjs-sitemap
Example src
folder:
└── src
└── pages
├── projects
│ ├── computers
│ │ ├── laptop.js
│ │ └── pc.js
│ └── phones
│ ├── android.js
│ └── ios.js
├── admin
│ ├── account.js
│ └── cms.js
└── index.js
All static routes from pages
folder will be automatically added to the sitemap.
// import { configureSitemap } from '@sergeymyssak/nextjs-sitemap';
const { configureSitemap } = require('@sergeymyssak/nextjs-sitemap');
const Sitemap = configureSitemap({
domains: [{ domain: 'example.com', defaultLocale: 'en', http: true }],
exclude: ['/admin/*'],
excludeIndex: true,
pagesConfig: {
'/projects/*': {
priority: '0.5',
changefreq: 'daily',
},
},
trailingSlash: true,
targetDirectory: __dirname + '/public',
pagesDirectory: __dirname + '/src/pages',
});
Sitemap.generateSitemap();
sitemap.xml
```xml
If you specify nextConfigPath
prop, then all values indicated in the exportPathMap will be automatically added (pages
folder will be ignored).
// import { configureSitemap } from '@sergeymyssak/nextjs-sitemap';
const { configureSitemap } = require('@sergeymyssak/nextjs-sitemap');
const Sitemap = configureSitemap({
exclude: ['/admin'],
excludeIndex: true,
pagesConfig: {
'/p/*': {
priority: '0.5',
changefreq: 'daily',
},
},
nextConfigPath: __dirname + '/next.config.js',
targetDirectory: __dirname + '/public',
pagesDirectory: __dirname + '/src/pages',
});
Sitemap.generateSitemap();
exportPathMap
in next.config.js
```js module.exports = { i18n: { domains: [ { domain: 'example.com', defaultLocale: 'en', locales: ['en-US', 'en-CA'], }, ], }, trailingSlash: true, exportPathMap: async function () { return { '/': { page: '/' }, '/admin': { page: '/admin' }, '/p/learn-nextjs': { page: '/post', query: { title: 'learn-nextjs' } }, }; }, }; ```
sitemap.xml
```xml
For dynamic routes, you have to declare them with the include
property.
Example src
folder:
└── src
└── pages
├── project
│ └── [id].js
└── index.js
// import { configureSitemap } from '@sergeymyssak/nextjs-sitemap';
const { configureSitemap } = require('@sergeymyssak/nextjs-sitemap');
async function fetchDynamicPaths() {
return ['house', 'flower', 'table'];
}
async function getDynamicPaths() {
const paths = await fetchDynamicPaths();
return paths.map((item) => `/project/${item}`);
}
getDynamicPaths().then((paths) => {
const Sitemap = configureSitemap({
domains: [{ domain: 'example.com', defaultLocale: 'en' }],
include: paths,
exclude: ['/project/*'],
excludeIndex: true,
pagesConfig: {
'/project/*': {
priority: '0.5',
changefreq: 'daily',
},
},
trailingSlash: true,
targetDirectory: __dirname + '/public',
pagesDirectory: __dirname + '/src/pages',
});
Sitemap.generateSitemap();
});
sitemap.xml
```xml
If you have localization, you can use locales
in domains
prop.
// import { configureSitemap } from '@sergeymyssak/nextjs-sitemap';
const { configureSitemap } = require('@sergeymyssak/nextjs-sitemap');
const Sitemap = configureSitemap({
domains: [{ domain: 'example.com', locales: ['en', 'es'] }],
excludeIndex: true,
trailingSlash: true,
targetDirectory: __dirname + '/public',
pagesDirectory: __dirname + '/src/pages',
});
Sitemap.generateSitemap();
sitemap.xml
```xml
If the number of urls is more than 50000, then several sitemaps will be automatically created. You can customize the number of urls using sitemapSize
// import { configureSitemap } from '@sergeymyssak/nextjs-sitemap';
const { configureSitemap } = require('@sergeymyssak/nextjs-sitemap');
const Sitemap = configureSitemap({
sitemapUrl: 'https://www.example.com',
sitemapSize: 5000,
pagesConfig: {
'/p/*': {
priority: '0.5',
changefreq: 'daily',
},
},
nextConfigPath: __dirname + '/next.config.js',
targetDirectory: __dirname + '/public',
pagesDirectory: __dirname + '/src/pages',
});
Sitemap.generateSitemap();
public
directory``` └── src └── public ├── sitemap.xml ├── sitemap1.xml ├── sitemap2.xml └── sitemap3.xml ```
generateSitemap
: () => Promise<ISitemapWriterResultItem[]>
;Generate sitemap
ISitemapWriterResultItem {
name: string; // sitemap file name
count: number; // number of urls
}
regenerateSitemapIndex
: (sitemapsNames: string[]) => void
;When there are multiple sitemaps, a sitemap index
is generated. If we somehow changed our sitemaps externally, then you can use this function to update sitemap index
domains
(optional
): IDomain[]
Domain list - same as in next.config.js.
IDomain {
domain: string; // domain name
defaultLocale?: string; // non-routing language
locales?: string[]; // routing languages
http?: boolean; // http or https
}
exclude
(optional
): string[]
The exclude parameter is an array of glob patterns to exclude static routes / folders from the generated sitemap.
excludeExtensions
(optional
): string[]
Ignore files by extension.
Example:
// import { configureSitemap } from '@sergeymyssak/nextjs-sitemap';
const { configureSitemap } = require('@sergeymyssak/nextjs-sitemap');
const Sitemap = configureSitemap({
// ...
excludeExtensions: ['.ts'],
// ...
});
Sitemap.generateSitemap();
excludeIndex
(optional
): boolean
Remove index
from URL, directory will be ending with the slash. Defaults to true
.
include
(optional
): string[]
Array of extra paths to include in the sitemap. If you want to add any route with dynamic parameters, you have to set an array of dynamic routes.
Example:
// import { configureSitemap } from '@sergeymyssak/nextjs-sitemap';
const { configureSitemap } = require('@sergeymyssak/nextjs-sitemap');
const Sitemap = configureSitemap({
// ...
include: ['/project/1', '/project/2'],
exclude: ['/project/[id]'], // or exclude: ['/project/*']
// ...
});
Sitemap.generateSitemap();
trailingSlash
(optional
): boolean
Add trailing slashes. Defaults to false
.
nextConfigPath
(optional
): string
Use exportPathMap
from next.config.js
file.
pagesConfig
(optional
): IPagesConfig[]
Object configuration of priority and changefreq per route / folder.
IPagesConfig {
[key: string]: {
priority: string,
changefreq: string
}
}
Example:
// import { configureSitemap } from '@sergeymyssak/nextjs-sitemap';
const { configureSitemap } = require('@sergeymyssak/nextjs-sitemap');
const Sitemap = configureSitemap({
// ...
pagesConfig: {
'/about': {
priority: '0.5',
changefreq: 'daily',
},
'/project/*': {
priority: '0.9',
changefreq: 'daily',
},
},
// ...
});
Sitemap.generateSitemap();
pagesDirectory
(required
): string
The directory where there are Next.js pages.
targetDirectory
(required
): string
The path to the public folder.
sitemapUrl
(optional
): string
The url which will be specified in the sitemap index
file.
sitemapSize
(optional
): number
Maximum number of url
in one sitemap file. Defaults to 50000
.
sitemapStylesheet
(optional
): ISitemapStylesheet[]
Array of style objects that will be applied to sitemap.
ISitemapStylesheet {
type: string;
styleFile: string;
}
Example:
// import { configureSitemap } from '@sergeymyssak/nextjs-sitemap';
const { configureSitemap } = require('@sergeymyssak/nextjs-sitemap');
const Sitemap = configureSitemap({
// ...
sitemapStylesheet: [
{
type: "text/css",
styleFile: "styles/styles.css"
},
{
type: "text/xsl",
styleFile: "styles/styles.xls"
}
],
// ...
});
Sitemap.generateSitemap();
The value of the hreflang attribute identifies the language (in ISO 639-1 format) and optionally a region (in ISO 3166-1 Alpha 2 format) of an alternate URL.
You can gzip your sitemap.xml
. The .gz extension just means that it's been compressed (using gzip compression), so that it's smaller and served faster. Most search engine bots can read gzip'd compressed content.
sitemap.xml.gz
```js // import zlib from 'zlib'; // import fs from 'fs'; // import { configureSitemap } from '@sergeymyssak/nextjs-sitemap'; const zlib = require('zlib'); const fs = require('fs'); const { configureSitemap } = require('@sergeymyssak/nextjs-sitemap'); async function getDynamicPaths() { const data = ['house', 'flower', 'table']; return data.map((item) => `/project/${item}`); } getDynamicPaths().then((paths) => { const Sitemap = configureSitemap({ domains: [{ domain: 'example.com', defaultLocale: 'en' }], include: paths, exclude: ['/project/*'], excludeIndex: true, pagesConfig: { '/project/*': { priority: '0.5', changefreq: 'daily', }, }, trailingSlash: true, targetDirectory: __dirname + '/public', pagesDirectory: __dirname + '/src/pages', }); Sitemap.generateSitemap().then(() => { const inp = fs.createReadStream('public/sitemap.xml'); const out = fs.createWriteStream('public/sitemap.xml.gz'); const gzip = zlib.createGzip(); inp.pipe(gzip).pipe(out); fs.unlink('public/sitemap.xml', () => console.log('Sitemap.xml has been deleted!'), ); console.log('Sitemap.xml.gz has been created!'); }); }); ```