Sitecore Headless Media URLs with Next.js

Something to be aware of when looking to modify the URLs of media items coming from a GraphQL query - by default, all of the media URLs come back as an absolute URL, including the hostname. For XM Cloud, this is necessary as the URL to the image is coming from the Sitecore CDN, so it’ll return a specific hostname for this.

The configuration for this is a property called IncludeServerUrlInMediaUrls that is set to true by default located here:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <sitecore>
    <layoutService>
      <configurations>
        <config name="sxa-jss">
          <rendering type="Sitecore.LayoutService.Configuration.DefaultRenderingConfiguration, Sitecore.LayoutService">
            <renderingContentsResolver type="Sitecore.XA.JSS.Foundation.Presentation.ContentsResolvers.RenderingContentsResolver, Sitecore.XA.JSS.Foundation.Presentation">
              <IncludeServerUrlInMediaUrls>true</IncludeServerUrlInMediaUrls>
            </renderingContentsResolver>
          </rendering>
        </config>
      </configurations>
    </layoutService>
  </sitecore>
</configuration>

Now, generally this is not an issue, however, the Sitecore Next.js starter kit comes with the following rewrites() configuration in next.config.js:

async rewrites() {
    // When in connected mode we want to proxy Sitecore paths off to Sitecore
    return [
      // API endpoints
      {
        source: '/sitecore/api/:path*',
        destination: `${jssConfig.sitecoreApiHost}/sitecore/api/:path*`,
      },
      // media items
      {
        source: '/-/:path*',
        destination: `${jssConfig.sitecoreApiHost}/-/:path*`,
      },
      // healthz check
      {
        source: '/healthz',
        destination: '/api/healthz',
      },
      // rewrite for Sitecore service pages
      {
        source: '/sitecore/service/:path*',
        destination: `${jssConfig.sitecoreApiHost}/sitecore/service/:path*`,
      },
    ];
  },

Note the “media items” section where it tries to rewrite media items to proxy out to the Sitecore server rather than the head server by appending the hostname. This doesn’t actually work because the incoming URL is an absolute URL rather than a relative one, so the Next rewrite module never picks it up. For XM Cloud, again, less of an issue as it should be coming from the Sitecore CDN. For XP/XM instances however, you may want to proxy out to your own CDN or to your CM or CD server, or if you have multiple environments, to point to the correct environment.

You’ve got 2 options here:

  1. Set the IncludeServerUrlInMediaUrls to be false to return media URLs as relative URLs. This will enable the default Next redirect module to start working and you may need to update to point to where you need it to.
  2. Use the Media.MediaLinkServerUrl property to change your media hostname to what you need, but note you’d have to patch this for each environment on the Sitecore side.

Both are viable, but I chose the first so I didn’t have to patch each environment separately and controlled it with environment variables on the head app. Also, as we migrate to XM Cloud, everything will still work as the redirect will just no longer trigger anymore.