Try our conversational search powered by Generative AI!

Remko Jantzen
Dec 14, 2021
(1 votes)

Twelve points to start with on page editing in CMS 11 or 12

Over the past few months, I've received a number of questions regarding the support for on-page editing by the CMS. It's not hard to enable, but you need to know where to look for. As I haven't found a complete overview of all steps needed to make it work, hence this blog post.

I will only cover the configuration needed and constraints to be obeyed to make on-page editing work, but won't go into the specifics of making changes within the CMS and/or building the decoupled frontend. The steps are the same for CMS 11 and CMS 12, on the few points where the version matters, I've highlighted these differences.

General setup

  1. As the Edit Mode requires communication between the shell and decoupled frontend the current constraint is that both must share the same domain. Thus and will work, but and will not work.

    Also make sure all domains are running either on HTTPS with certificates trusted by the browser or on HTTP, when you'll mix HTTP and HTTPS it will not work.
  2. In the Site configuration, make sure that the website URLs are configured correctly:
    • Website URL: The domain where the decoupled frontend is running
    • Host Names: Configure at a minimum two host-names
      • The domain of the decoupled frontend should have the type: Primary
      • The domain of the shell should have the type: Edit
  3. Though not a firm requirement, having the CMS control the URLs and routing within the decoupled frontend gives two major benefits:
    • Editors retain full control over both the website structure and content, at the expense of a slightly more complicated initial build - especially with Server Side Rendering involved.
    • Routing for edit-mode URLs is much easier to implement.

CMS configuration

  1. Ensure that your CMS is capable to serve unpublished versions of a content item, either by extending the Content Delivery API or using the Content Management API.

    Tip 1: To get close to feature parity, you'll need to extend the CMS with support for loading by Project ID, Visitor Group ID, and Channel ID. (The last one as 3rd party modules within the CMS may depend on it).

    Tip 2: By default, the Context Mode resolution differs between the Content Delivery/Management API and the regular CMS, so any 3rd party add-on will behave like you're working on a public endpoint, even when accessing the API from within edit mode. Easy solution? Create a single ContextModeResolver unifying both resolvers into one single implementation.
  2. Ensure that your CMS supports a form of single-sign-on between the Shell and Decoupled frontend. There's no requirement on which IAM solution is used, beyond it enabling the decoupled frontend to send authenticated requests to the Content Delivery/Management API.
  3. Make sure that the ContentDeliveryAPI option "OptimizeForDelivery" has been set. Furthermore it is highly recommended to invoke the following extension methods on the service container in your startup: "ConfigureForExternalTemplates()" and "ConfigureForContentDeliveryClient()"

    Note: If you make these changes on an application already using the Content Delivery API you will find it changing the data returned by the Content Delivery API.
  4. Make sure the shell updates the document.domain value in the browser. Yes, this is a deprecated setting, but at the time of writing, it's the only way to get On-Page Editing to work. This must be the domain, without subdomains, protocol, and port number. So for, this becomes ""
    • CMS 11: Add the AppSetting "episerver:ManagementDomain" with the value as above
    • CMS 12: At the time of writing, there's no standard way of doing this. Probably injecting a script into the shell will give you the ability to update this value.

Frontend requirements

  1. The shell determines the currently selected item by URL and uses special URLs to render edit mode. Hence:
    • All navigation between content items must happen by a regular page unload/load. So using the History API or on-page routers is not allowed in this mode.
    • The Decoupled frontend must support the special URLs generated by the shell to load the content item selected by the editor 
  2. The actual DOM tree must have the appropriate attributes to inform the shell where the editable fields actually are presented on the page. See for more details.

    Note: This is the actual DOM tree, shown by "inspect element" in a browser, not the virtual DOM maintained by React, Vue, etc...
  3. When the page runs in edit mode it must update the document.domain value in the browser. This must be the domain, without subdomains, protocol, and port number. So for, this becomes "". This must be the same value as for step 4 in the CMS.
  4. To ensure that the edit mode renders correctly and can communicate with the SPA/PWA, the communicator script must be loaded and executed (verify that there’re no CORS or other security measures preventing this). The URL for this script is (assuming that the CMS runs at
  5. Last, but certainly not least, the frontend must listen to the contentSaved event to refresh the view with the latest data. The documentation for this is available at:

    When running decoupled, with the communicationInjector (Step 4 above) loaded, this can be done by using the global "epi" variable like so:
    epi.subscribe("contentSaved", event => { /* Your handler here */});

And that's it, these are my "Twelve points to start with on-page-editing in CMS 11 or 12".

Happy coding!

Dec 14, 2021


Daniel Jan 19, 2022 11:15 AM


Thank you for clarifying the on page editing setup!

I have a question regarding decoupled and OPE:

This page of the documentation recommends breaking apart the CMS UI from the public facing server.

If you have a public facing server (SSR javascript) with no EPiServer reference other than the @episerver/content-delivery npm package and (when signed in) the DOM attributes utilized by the communicationinjector-script.

And an internal server with the CMS UI and the Content Delivery API (only reachable by the public facing server).

Should the CMS UI somehow be kept separate from the Content Delivery API for some reason or is this setup fine provided the SSO is in place?


Or are there any potential pitfalls regarding decoupled setup and OPE to be aware of security-wise?

Best regards

Please login to comment.
Latest blogs
Headless forms reloaded (beta)

Forms is used on the vast majority of CMS installations. But using Forms in a headless setup is a bit of pain since the rendering pipeline is based...

MartinOttosen | Mar 1, 2024

Uploading blobs to Optimizely DXP via PowerShell

We had a client moving from an On-Prem v11 Optimizely instance to DXP v12 and we had a lot of blobs (over 40 GB) needing uploading to DXP as a part...

Nick Hamlin | Mar 1, 2024 | Syndicated blog

DbLocalizationProvider v8.0 Released

I’m pleased to announce that Localization Provider v8.0 is finally out.

valdis | Feb 28, 2024 | Syndicated blog

Epinova DXP deployment extension – With Octopus deploy

Example how you can use Epinova DXP deployment extension in Octopus deployment.

Ove Lartelius | Feb 28, 2024 | Syndicated blog

Identify Azure web app instance id's for an Optimizely CMS site

When running Optimizely CMS in Azure, you will be using an instance bound cloud license. What instances are counted, and how can you check them? Le...

Tomas Hensrud Gulla | Feb 27, 2024 | Syndicated blog

Introducing Image Transformer - AI Assistant for Optimizely

We've got something super cool to share with you, and it's all about giving your images a fresh spin. Image Transformer, the latest feature from ou...

Luc Gosso (MVP) | Feb 26, 2024 | Syndicated blog