Generate a sitemap for Sitecore Headless Next.js app


A Sitemap is an important part of SEO for any public-facing website. This is a list of URLs you want to crawl by the google bots for indexing.

NextJS makes it easy for us to achieve this. So let’s see how to add a sitemap to your NextJS project.

What is an XML Sitemap?

An XML sitemap or simply sitemap.xml is a file that lists all the important URLs or pages so that search engines can easily crawl them.

When we go for /sitemap.xml path in any websites which implemented the Sitemap, we could see an XML file as the result included with all the links in that website. 

How to Add an XML Sitemap in a Next.js App?

Assumption - You have set up your project using the Sitecore Containers template for Next.js. If not please refer this link.

Install the Next-Sitemap package

We are going to use a package next-sitemap for generating the sitemap in our Next.js app. The following command will install the package inside our Next.js app.

npm i next-sitemap

Add the next-sitemap config file

In the root directory of our folder, create a file next-sitemap.config.js to configure our sitemap. Here we can exclude to paths from the sitemap which are not required to be indexed. For example - the 404 page.

The next-sitemap package also creates a robot.txt file and we can also add paths to be in that file.

We can also add additional sitemaps that will also be included in the main sitemap.xml file.

Note that the will add the .env.local file later where we get our site domain URL using process.env. NEXT_PUBLIC_DOMAIN_URL.
const siteUrl = process.env.NEXT_PUBLIC_DOMAIN_URL;
module.exports = {
  siteUrl,
  exclude: ["/404"],
  generateRobotsTxt: true,
  robotsTxtOptions: {
    policies: [
      {
        userAgent: "*",
        disallow: ["/404"],
      },
      { userAgent: "*", allow: "/" },
    ],
    additionalSitemaps: [
      `${siteUrl}sitemap.xml`,
      `${siteUrl}server-sitemap.xml`,
    ],
  },
};

Create sitemap.xml inside the pages directory

Now let’s create a file index.tsx inside the pages/sitemap.xml directory. All the dynamic paths are added to the sitemap from here.


Now write this code in index.tsx file to fetch all the pages details respective to your Sitecore Site context using sitemapFetcher.fetch() method.
import { GetServerSideProps } from 'next';
import { getServerSideSitemap, ISitemapField } from 'next-sitemap';
import { sitemapFetcher } from 'lib/sitemap-fetcher';
import { getSitesPaths } from 'lib/multisite/sites';
import Site from 'lib/type/Site';
import { sitecorePagePropsFactory } from 'lib/page-props-factory';

export const getServerSideProps: GetServerSideProps = async (ctx) => {
  console.log('inside getServerSideProps');

  const sitecorePageLayoutData = await sitecorePagePropsFactory.create(ctx);

  const contextSite = sitecorePageLayoutData.layoutData.sitecore.context.site?.name;
  const contextLanguage = sitecorePageLayoutData.layoutData.sitecore.context.language ?? 'en';

  console.log('context.site' + contextSite);
  console.log('context.language ' + contextLanguage);

  const sitesData = {
    site: contextSite,
    languages: [contextLanguage],
  };

  const sites = (await getSitesPaths()) as unknown as Site[];

  const filteredSites = sites.filter((site: Site) => {
    return site.site === sitesData.site && site.languages.includes(sitesData?.languages[0]);
  });

  const pages = await sitemapFetcher.fetch(filteredSites, ctx);
  const paths = pages.map((page) => ({
    params: { site: page.params.site, path: page.params.path },
    locale: page.locale,
  }));

  const fields: ISitemapField[] = paths.map((sitecorepage) => ({
    loc: `${process.env.NEXT_PUBLIC_DOMAIN_URL}${sitecorepage?.params.path.join('/')}`,
    changefreq: 'weekly',
    priority: 1.0,
    lastmod: new Date().toISOString(),
  }));

  return getServerSideSitemap(ctx, fields);
};

const DynamicSiteMap = (): void => {
  console.log('inside DynamicSiteMap');
};

export default DynamicSiteMap;

Add a .env.local file

Now add an env file .env.local where it contains the value NEXT_PUBLIC_DOMAIN_URL which is used in our app.

That's it! 

Now run your Next JS app and hit the sitemap url probably -  http://localhost:3000/sitemap.xml you shoud see the result something like this.

Comments

Popular posts from this blog

Setup Sitecore XM Cloud Dev Environment using Docker

Sitecore Content Hub - Triggers, Actions and Scripts

All Blog Posts - 2023