Published on:Dec 14, 2021
Views: 2346
Number of votes: 0
Average rating:

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 https://cms.example.com and https://www.example.com will work, but https://www.holding-name.com and https://www.brand-name.com 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 https://cms.example.com, this becomes "example.com"
    • 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 https://world.optimizely.com/documentation/developer-guides/CMS/editing/on-page-editing-with-client-side-rendering/ 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 https://cms.example.com, this becomes "example.com". 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 https://cms.example.com/episerver): https://cms.example.com/episerver/cms/latest/clientresources/epi-cms/communicationinjector.js
  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: https://world.optimizely.com/documentation/developer-guides/CMS/editing/on-page-editing-with-client-side-rendering

    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
( By Daniel, 1/19/2022 11:15:30 AM)

Hi!

Thank you for clarifying the on page editing setup!

I have a question regarding decoupled and OPE:

This page of the documentation https://world.optimizely.com/documentation/developer-guides/CMS/security/decoupled-setup/ 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
Dan

Please login to comment.