Running custom next.js editing host in Sitecore XM Cloud

Artsem Prashkovich on September 29, 2022

In Sitecore, we have a separation between rendering and editing hosts. Where:

  • The rendering host - is the front-end application that is used for displaying the website to your audience. You host the application on platforms such as Vercel, Netlify, or even on your own Node.js server. This application is set up and scaled to serve live traffic. 
  • The editing host -  serves the purpose of editing experiences inside the XM Cloud instance and is not set up or scaled for serving live traffic.

Rendering host runs on third-party services - it is more or less clear because we follow the instructions and documentation of the service. But in the case of the editing host - it is a kind of black box. The editing host app runs inside XM Cloud and a build and execution process is not so obvious. 

Sitecore provides the XM Cloud Starter Kit (Next JS) and pretty well describes the process of creating our own project based on this starter kit. But what if we want to deploy and run our existing rendering host application as an editing host? It is surely possible but has a few peculiarities:

  • Version of Sitecore JavaScript Rendering SDKs (JSS) should be 19.0.0 or newer
  • It should be a JSS, node.js-based application
  • Your application should not depend on any custom environment variables because the environment variables for Editing Host cannot be set in the environment variables UI
  • Your application should support the Experience Editor and built in accordance with all best practices of it.

If our app matches all points above, you can run your app as an editing host within XM Cloud. 

First of all, we need to make sure that we have xmcloud.build.json in the root of our solution. This article describes which parameters we have in the configuration. You should have it if you already deploy your backend part into the XM Cloud. If not, create it manually with the following content:

{
    "deployItems": {
        "modules": [
            "Foundation.*",
            "Feature.*",
            "project.*"
        ]
    },
    "buildTargets": [
      "./DemoCloud.sln"
    ],
    "renderingHosts": {
        "global": {
            "path": "./src/Project/Demo/nextjs",
            "nodeVersion": "14.15.3",
            "jssDeploymentSecret":"dd5d764c4776459e92e1233b8cde0ab5",
            "enabled": true,
            "type": "sxa"
        }
    }
}

 

In this article we are interested only in renderingHosts properties, where the most important of them are:

  • global - is a jss app name,
  • Path - The relative path from the xmcloud.build.json file to the app source code. Usually, it is the relative path from the root folder,
  • nodeVersion - Specific Node.js version for rendering host
  • Type - type of rendering host. Allowed values: "jss" or "sxa"

 Once you are done with the deployment, you should see the following item created under the /sitecore/system/Settings/Services/Rendering Hosts/ :

Sitecore SXA Site Settings Predefined application rendering host

 

If you use the latest versions if JSS and SXA, you should have the Predefined application rendering host field for the SXA site definition where you have to select a proper rendering host:

Sitecore SXA Site Settings

 

If you don’t have the field above, but still use SXA, you should copy values from /sitecore/system/Settings/Services/Rendering Hosts/global to your Site settings:

Sitecore SXA General Site Settings

 

And finally, if you don’t use SXA at all, you should make sure your app config looks like below:

<?xml version="1.0"?>

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"
              xmlns:set="http://www.sitecore.net/xmlconfig/set/">
  <sitecore>
    <sites>
      <!--
        JSS Site Registration
        This configures the site with Sitecore - i.e. host headers, item paths.
        If your JSS app lives within an existing Sitecore site, this may not be necessary.
      -->
      <site name="global"
            inherits="website"
            hostName="$(env:host)"
            rootPath="/sitecore/content/Global"
            patch:before="site[@name='website']" />
    </sites>
    <javaScriptServices>
      <apps>
        <!--
          JSS App Registration
          The JSS app needs to be registered in order to support layout service and import services.

          There are many available attributes, and they inherit the defaults if not explicitly specified here.
          Defaults are defined in `/App_Config/Sitecore/JavaScriptServices/Sitecore.JavaScriptServices.Apps.config`

          NOTE: graphQLEndpoint enables _Integrated GraphQL_. If not using integrated GraphQL, it can be removed.

          NOTE: This app configuration assumes a Sitecore-first approach and thus disables the JSS Workflow for
          initial app import, and does not protect imported items.
        -->
        <app name="global"
            sitecorePath="/sitecore/content/Global"
            graphQLEndpoint="/sitecore/api/graph/edge"
            serverSideRenderingEngine="http"
            serverSideRenderingEngineEndpointUrl=

"$(env:RENDERING_HOST_INTERNAL_URI_global)/api/editing/render"
            serverSideRenderingEngineApplicationUrl=

"http://$(env:SITECORE_EDITING_HOST_PUBLIC_HOST_global)"
            useLanguageSpecificLayout="true"
            defaultWorkflow=""
            protectDeveloperItems="false"
            deploymentSecret="$(env:JSS_DEPLOYMENT_SECRET_global)"
            debugSecurity="false"
            inherits="defaults" />
      </apps>   
    </javaScriptServices>
  </sitecore>
</configuration>

 

Or you can replace values for serverSideRenderingEngineEndpointUrl and serverSideRenderingEngineApplicationUrl with values from the /sitecore/system/Settings/Services/Rendering Hosts/global item.

One more important thing related to the JSS_EDITING_SECRET. In NON XM Cloud project, we usually secure the Sitecore editor endpoint using a Sitecore configuration patch with the following setting:

 <setting name="JavaScriptServices.ViewEngine.Http.JssEditingSecret" value="<YOUR_SECRET_TOKEN>" />

 

In XM Cloud this setting is patched from the Sitecore.JavaScriptServices.ViewEngine.Http.config:

<setting name="JavaScriptServices.ViewEngine.Http.JssEditingSecret" value="some value" patch:source="Sitecore.JavaScriptServices.ViewEngine.Http.config"/> 

 

If you override this setting, your editing host app will not work. So, you have to remove your patch if you have one.