Leading digital experience platform Sitecore offers strong capabilities for developing reliable websites and applications. The headless CMS and Jamstack architecture trends have been very popular in recent years. Sitecore provides Headless SXA (Sitecore Experience Accelerator) as a solution to decouple the front-end presentation layer from the content management capabilities since it recognizes the value of headless capabilities.
In this article, we will guide you through the process of configuring a Sitecore Next.js multisite app and integrating it with Headless SXA in a Sitecore container. This setup allows you to leverage the benefits of Next.js, a popular React framework for server-side rendering, and the flexibility of Headless SXA for managing and delivering content.
Before we begin, make sure you have a basic understanding of Sitecore, Next.js, and Docker. Let's dive in!
In this article, we will guide you through the process of configuring a Sitecore Next.js multisite app and integrating it with Headless SXA in a Sitecore container. This setup allows you to leverage the benefits of Next.js, a popular React framework for server-side rendering, and the flexibility of Headless SXA for managing and delivering content.
Table of Contents
- Step 1: Set Up the Sitecore Container
- Step 2: Add support for Sitecore SXA in Sitecore Headless Container setup
- Step 3: Add support for Sitecore Next.js multisite add-on
- Step 4: Setup security for your Sitecore Layout Service
- Step 5: Set up the editing host for Sitecore Headless SXA Multisite
- Step 6: Set the Application Name in the Sitecore Headless SXA Multisite setup
- Step 7: Set values of the Sitecore Headless SXA Site Grouping and Site Definition Item
- Step 8: Sitecore JSS Headless SXA Next.js App Setup
- Step 9: Set DeploymentSecret for the Sitecore Headless SXA Site Grouping Item
- Step 10: Set Jss Editing Secret for the Sitecore Headless SXA Site
- Step 11: Update the Sitecore Layout Service configuration for the Sitecore JSS Headless SXA
- Step 12: Set dictionary data source for the Sitecore JSS GraphQL Dictionary Service
Before we begin, make sure you have a basic understanding of Sitecore, Next.js, and Docker. Let's dive in!
The first step is to set up a Sitecore container using Docker. You can follow the official Sitecore Docker documentation Walkthrough: Setting up a development environment with the Sitecore Containers template for Next.js to create a Sitecore latest version container setup with Next.js app with the desired Sitecore modules installed like Sitecore Management Services, Sitecore Headless Services, Sitecore Content Serialization etc..
You need to have the following software applications installed on your computer before you can install the template and build a full-stack solution for Sitecore and JSS for Next.js:
And select the following options during the execution of above command:
Once, command execution is successful you will get the following prompt:
If you open the code base folder, then you will find required setup to start with Sitecore Headless Services: The above Sitecore Containers setup for Next.js not have the Sitecore SXA module and Sitecore Next.js Multisite add-on to support the Sitecore Headless SXA.
You need to have the following software applications installed on your computer before you can install the template and build a full-stack solution for Sitecore and JSS for Next.js:
- A valid Sitecore license file.
- Windows PowerShell 5.1. PowerShell 7 is not supported at this time.
- The current long-term support (LTS) version of Node.js.
- .NET Core 3.1 SDK (check your installed version with the dotnet --version command).
- .NET Framework 4.8 SDK (see the Microsoft procedure for checking .NET Framework versions).
- Visual Studio 2019.
- Docker for Windows, with Windows Containers enabled.
- Any required components for using Sitecore Containers.
dotnet new sitecore.nextjs.gettingstarted -n MyProject
And select the following options during the execution of above command:
Template is configured to run the following action: Description: Restores dotnet local tools for the solution. Actual command: dotnet tool restore Do you want to run this action [Y(yes)|N(no)]? y Running command 'dotnet tool restore'... Command succeeded. Template is configured to run the following action: Description: Initializes the JSS project. Actual command: powershell -File create-jss-project.ps1 Do you want to run this action [Y(yes)|N(no)]? y Running command 'powershell -File create-jss-project.ps1'... Adding JSS sample to solution via 'npx create-sitecore-jss... Creating JSS Project for myproject ? Would you like to use the pre-push hook for linting check? Yes Initializing 'nextjs'... ? What is your Sitecore hostname (used if deployed to Sitecore)? myproject.dev.local ? How would you like to fetch Layout and Dictionary data? GraphQL ? How would you like to prerender your application? SSG Initializing 'nextjs-styleguide'... ? Which additional language do you want to support (en is already included and required)? da-DK Installing packages... > npm install
Once, command execution is successful you will get the following prompt:
Installing pre-push hook... Pre-push hook installed successfully! -/oyhdmNNNNmdhyo/- :sdMMMMMMMMMMMMMMMMMMMMds: :yNMMMMMMMMMMMMMMMMMMMMMMMMMMNy: /mMMMMMMMMMNdyo+//://+shmMMMMMMMMMm/ :mMMMMMMMMh+. `:smMMMMMMMm: `yMMMMMMMm+` :yMMMMMMMs` `dMMMMMMN/ .hMMMMMMd` `mMMMMMMh` -s/+MMMMMMd` yMMMMMMh `:yNMMMs/MMMMMMy :MMMMMMm` `hMMMMMMMsoMMMMMM- yMMMMMM/ dMMMMMMM:mMMMMMy NMMMMMN` oMyossss:sMMMMMm MMMMMMN yM:NMMMMyoMMMMMN mMMMMMM` :Md+MMMMMoyMMMMMm yMMMMMM+ :NN+NMMMMM-NMMMMMy :MMMMMMN:- `sMdyMNymMMosMMMMMM- yMMMMMMd/o` .oNdhmMhhMmh++MMMMMMy `dMMMMMMm+do.- ./oyhhhNNhyNMMNosMMMMMMd` `dMMMMMMMssNdhsoo+/+oyyyydMmhhhMMMNs+mMMMMMMd` `yMMMMMMMNyydMNddddddddddhmMMMMho+dMMMMMMMy` :mMMMMMMMMmhhhdNMMMMMMMMmhssohMMMMMMMMm: /mMMMMMMMMMMNdhyyyyyyyhmMMMMMMMMMMm/ :yNMMMMMMMMMMMMMMMMMMMMMMMMMMNy: :sdMMMMMMMMMMMMMMMMMMMMds: `-/oyhdmNNNNmdhyo/- __________ __ / / __/ __/ / // /\ \_\ \ \___/___/___/ JSS application myproject is ready! Next steps: * Connect to Sitecore with jss setup (optional) * Try out your application with jss start * Enable source control (i.e. git init) (optional) * Check out the JSS documentation at https://jss.sitecore.com Enjoy! Updating JSS sample for containerized environment Done! Command succeeded.
If you open the code base folder, then you will find required setup to start with Sitecore Headless Services: The above Sitecore Containers setup for Next.js not have the Sitecore SXA module and Sitecore Next.js Multisite add-on to support the Sitecore Headless SXA.
To add the support for Sitecore SXA, you have to add Sitecore SXA and Sitecore SPE modules into your container setup.
The Sitecore developers knowledge repository provides details about how to add different Sitecore modules into your Sitecore Docker Container setup at Sitecore module reference.
For a more detailed explanation of Sitecore module images and how they are included, refer to this topic on how to add Sitecore modules, which includes the Sitecore PowerShell Extensions (SPE) and Sitecore Experience Accelerator (SXA) modules.
The Sitecore developers knowledge repository provides details about how to add different Sitecore modules into your Sitecore Docker Container setup at Sitecore module reference.
For a more detailed explanation of Sitecore module images and how they are included, refer to this topic on how to add Sitecore modules, which includes the Sitecore PowerShell Extensions (SPE) and Sitecore Experience Accelerator (SXA) modules.
-
Update docker compose file:
-
Sitecore PowerShell Extensions (SPE) Module:
Go to your docker compose override file add SPE module argument (SPE_IMAGE) to mssql-init and cm container services:
SPE_IMAGE: ${SITECORE_MODULE_REGISTRY}sitecore-spe-assets:${SPE_VERSION}
Here the values of SITECORE_MODULE_REGISTRY and SPE_VERSION defined in the environment (.env) file asSITECORE_MODULE_REGISTRY=scr.sitecore.com/sxp/modules/ SPE_VERSION=6.4-1809
You can check the Sitecore PowerShell Extensions compatibility with Sitecore Experience Accelerator (SXA) at Sitecore Experience Accelerator compatibility tables.
-
Sitecore Experience Accelerator (SXA) Module:
Go to your docker compose override file add SPE module argument (SXA_IMAGE) to solr-init, cm and cd container services:
SXA_IMAGE: ${SITECORE_MODULE_REGISTRY}sitecore-sxa-xm1-assets:${SXA_VERSION}
Here the values of SITECORE_MODULE_REGISTRY and SXA_VERSION defined in the environment (.env) file as
SITECORE_MODULE_REGISTRY=scr.sitecore.com/sxp/modules/ SXA_VERSION=10.3-1809
-
Update mssql-init base image details for Sitecore XP0 topology:
If you are using Sitecore Container XP0 topology, then you have to replace the sitecore-${TOPOLOGY} with sitecore-xp1 in image name of mssql-init service in the docker compose file and updated value would be like this:
mssql-init: isolation: ${ISOLATION} image: ${SITECORE_DOCKER_REGISTRY}sitecore-xp1-mssql-init:${SITECORE_VERSION}
-
Sitecore PowerShell Extensions (SPE) Module:
-
Update docker file:
-
CM service DockerFile instructions:
In previous step, we have added Sitecore PowerShell Extensions (SPE) and Sitecore Experience Accelerator (SXA) modules in docker compose file, so we have to add instructions for the SPE and SXA as per Sitecore module reference.
You have to append following instructions in your CM Service DockerFile
ARG PARENT_IMAGE ARG SXA_IMAGE ARG SPE_IMAGE FROM ${SPE_IMAGE} as spe FROM ${SXA_IMAGE} as sxa FROM ${PARENT_IMAGE} WORKDIR C:\inetpub\wwwroot # Add SPE module COPY --from=spe \module\cm\content .\ # Add SXA module COPY --from=sxa \module\cm\content .\ COPY --from=sxa \module\tools \module\tools RUN C:\module\tools\Initialize-Content.ps1 -TargetPath .\; ` Remove-Item -Path C:\module -Recurse -Force;
-
CD service DockerFile instructions:
We have added Sitecore Experience Accelerator (SXA) module in docker compose file, so we have to add instructions for the SXA in your CD Service DockerFile
ARG PARENT_IMAGE ARG SXA_IMAGE FROM ${SXA_IMAGE} as sxa FROM ${PARENT_IMAGE} WORKDIR C:\inetpub\wwwroot # Add SXA module COPY --from=sxa \module\cd\content .\ COPY --from=sxa \module\tools \module\tools RUN C:\module\tools\Initialize-Content.ps1 -TargetPath .\; ` Remove-Item -Path C:\module -Recurse -Force;
-
MSSQL-INIT service DockerFile instructions:
We have added Sitecore PowerShell Extensions (SPE) module in docker compose file, so we have to add instructions for the SPE in your mssql-init Service DockerFile
ARG PARENT_IMAGE ARG SPE_IMAGE FROM ${SPE_IMAGE} as spe FROM ${PARENT_IMAGE} WORKDIR C:\inetpub\wwwroot # Add SPE module COPY --from=spe C:\module\db C:\resources\spe
-
SOLR-INIT service DockerFile instructions:
We have added Sitecore Experience Accelerator (SXA) module in docker compose file of CM and CD role, so we required the Solr indexes for these roles, and for this we need to add instructions for the SXA in solr-init Service DockerFile
ARG PARENT_IMAGE ARG SXA_IMAGE FROM ${SXA_IMAGE} as sxa FROM ${PARENT_IMAGE} WORKDIR C:\inetpub\wwwroot # Add SXA module COPY --from=sxa .\module\solr\ C:\data\
-
CM service DockerFile instructions:
The Sitecore Next.js app which created by the Sitecore Next.js container template does not have Sitecore Next.js multisite add-on which is required to support the Sitecore Headless SXA multisite feature.
To get more information about what type of Next.js project you can create with the JSS initializer script present at Add-ons for Sitecore Next.js applications.
For our purpose, we will be creating the Sitecore Next.js app with Sitecore SXA and multisite add-on using following steps:
To get more information about what type of Next.js project you can create with the JSS initializer script present at Add-ons for Sitecore Next.js applications.
For our purpose, we will be creating the Sitecore Next.js app with Sitecore SXA and multisite add-on using following steps:
- Create new folder outside of your container setup
-
Open the Powershell terminal in ADMIN mode, and go to the location of newly created folder and run the following command
npx create-sitecore-jss --templates nextjs,nextjs-sxa,nextjs-multisite
-
Follow the prompts to provide options for your application.
npx create-sitecore-jss --templates nextjs,nextjs-sxa,nextjs-multisite ? Where would you like your new app created? C:\Multisiteaddon\nextjs Initializing 'nextjs'... ? What is the name of your app? sxamultisite ? What is your Sitecore hostname (used if deployed to Sitecore)? sxamultisite.dev.local ? How would you like to fetch Layout and Dictionary data? GraphQL ? How would you like to prerender your application? SSG Initializing 'nextjs-sxa'... Initializing 'nextjs-multisite'... Installing packages... > npm install
-
After successful execution of command, you will see the following information on terminal:
> sxamultisite@21.1.0 lint > eslint ./src/**/*.tsx ./src/**/*.ts ./scripts/**/*.ts --fix -/oyhdmNNNNmdhyo/- :sdMMMMMMMMMMMMMMMMMMMMds: :yNMMMMMMMMMMMMMMMMMMMMMMMMMMNy: /mMMMMMMMMMNdyo+//://+shmMMMMMMMMMm/ :mMMMMMMMMh+. `:smMMMMMMMm: `yMMMMMMMm+` :yMMMMMMMs` `dMMMMMMN/ .hMMMMMMd` `mMMMMMMh` -s/+MMMMMMd` yMMMMMMh `:yNMMMs/MMMMMMy :MMMMMMm` `hMMMMMMMsoMMMMMM- yMMMMMM/ dMMMMMMM:mMMMMMy NMMMMMN` oMyossss:sMMMMMm MMMMMMN yM:NMMMMyoMMMMMN mMMMMMM` :Md+MMMMMoyMMMMMm yMMMMMM+ :NN+NMMMMM-NMMMMMy :MMMMMMN:- `sMdyMNymMMosMMMMMM- yMMMMMMd/o` .oNdhmMhhMmh++MMMMMMy `dMMMMMMm+do.- ./oyhhhNNhyNMMNosMMMMMMd` `dMMMMMMMssNdhsoo+/+oyyyydMmhhhMMMNs+mMMMMMMd` `yMMMMMMMNyydMNddddddddddhmMMMMho+dMMMMMMMy` :mMMMMMMMMmhhhdNMMMMMMMMmhssohMMMMMMMMm: /mMMMMMMMMMMNdhyyyyyyyhmMMMMMMMMMMm/ :yNMMMMMMMMMMMMMMMMMMMMMMMMMMNy: :sdMMMMMMMMMMMMMMMMMMMMds: `-/oyhdmNNNNmdhyo/- __________ __ / / __/ __/ / // /\ \_\ \ \___/___/___/ JSS application sxamultisite is ready! Next steps: * Connect to Sitecore with jss setup (optional) * Enable source control (i.e. git init) (optional) * Check out the JSS documentation at https://jss.sitecore.com Enjoy!
The code structure of newly created Sitecore Next.js multisite would be like this
- Now go to the old rendering solution folder created using Next.js container template and delete all the files/folder from location \MyProject\src\rendering
-
Copy all the Nextjs code (files/folder) from the multisite setup created at previous step and place inside the \MyProject\src\rendering and change the project name as per the app name of your Sitecore JSS Site in the Sitecore CMS e.g. sxamultisite with sxawebsite if required:
Your Sitecore CMS Content Tree
In the previous step you have set up the Sitecore Headless SXA Multisite Next.js code base. Now we will add required Sitecore items into the Sitecore Headless SXA Site instance.
Create the API Key which is utilized by the Sitecore Layout Service or Sitecore Edge GraphQL or any other client to get the Sitecore Content. In the content tree, navigate to /sitecore/system/Settings/Services/API Keys and create a new API Key item and fill the required field as per the Create a Sitecore API key.
Create the API Key which is utilized by the Sitecore Layout Service or Sitecore Edge GraphQL or any other client to get the Sitecore Content. In the content tree, navigate to /sitecore/system/Settings/Services/API Keys and create a new API Key item and fill the required field as per the Create a Sitecore API key.
How to setup Sitecore Headless SXA Rendering Host Configuration item for Sitecore Headless SXA Multisite setup (Configure the editing host for your local environment)?
In Sitecore JSS setup (Sitecore Next.js SDK), you generally define the Rendering Engine Endpoint URL, Rendering Engine Application URL and Application Name settings in the Sitecore Patch Configuration present in the rendering code base at /sitecore/config/"app name".config and deploy this Sitecore Patch Configuration into the Sitecore CMS instance:
Here, app name sxawebsite is from the config.appName setting in the rendering host code (front-end app) base > package.json file and if you are deploying to local Sitecore CMS setup (IaaS setup) then replace rendering-host-name with localhost:3000, and if on the higher environment then you should have separate Editing Rendering Host for Experience Editor support and for lower environment (not local dev setup) you can use end-user Rendering Host for Experience Editor support.
For example, if you are on lower environment (not local dev setup) and your end-user Rendering Host name is uat.contoso.com then replace rendering-host-name with uat.contoso.com, and in higher environment you should have separate editing host like preview.contoso.com then replace rendering-host-name with preview.contoso.com.
In Sitecore JSS Headless SXA setup, you define the Rendering Engine Endpoint URL, Rendering Engine Application URL and Application Name settings with the help of Sitecore Rendering Host Configuration item at /sitecore/system/Settings/Services/Rendering Hosts/ and not via the Sitecore Patch Configuration as explained above.
Create the new Rendering Host item at /System/Settings/Services/Rendering Hosts/ item or use the Default item. Here we will be using Default rendering host item:
Here, application name sxawebsite is from the config.appName setting in the rendering host code (front-end app) base > package.json file and if you are deploying to local Sitecore CMS setup (IaaS setup) then replace rendering-host-name with localhost:3000, and if you have Sitecore Container based local setup with end-user Rendering host service then replace rendering-host-name with rendering:3000 (if end-user front-end app service name is rendering and you have separate editing rendering host service then use host name of that). If on the higher environment, then you should have separate Editing Rendering Host for Experience Editor support and for lower environment (not local dev setup) you can use end-user Rendering Host for Experience Editor support.
In Sitecore JSS setup (Sitecore Next.js SDK), you generally define the Rendering Engine Endpoint URL, Rendering Engine Application URL and Application Name settings in the Sitecore Patch Configuration present in the rendering code base at /sitecore/config/"app name".config and deploy this Sitecore Patch Configuration into the Sitecore CMS instance:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/" xmlns:role="http://www.sitecore.net/xmlconfig/role/"> <sitecore> <javaScriptServices> <apps> <app name="sxawebsite" layoutServiceConfiguration="default" sitecorePath="/sitecore/content/sxawebsite" useLanguageSpecificLayout="true" graphQLEndpoint="/sitecore/api/graph/edge" inherits="defaults" serverSideRenderingEngine="http" serverSideRenderingEngineEndpointUrl="http://<rendering-host-name>/api/editing/render" serverSideRenderingEngineApplicationUrl="http://<rendering-host-name>" /> </apps> </javaScriptServices> </sitecore> </configuration>
Here, app name sxawebsite is from the config.appName setting in the rendering host code (front-end app) base > package.json file and if you are deploying to local Sitecore CMS setup (IaaS setup) then replace rendering-host-name with localhost:3000, and if on the higher environment then you should have separate Editing Rendering Host for Experience Editor support and for lower environment (not local dev setup) you can use end-user Rendering Host for Experience Editor support.
For example, if you are on lower environment (not local dev setup) and your end-user Rendering Host name is uat.contoso.com then replace rendering-host-name with uat.contoso.com, and in higher environment you should have separate editing host like preview.contoso.com then replace rendering-host-name with preview.contoso.com.
In Sitecore JSS Headless SXA setup, you define the Rendering Engine Endpoint URL, Rendering Engine Application URL and Application Name settings with the help of Sitecore Rendering Host Configuration item at /sitecore/system/Settings/Services/Rendering Hosts/ and not via the Sitecore Patch Configuration as explained above.
Create the new Rendering Host item at /System/Settings/Services/Rendering Hosts/ item or use the Default item. Here we will be using Default rendering host item:
Here, application name sxawebsite is from the config.appName setting in the rendering host code (front-end app) base > package.json file and if you are deploying to local Sitecore CMS setup (IaaS setup) then replace rendering-host-name with localhost:3000, and if you have Sitecore Container based local setup with end-user Rendering host service then replace rendering-host-name with rendering:3000 (if end-user front-end app service name is rendering and you have separate editing rendering host service then use host name of that). If on the higher environment, then you should have separate Editing Rendering Host for Experience Editor support and for lower environment (not local dev setup) you can use end-user Rendering Host for Experience Editor support.
In previous steps we have created the API key and Rendering host items which required for accessing the data and for experience editor support.
In your Sitecore CMS instance, go to /content/[Headless SXA Tenant Name]/[Headless SXA Site]/Settings item, in the App Settings section, verify that the App Name field contains the name of your application from the config.appName setting in the rendering host code (front-end app) base > package.json file.
We will update value of DeploymentSecret field later once generated via Sitecore JSS Setup command
You also don’t need to enter the values of the Rendering Engine Endpoint URL and Rendering Engine Application URL in the Sitecore Headless SXA Settings item.
In your Sitecore CMS instance, go to /content/[Headless SXA Tenant Name]/[Headless SXA Site]/Settings item, in the App Settings section, verify that the App Name field contains the name of your application from the config.appName setting in the rendering host code (front-end app) base > package.json file.
We will update value of DeploymentSecret field later once generated via Sitecore JSS Setup command
You also don’t need to enter the values of the Rendering Engine Endpoint URL and Rendering Engine Application URL in the Sitecore Headless SXA Settings item.
In your Sitecore CMS instance, go to /content/[Headless SXA Tenant Name]/[Headless SXA Site]/Settings/Site Grouping/[your-site] SXA Site Definition item, in the Settings section, in the Predefined application rendering host field, verify that the field references the default rendering host item created in the step-5.
How to setup Multiple Hosts for a Sitecore SXA Site in Sitecore Headless SXA?
In Sitecore SXA setup when you will create the new SXA site then Sitecore SXA setup will create the default Site grouping > Sitecore Definition item under the /content/[Headless SXA Tenant Name]/[Headless SXA Site]/Settings/Site Grouping. This item is used by the SXA site to identify the Site based on the Host name defined in this Site Grouping/[your-site] item.
This Sitecore SXA Site Definition item will work when you are having only CM instance (in local XP0 dev setup) and in default SXA Site Definition item, hostname defined as wildcard (*) and database as MASTER, and it will handle all requests even from CD, and you will start getting error like Could not find configuration node: databases/database[@id='master'] while access the CD service (e.g., cd.myproject.localhost) and CD container become Unhealthy:
The above error is coming because CD service will try to find MASTER database on the CD service (server) which they don’t have access. For this you should have two Site Definitions items, one for CM and one for CD e.g., if you have separate preview website then you should create separate site definition entry for that also. In Sitecore Container setup you will be having CM and CD services so I will be taking this setup to define the separate site entries:
With above settings, you will be able to access the Frontend app in CM with Experience Editor support (separate rendering host) and Frontend app (end user rendering host) will load without error.
How to setup Multiple Hosts for a Sitecore SXA Site in Sitecore Headless SXA?
In Sitecore SXA setup when you will create the new SXA site then Sitecore SXA setup will create the default Site grouping > Sitecore Definition item under the /content/[Headless SXA Tenant Name]/[Headless SXA Site]/Settings/Site Grouping. This item is used by the SXA site to identify the Site based on the Host name defined in this Site Grouping/[your-site] item.
This Sitecore SXA Site Definition item will work when you are having only CM instance (in local XP0 dev setup) and in default SXA Site Definition item, hostname defined as wildcard (*) and database as MASTER, and it will handle all requests even from CD, and you will start getting error like Could not find configuration node: databases/database[@id='master'] while access the CD service (e.g., cd.myproject.localhost) and CD container become Unhealthy:
The above error is coming because CD service will try to find MASTER database on the CD service (server) which they don’t have access. For this you should have two Site Definitions items, one for CM and one for CD e.g., if you have separate preview website then you should create separate site definition entry for that also. In Sitecore Container setup you will be having CM and CD services so I will be taking this setup to define the separate site entries:
With above settings, you will be able to access the Frontend app in CM with Experience Editor support (separate rendering host) and Frontend app (end user rendering host) will load without error.
The deployment of Sitecore JSS Headless SXA App deployment is different from conventional JSS application because the default configuration settings are added to items (Site/Settings/) when a headless site is created, the Config Deployment step in the general process outlined at Walkthrough: Connecting a code-first JSS Next.js application to Sitecore must be skipped. Additionally, if any configuration changes required to Sitecore the you must comment out the app and site nodes in the configuration (sitecore/sites/site and sitecore/javaScriptServices/apps/app).
Open the rendering folder where Sitecore Next.js multisite code base in the terminal (ADMIN mode) and run the JSS command jss setup to generate the scjssconfig.json and /sitecore/config/[App Name].deploysecret.config files and follow the prompts. Follow the prompts to supply the following pieces of information:
Open the rendering folder where Sitecore Next.js multisite code base in the terminal (ADMIN mode) and run the JSS command jss setup to generate the scjssconfig.json and /sitecore/config/[App Name].deploysecret.config files and follow the prompts. Follow the prompts to supply the following pieces of information:
Is your Sitecore instance on this machine or accessible via network share? [y/n]: y Path to the Sitecore folder (e.g. c:\inetpub\wwwroot\my.siteco.re): ..\..\docker\deploy\platform\ Sitecore hostname (e.g. http://myapp.local.siteco.re; see /sitecore/config; ensure added to hosts): https://cm.myproject.localhost Sitecore import service URL [https://cm.myproject.localhost/sitecore/api/jss/import]: Sitecore API Key (ID of API key item): 2036C66B-228B-4967-88A5-5C31ABC72D2C Please enter your deployment secret (32+ random chars; or press enter to generate one): Deployment secret has been generated. Ensure the JSS app config on the Sitecore end has the same secret set.
- Is your Sitecore instance on this machine or accessible via network share? [y/n]:
Enter y because you will be able to access your website over the network.
- Path to the Sitecore folder (e.g. c:\inetpub\wwwroot\my.siteco.re):
What should be the path of the Sitecore folder during Sitecore JSS setup?
If you are doing development in local system (not in Sitecore Container setup) then it's the root physical path to the Sitecore instance, used to deploy config files and JS build artifacts. File share paths are fine for remote instances. For example: c:\inetpub\wwwroot\MySitecore\Website. If you do not have access to the website folder directly, answer no when asked if your instance is remote.
For Sitecore Container setup this would be the path of deploy folder as per your CM/CD service volume setup ..\..\docker\deploy\platform\
- Sitecore hostname (e.g. http://myapp.local.siteco.re; see /sitecore/config; ensure added to hosts):
This is the hostname of your Sitecore CMS instance previously configured in the Sitecore configuration patch /sitecore/config/[AppName].config. For example, https://cm.myproject.localhost
- Sitecore import service URL:
This is the import service URL of your JSS app. It consists of the hostname of your JSS app plus /sitecore/api/jss/import: https://cm.myproject.localhost/sitecore/api/jss/import.
You can leave this blank to use the default value or provide your custom URL.
- API key ID:
provide the Item ID of the Sitecore API key for this JSS app from the location /sitecore/system/Settings/Services/API Keys
- Deployment secret:
This is a shared secret that enables authentication to deploy your app items to Sitecore. We recommend you use the random key generated by the setup process. If you choose your own key, the secret must be a randomly generated string 32 or more characters long.
You are using Sitecore Headless SXA so you don’t need to deploy the app configuration and JSS Next.js app to Sitecore, and to support the experience editor separate Node.js based Rendering host (service) required to deploy your Sitecore Next.js (front-end) code base.
Applications built with JSS for Next.js are deployed differently than apps built with JSS for React, Angular, and Vue.js because of the particularities of Next.js. Essentially, because of the Next.js server, a JSS Next.js app uses the HTTP rendering engine.
You expose the Sitecore editor endpoints through editor integration API routes in the Next.js application when rendering Sitecore pages in editing mode.
You must create a secret token in order to safeguard the Sitecore editor endpoints. An alphanumeric value of at least 16 characters is advised by Sitecore.
This secret must be set on both the server and the client, and the values must be same.
There are two ways to configure the JSS Editing Secret server-side:
You must create a secret token in order to safeguard the Sitecore editor endpoints. An alphanumeric value of at least 16 characters is advised by Sitecore.
This secret must be set on both the server and the client, and the values must be same.
There are two ways to configure the JSS Editing Secret server-side:
-
Set JSS Editing Secret via environment variable:
In your Sitecore setup e.g., Sitecore Container setup you have the environment variable called JSS_EDITING_SECRET which used to store the JSS Editing Secret (I am using the deployment secret key as the JSS Editing Secret but you can have different also) and passed to the environment variable to CM service:
-
Other option is to secure the Sitecore editor endpoint using a Sitecore configuration patch and deploy to [WEBROOT]/App_Config/Include/zzz:
<!-- JSS Sitecore Configuration Patch File This configuration file registers the JSS site with Sitecore, and configures the Layout Service to work with it. Config patches need to be deployed to the Sitecore server. Normally `jss deploy config` can do this for local development. To manually deploy, or to deploy via CI, this file can be placed in the `App_Config/Include` folder, or a subfolder of it, within the Sitecore site. --> <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/" xmlns:role="http://www.sitecore.net/xmlconfig/role/"> <sitecore> <!-- Note that if any of these settings are enabled, they will apply to the entire Sitecore instance. If there are multiple sites defined in the instances, the settings will affect all of them. --> <settings> <!-- JSS EDITING SECRET To secure the Sitecore editor endpoint exposed by your Next.js app (see `serverSideRenderingEngineEndpointUrl` below), a secret token is used. This is taken from an env variable by default, but could be patched and set directly by uncommenting. This (server-side) value must match your client-side value, which is configured by the JSS_EDITING_SECRET env variable (see the Next.js .env file). We recommend an alphanumeric value of at least 16 characters. You can use the deployment secret key as the JSS Editing Secret but you can have different also --> <setting name="JavaScriptServices.ViewEngine.Http.JssEditingSecret" value="xxxx" /> </settings> </sitecore> </configuration>
In Sitecore JSS Next.js applications you can fetch layout and dictionary data using the Sitecore Layout Service REST API or the Sitecore GraphQL Edge schema and for this you can change the value of FETCH_WITH environment variable (possible values REST or GraphQL) mention in the environment file of your Sitecore Next.js code base(src\rendering\.env).
If you are fetching data with Sitecore Layout Service in your Sitecore Next.js SXA application (using the nextjs-sxa add-on) then you have to update the configurationName parameter value of the RestLayoutService object to 'sxa-jss' in /src/lib/layout-service-factory.ts file because the Layout service will append this updated value into the Sitecore Layout service api end point as https://[Host Name]/sitecore/api/layout/render/sxa-jss?item=
If you are fetching data with Sitecore Layout Service in your Sitecore Next.js SXA application (using the nextjs-sxa add-on) then you have to update the configurationName parameter value of the RestLayoutService object to 'sxa-jss' in /src/lib/layout-service-factory.ts file because the Layout service will append this updated value into the Sitecore Layout service api end point as https://[Host Name]/sitecore/api/layout/render/sxa-jss?item=
/** * Factory responsible for creating a LayoutService instance */ export class LayoutServiceFactory { /** * @param {string} siteName site name * @returns {LayoutService} service instance */ create(siteName: string): LayoutService { return process.env.FETCH_WITH === constants.FETCH_WITH.GRAPHQL ? new GraphQLLayoutService({ endpoint: config.graphQLEndpoint, apiKey: config.sitecoreApiKey, siteName, }) : new RestLayoutService({ apiHost: config.sitecoreApiHost, apiKey: config.sitecoreApiKey, siteName, //configurationName: 'default', configurationName: 'sxa-jss', }); } }
If you would like to fetch dictionary data from Sitecore using GraphQL and the JSS GraphQLDictionaryService then you have to set the root item id of your website.
To obtain dictionary data for the current app, the Dictionary Service requires a root item ID. If your instance have only one Sitecore JSS app then you can give the root item ID of your website landing page (Home page) at /src/lib/dictionary-service.ts and add rootItemId : "[Your JSS App Home item id with curly braces]" and if your Sitecore instance have more than one Sitecore JSS app then service will try to determine the root item for the current JSS App using GraphQL and app name.
import { DictionaryService, RestDictionaryService, GraphQLDictionaryService, constants, } from '@sitecore-jss/sitecore-jss-nextjs'; import config from 'temp/config'; /** * Factory responsible for creating a DictionaryService instance */ export class DictionaryServiceFactory { /** * @param {string} siteName site name * @returns {DictionaryService} service instance */ create(siteName: string): DictionaryService { return process.env.FETCH_WITH === constants.FETCH_WITH.GRAPHQL ? new GraphQLDictionaryService({ endpoint: config.graphQLEndpoint, apiKey: config.sitecoreApiKey, siteName, rootItemId: '<Your JSS App Home item id with curly braces>', /* The Dictionary Service needs a root item ID in order to fetch dictionary phrases for the current app. If your Sitecore instance only has 1 JSS App, you can specify the root item ID here; otherwise, the service will attempt to figure out the root item for the current JSS App using GraphQL and app name. rootItemId: '{GUID}' */ }) : new RestDictionaryService({ apiHost: config.sitecoreApiHost, apiKey: config.sitecoreApiKey, siteName, }); } } /** DictionaryServiceFactory singleton */ export const dictionaryServiceFactory = new DictionaryServiceFactory();
Open the Sitecore SXA Site Manager and make sure that your SXA Website resolved successfully:
After doing all the configuration/code changes, now its time to validate the Sitecore JSS SXA Next.js app, Go to your rendering host directory and start the front-end application in connected mode with the command: jss start:connected
You will see the registration of components and sample build logs are
Now open the browser and access the http://localhost:3000/, and you will be able to see the Blank page which will be showing title of your Sitecore SXA Site Home node item (/sitecore/content/[Tenant]/[Site]/Home)
If you will try to open the Sitecore Headless SXA page (from Container Sitecore Instance) into Experience Editor where remote rendering host (running SXA Next.JS app from host machine using jss start:connected) at http://localhost:3000/api/editing/render then you will get error Unable to connect to the remote server:
Error:
In this case you should have a separate Rendering host and use that as Editing Host to support Editing Experience in the lower environment and for higher environment you should have separate Editing Host. Also verify the Editing secret value correctly present at JavaScriptServices.ViewEngine.Http.JssEditingSecret attribute in Sitecore CMS and in SXA website (/sitecore/content/[Tenant]/[Site]/Settings, you can have same value for both Editing Secret and Deployment Secret) and disable the Rendering\sitecore\config\[website].config file in Rendering code base and not deploying to Sitecore CMS also.
After doing all the configuration/code changes, now its time to validate the Sitecore JSS SXA Next.js app, Go to your rendering host directory and start the front-end application in connected mode with the command: jss start:connected
You will see the registration of components and sample build logs are
> npm run start:connected -- > sxawebsite@21.2.1 start:connected > npm-run-all --serial bootstrap --parallel next:dev start:watch-components > sxawebsite@21.2.1 bootstrap > ts-node --project tsconfig.scripts.json scripts/bootstrap.ts Registering generate-component-builder plugin component-builder Registering generate-component-builder plugin packages Writing generate-component-builder plugins to C:\Amit\Sitecore-JSS-Headless-SXA\sxawebsite\scripts\temp\generate-component-builder-plugins.ts Registering config plugin computed Registering config plugin fallback Registering config plugin multisite Registering config plugin package-json Registering config plugin scjssconfig Writing config plugins to C:\Amit\Sitecore-JSS-Headless-SXA\sxawebsite\scripts\temp\config-plugins.ts Registering sitemap-fetcher plugin graphql-sitemap-service Writing sitemap-fetcher plugins to C:\Amit\Sitecore-JSS-Headless-SXA\sxawebsite\src\temp\sitemap-fetcher-plugins.ts Registering middleware plugin multisite Registering middleware plugin redirects Writing middleware plugins to C:\Amit\Sitecore-JSS-Headless-SXA\sxawebsite\src\temp\middleware-plugins.ts Registering page-props-factory plugin component-props Registering page-props-factory plugin normal-mode Registering page-props-factory plugin preview-mode Registering page-props-factory plugin site Writing page-props-factory plugins to C:\Amit\Sitecore-JSS-Headless-SXA\sxawebsite\src\temp\page-props-factory-plugins.ts Registering next-config plugin graphql Registering next-config plugin robots Registering next-config plugin sass Registering next-config plugin sitemap Writing next-config plugins to C:\Amit\Sitecore-JSS-Headless-SXA\sxawebsite\src\temp\next-config-plugins.js Registering extract-path plugin multisite Writing extract-path plugins to C:\Amit\Sitecore-JSS-Headless-SXA\sxawebsite\src\temp\extract-path-plugins.ts Registering site-resolver plugin default Registering site-resolver plugin multisite Writing site-resolver plugins to C:\Amit\Sitecore-JSS-Headless-SXA\sxawebsite\src\temp\site-resolver-plugins.ts Registering JSS component ColumnSplitter Registering JSS component Container Registering JSS component ContentBlock Registering JSS component FEaaSWrapper Registering JSS component Image Registering JSS component LinkList Registering JSS component Navigation Registering JSS component PageContent Registering JSS component PartialDesignDynamicPlaceholder Registering JSS component Promo Registering JSS component RichText Registering JSS component RowSplitter Registering JSS component Title Writing component builder to C:\Amit\Sitecore-JSS-Headless-SXA\sxawebsite\src\temp\componentBuilder.ts Fetching site information from https://cm-myproject.localhost/sitecore/api/graph/edge (node:44944) Warning: Setting the NODE_TLS_REJECT_UNAUTHORIZED environment variable to '0' makes TLS connections and HTTPS requests insecure by disabling certificate verification. (Use `node --trace-warnings ...` to show where the warning was created) Writing runtime config to C:\Amit\Sitecore-JSS-Headless-SXA\sxawebsite\src\temp\config.js > sxawebsite@21.2.1 next:dev > cross-env NODE_OPTIONS='--inspect' next dev > sxawebsite@21.2.1 start:watch-components > ts-node --project tsconfig.scripts.json scripts/generate-component-builder/index.ts --watch Debugger listening on ws://127.0.0.1:9229/fcf1066c-ddab-45f2-8af2-3d2d3296b7e7 For help, see: https://nodejs.org/en/docs/inspector Watching for changes to component builder sources in src/components... - info the --inspect option was detected, the Next.js proxy server should be inspected at port 9229. - ready started server on 0.0.0.0:3000, url: http://localhost:3000 - info the --inspect option was detected, the Next.js routing server should be inspected at port 9230. Debugger listening on ws://127.0.0.1:9230/b166d47f-1a42-4566-9fab-53d539e858b2 For help, see: https://nodejs.org/en/docs/inspector - info Loaded env from C:\Amit\Sitecore-JSS-Headless-SXA\sxawebsite\.env
Now open the browser and access the http://localhost:3000/, and you will be able to see the Blank page which will be showing title of your Sitecore SXA Site Home node item (/sitecore/content/[Tenant]/[Site]/Home)
If you will try to open the Sitecore Headless SXA page (from Container Sitecore Instance) into Experience Editor where remote rendering host (running SXA Next.JS app from host machine using jss start:connected) at http://localhost:3000/api/editing/render then you will get error Unable to connect to the remote server:
Error:
1952 17:28:25 ERROR Unable to connect to the remote server Exception: System.Net.WebException Message: Unable to connect to the remote server Source: System at System.Net.WebClient.UploadDataInternal(Uri address, String method, Byte[] data, WebRequest& request) at System.Net.WebClient.UploadString(Uri address, String method, String data) at Sitecore.JavaScriptServices.ViewEngine.Http.RenderEngine.Invoke[T](String moduleName, String functionName, Object[] functionArgs) Nested Exception Exception: System.Net.Sockets.SocketException Message: No connection could be made because the target machine actively refused it 127.0.0.1:3000 Source: System at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress) at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception)
In this case you should have a separate Rendering host and use that as Editing Host to support Editing Experience in the lower environment and for higher environment you should have separate Editing Host. Also verify the Editing secret value correctly present at JavaScriptServices.ViewEngine.Http.JssEditingSecret attribute in Sitecore CMS and in SXA website (/sitecore/content/[Tenant]/[Site]/Settings, you can have same value for both Editing Secret and Deployment Secret) and disable the Rendering\sitecore\config\[website].config file in Rendering code base and not deploying to Sitecore CMS also.
With the help of the above steps, you should be successfully able to configure a Sitecore Next.js multisite app and integrate it with Headless SXA within a Sitecore container. This setup empowers you to build scalable, decoupled, and content-rich applications while leveraging the powerful capabilities of both Sitecore and Next.js. Enjoy the benefits of headless architecture and the flexibility of Sitecore in delivering exceptional digital experiences.