Insights

Sitecore XM Cloud Redirects: Page-Level, Dynamic & Out of the Box Redirects

A deep dive on redirect solutions for Sitecore XM Cloud

The Importance of Redirects

Migrating to XM Cloud, we’ll be creating new sites with new pages and new URLs.

In Sitecore XM / XP redirects were handled in Sitecore’s Http request pipelines, a web.config file (ugh) or at an infrastructure point in-front of Sitecore. Now where and how we deal with redirects are quite different. We’ll look at a few ways:

  • Redirects set in existing page items and content items (custom code)
  • Next.js configured dynamic redirects & mass redirects (configuration)
  • SXA-based redirects in XM Cloud (content)

Redirects From Existing Sitecore Page Items

This is the classic scenario. A content author can add a redirect item in the tree or use fields in existing page items to have them behave as a redirect. This is used when a page has been moved or deleted but we still want the previous URL to still work.

Redirect Fields in the Sitecore Item

Below is a screenshot of the fields being referenced in this example.

Interface showing detailed settings for redirect mappings in a content management system, including fields for old and new URL paths with options for regular expressions and query string preservation.

This is a custom solution but fields like these are typically used in any redirect solution.

The Code to Redirect From Sitecore Item

We will need to customize the /src/pages/[[...path]].tsx file to implement this redirect solution.

Scroll down to you getStaticProps function. Here is a sample of the code.

export const getStaticProps: GetStaticProps = async (context) => {
  const props = await sitecorePagePropsFactory.create(context);

  // Free code starts here (DC)
  const redirectItem: PageRedirect = props.layoutData?.sitecore?.route;

  // Simplify redirect condition checks
  const isRedirectEnabled = redirectItem?.fields?.['Redirect Enabled']?.value;
  const redirectUrl = redirectItem?.fields?.['Redirect Url']?.value?.href;

  // Proceed with redirect if enabled and URL is available
  if (isRedirectEnabled && redirectUrl) {
    return {
      redirect: {
        destination: redirectUrl,
        // Ensure boolean for permanent redirect, default to false if not specified
        permanent: redirectItem?.fields?.['Permanent Redirect']?.value,
      },
      props: {},
    };
  }
  // Free code ends here (DC)

  // Rest of the pre-existing function code goes here
  return {...};
}

type PageRedirect = null | {
  fields?: {
    'Redirect Enabled'?: {
      value: boolean;
    };
    'Redirect Url'?: {
      value: {
        href: string;
      };
    };
    'Permanent Redirect'?: {
      value: boolean;
    };
  };
};

Let’s break down these changes

  • We return the existing route which contains page-level fields into a PageRedirect object
  • Check the object for the required values
  • If our item has the required fields, we return a redirect object for Next.js to process

If you’re curious about this approach, please look into the getStaticProps documentation and see what else you can do.

Dynamic Redirects in XM Cloud Using Next.js

To configure dynamic redirects, find your next.config.js file. In my file I have a nextConfig object that is exported. We need to find (or newly define) a redirects function.


const nextConfig = {
  // other stuff
  async redirect() { return []; } // <- this guy
  // other stuff
};

Now that we’re oriented here is a working sample of a dynamic redirect.


const nextConfig = {
  // other stuff
  async redirects() {
    return [
      {
        source: '/blog/:slug',
        destination: '/insights/:slug', // Matched parameters can be used in the destination
        permanent: true,
      },
      {
        source: '/page-a',
        destination: '/new-page-a', // Matched parameters can be used in the destination
        permanent: true,
      },
      {
        source: '/page-b',
        destination: '/new-page-b', // Matched parameters can be used in the destination
        permanent: true,
      },

    ]
  },
  // other stuff
};

You can find further documentation on redirects to see everything you can do. There are some very advanced features that you can leverage.

Mass Redirects

If you have a large number of redirects this is the best place in the XM Cloud stack to define them. Create a JSON file, import it into next.config.js and add them to the array.

Redirects Managed in XM Cloud

Under your site in XM Cloud you can insert a Redirect Map item underneath the {Site}/Settings/Redirects item. See a screen below of what this looks like.

Screenshot of a CMS interface showing redirection settings with options for enabling redirects, choosing between permanent and temporary redirects, and specifying redirect URLs.

This gives you with the ability to:

  • Set the type of redirect (301 vs 302)
  • Preserve the query string
  • Add any amount of URL paths in a key-value structure for direction
  • You can organize your redirects into logical groups by item for easy management.

Sitecore’s code that runs the redirect can be found on Github and is definitely worth looking at when you’re trying to understand how it works. Let’s take a peek at the all important getExistsRedirect function (as written at the time of this article):

  private async getExistsRedirect(
    req: NextRequest,
    siteName: string
  ): Promise<RedirectInfo | undefined> {
    const redirects = await this.redirectsService.fetchRedirects(siteName);

    return redirects.length
      ? redirects.find((redirect: RedirectInfo) => {
          const pattern = `/^/${redirect.pattern
            .toLowerCase()
            .replace(/^\/|\/$/g, '')
            .replace(/^\^|\$$/g, '')}$/`;

          return (
            (regexParser(pattern).test(req.nextUrl.pathname.toLowerCase()) ||
              regexParser(pattern).test(
                `/${req.nextUrl.locale}${req.nextUrl.pathname}`.toLowerCase()
              )) &&
            (redirect.locale
              ? redirect.locale.toLowerCase() === req.nextUrl.locale.toLowerCase()
              : true)
          );
        })
      : undefined;
  }

While it says it supports regular expressions it makes a few modifications to the redirect pattern of the source in Sitecore:

  • Removes leading and trailing slashes from the source
  • Remove leading ^ and trailing $ if they exist
  • Encapsulate the pattern within /^...$/, turning it into a regular expression string that matches the entire value

A few other things are happening as well:

  • It does a GraphQL call to fetch about redirects for your site
  • Evaluates only the path for the request against the source pattern URL
  • It matches the incoming path against the source pattern with and without the locale

One last note - and this may have changed - but redirects set in XM Cloud are only checked if the URL in the request is not found. So if you have a redirect for /blog but also have an item published for /blog the redirect will not fire.

Final Word on Redirects

Thanks for reading. A lot has changed in handling redirects from MVC Sitecore XP to XM Cloud. Hopefully this post has given you an idea of the different approaches available. These approaches will also work on Sitecore Headless (SXA + JSS) if you’re not using XM Cloud.

Thanks for reading.



Meet Dan Cruickshank

President | Sitecore MVP x 11

Dan is the founder of Fishtank. He's a multi-time Sitecore MVP and Coveo MVP award winner. Outside of technology, he is widely considered to be a top 3 father (routinely receiving "Father of the Year" accolades from his family) and past his prime on the basketball court.

Connect with Dan