State of the Sitecore Docker + Next.js Starter Kits
At the time of writing these lines, whether you create a project from the XM starter kit or the XM Cloud starter kit, both are affected by the same issue: CORS errors in the browser console in the Experience Editor. This only occurs on development environments on Docker. This does not happen on hosted XM Cloud environments. This could also happen on hosted XM environments.
In this blog post, we will cover the Docker development environment scenario.
How Do I Know if I Have CORS Errors?
In Experience Editor, open the browser developer tools in the console tab. If you see CORS errors similar to those, you are affected by this issue:
Why Are There CORS Errors?
When running the Experience Editor, the page domain is the Content Manager (CM) domain: https://xmcloudcm.localhost/
However, the HTML in the DOM of the Experience Explorer is coming from the rendering host. The Experience Editor asks the rendering host to return the server-side rendered (SSR) version of the page in edit mode: https://${RENDERING_HOST}/api/editing/render
The HTML page returned by the rendering host contains many absolute URLs with the rendering host domain as the rendering container PUBLIC_URL environment variable is by default set to "https://${RENDERING_HOST}". For the XM Cloud starter kit, it translates to https://www.sxastarter.localhost.
As the Experience Editor HTTP response does not specify any Access-Control HTTP headers, the requests to the absolute rendering host URLs are blocked by the browser CORS protections.
How to Get Rid of the CORS Errors?
This solution consists of adding the required HTTP headers to all the responses of the rendering host Next.js application. One way to achieve that is by configuring the Traefik HTTP proxy to do it.
- Edit your project
docker-compose.override.yml file.
- Locate your
rendering service.
-
Locate the service labels. You will usually find these:
labels:
- "traefik.enable=true"
- "traefik.http.routers.rendering-secure.entrypoints=websecure"
- "traefik.http.routers.rendering-secure.rule=Host(`${RENDERING_HOST}`)"
- "traefik.http.routers.rendering-secure.tls=true"
Yours may be slightly different.
-
Add the following labels just after your last one.
- "traefik.http.middlewares.rendering-headers.headers.accesscontrolallowmethods=GET,POST,OPTIONS"
- "traefik.http.middlewares.rendering-headers.headers.accesscontrolallowheaders=Content-Type"
- "traefik.http.middlewares.rendering-headers.headers.accesscontrolalloworiginlist=https://${CM_HOST}"
- "traefik.http.routers.rendering-secure.middlewares=rendering-headers"
-
You will end up with the following configuration:
labels:
- "traefik.enable=true"
- "traefik.http.routers.rendering-secure.entrypoints=websecure"
- "traefik.http.routers.rendering-secure.rule=Host(`${RENDERING_HOST}`)"
- "traefik.http.routers.rendering-secure.tls=true"
- "traefik.http.middlewares.rendering-headers.headers.accesscontrolallowmethods=GET,POST,OPTIONS"
- "traefik.http.middlewares.rendering-headers.headers.accesscontrolallowheaders=Content-Type"
- "traefik.http.middlewares.rendering-headers.headers.accesscontrolalloworiginlist=https://${CM_HOST}"
- "traefik.http.routers.rendering-secure.middlewares=rendering-headers"
These labels are used by the Traefik container to:
- Create a new
rendering-headers Traefik middleware.
- Define 3 HTTP headers on this middleware:
- Access-Control-Allow-Methods:
GET,POST,OPTIONS
- Access-Control-Allow-Headers:
Content-Type
- Access-Control-Allow-Origin:
https://${CM_HOST}
- The
CM_HOST variable is usually defined in the main .env file.
- On an XM Cloud project, its value is most of the time
xmcloudcm.localhost. Thus, the allowed origin becomes https://xmcloudcm.localhost.
- On an XM/XP project, its value is usually
cm.<your_project_name>.localhost. Thus, the allowed origin becomes https://cm.<your_project_name>.localhost.
- Attach this new Traefik middleware to the existing
rendering-secure Traefik router.
- Save the file.
- Assuming your solution is already initialized, and your containers are already running: In a PowerShell terminal running as administrator in your solution folder, restart the
rendering container by running the docker compose up -d command.
- This will compare the running containers with the Docker compose configuration, and recreate the containers with a modified configuration.
- Wait for the containers to be ready.
- Monitor your
rendering container logs to know when it has compiled the next.js project and it is ready to receive requests.
- Access the Experience Editor and enjoy having no CORS errors anymore.
Wrapping Up on CORS Errors
I hope you better understand the cause of Experience Editor CORS errors and this solution worked for your project. Other solutions might include configuring Access-Control HTTP headers directly in the Next.js application next.config.js file or as a Next.js middleware.
Happy Sitecoring!