Skip to content

Latest commit

 

History

History
181 lines (146 loc) · 5.94 KB

generate-dynamic-sitemap.mdx

File metadata and controls

181 lines (146 loc) · 5.94 KB
title description author publishedAt updatedAt tags logoImage
Generate A Dynamic Sitemap In Next.js Website
Learn how to create a dynamic sitemap for a react and Next.js website using fs, globby, and prettier.
benjamin-carlson.mdx
2021-09-27T21:30:00
2021-12-23T14:50
nextjs
javascript
seo
nextjs-light.png

Update December 2021:

This article is still up to date and works, however a much, much easier way to add a dynamic sitemap in Next.js is using the next-sitemap package. This website now uses next-sitemap! As you can see it is super easy to set up.

Introduction

A sitemap is how you tell Google what pages are in your website. This helps them get ranked higher. Take a look at the performance chart of this website.

Performance click chart in Google Search Console for coffeeclass.io

I added the sitemap on 7/20/21 and you can see the clicks spiked right after.

In this snippet, we'll write code to generate a dynamic sitemap for a React (specifically Next.js) based website.

First, install these 3 dependencies:

yarn add fs globby prettier

We will be using fs to write to our file system, globby to read and sort the files, and prettier to format our outputted sitemap.xml.

Create a file named generate-sitemap.js. Inside of here, require all 3 of the packages we just imported.

const fs = require('fs');
const globby = require('globby');
const prettier = require('prettier');

Next, define our async function.

(async () => {
	// we'll add code in here!
})();

We'll initialize our prettier variable named prettierConfig and use globby to find files and directories using glob patterns. In this example, I have js pages inside of a pages folder and mdx files inside of a content folder. We can also exclude routes using !.

(async () => {
	const prettierConfig = await prettier.resolveConfig('./.prettierrc.js');
    const pages = await globby([
        'pages/*.js',
        'content/**/*.mdx',
        '!pages/_*.js',
        '!pages/api'
    ]);
})();

Declare a variable sitemap which will be our sitemap content. Go ahead and add any urls that were not able to be fetched with globby. Below that, map over the pages variable, remove the extensions, and add them to the sitemap.

(async () => {
	const prettierConfig = await prettier.resolveConfig('./.prettierrc.js');
    const pages = await globby([
        'pages/*.js',
        'content/**/*.mdx',
        '!pages/_*.js',
        '!pages/api'
    ]);

const sitemap = `
        <?xml version="1.0" encoding="UTF-8"?>
        <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
            <!--Base URL-->
            <url>
                <loc>https://www.example.com</loc>
            </url>
					${pages
            .map((page) => {
                const path = page
                    .replace('pages', '')
                    .replace('content', '')
                    .replace('.js', '')
                    .replace('.mdx', '');
                const route = path === '/index' ? '' : path;
                if (path === '/404') {
                    return;
                }
                return `
                        <url>
                            <loc>${`https://www.example.com${route}`}</loc>
                        </url>
                    `;
            })
            .join('')}
        </urlset>
    `;
})();

Finally, format the sitemap using prettier and write the sitemap to our public directory using fs.

const formatted = prettier.format(sitemap, {
        ...prettierConfig,
        parser: 'html'
    });

    // eslint-disable-next-line no-sync
    fs.writeFileSync('public/sitemap.xml', formatted);

Your sitemap is now available on the route /sitemap.xml!

Full Code

(async () => {
	const prettierConfig = await prettier.resolveConfig('./.prettierrc.js');
    const pages = await globby([
        'pages/*.js',
        'content/**/*.mdx',
        '!pages/_*.js',
        '!pages/api'
    ]);

const sitemap = `
        <?xml version="1.0" encoding="UTF-8"?>
        <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
            <!--Base URL-->
            <url>
                <loc>https://www.example.com</loc>
            </url>
					${pages
            .map((page) => {
                const path = page
                    .replace('pages', '')
                    .replace('content', '')
                    .replace('.js', '')
                    .replace('.mdx', '');
                const route = path === '/index' ? '' : path;
                if (path === '/404') {
                    return;
                }
                return `
                        <url>
                            <loc>${`https://www.example.com${route}`}</loc>
                        </url>
                    `;
            })
            .join('')}
        </urlset>
    `;

    const formatted = prettier.format(sitemap, {
        ...prettierConfig,
        parser: 'html'
    });

    // eslint-disable-next-line no-sync
    fs.writeFileSync('public/sitemap.xml', formatted);
})();

Google Search Console

The last thing you want to do is tell google where to find your sitemap. Navigate to Google Search Console and in the left pannel, click on the "Sitemaps" tab. In the "Add a new sitemap" input box, enter the url to your sitemap. When Google processes it, you should see a success status in the table!