HomeDev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideGitHubNuGetDev CommunitySubmit a ticketLog In
GitHubNuGetDev CommunitySubmit a ticket

Configure Shell modules

Describes how to configure custom modules like gadgets and plug-ins, to be used in the Optimizely Content Management System (CMS) user interface.

There are two different kinds of shell modules: protected and public. Protected ones are secured by default, while public ones are accessible to all users. The different types of modules are configured through PublicModuleOptions and ProtectedModuleOptions in the CmsUI section.

Modules can be added to Optimizely Content Management System (CMS) by configuring the options for automatic discovery or by explicitly adding them either by configuring the corresponding option through code or through appSettings.json file.

Example on configuration from appSettings.json:

"EPiServer": {
  "CmsUI": {
    "ProtectedModule": {
      "Items": [{
        "Name": "MySecureModule"

Example on configuration from code:

services.Configure<ProtectedModuleOptions>(o => o.Items.Add(new ModuleDetails { Name = "MySecureApp" }));

Public modules are installed in the modules folder while protected modules should be installed in the modules\_protected folder. The web application self is also treated as a "default" shell module but with path '.' (the application root). To add additional settings for the "default" shell module, add a module.config to the root of the application.

Options configuration

You can configure a module through options like resource paths and assemblies. However, you should have a corresponding module.config for a shell module.

Module manifest

Each module can have a manifest file (module.config) in the module's root directory, where you can specify further module-specific settings.


A shell module can specify which security policy should be applied to all requests for the module by assigning attribute authorizationPolicy in module.config with the name of the policy to apply. If the module does not explicitly specify a policy, is by default no policy applied to public modules, while a policy named episerver:defaultshellmodule (requires the user to be in any of the roles defined in CmsPolicyOptions.DefaultShellModuleRoles which by default is WebEditors, WebAdmins, CmsAdmins and Administrators) is applied to protected modules.

Example of assigned policy episerver:cmsedit for the module through module.config:

<?xml version="1.0" encoding="utf-8" ?>
<module authorizationPolicy="episerver:cmsedit">
    <add assembly="MyModuleAssembly" />


ProtectedModuleOptions and PublicModuleOptions have a property AutoDiscovery that you can configure to specify how module discovery should be performed. By default PublicModuleOptions.AutoDiscovery is set to AutoDsicovery.Modules meaning the modules folder is scanned for modules, which are then automatically registered. The default for ProtecedModuleOptions.AutoDiscovery is set to AutoDiscovery.Minimal meaning all protected modules must be explicitly registered. The CMS built-in modules like edit and admin mode are registered when AddCms is called.

Version client resources

You can specify the relative path to client resources in the module folder using the optional clientResourceRelativePath attribute of the module node in the module manifest file, module.config. The module client resource path is equal to the resource base path when clientResourceRelativePath attribute is not defined, or the value is an empty string. Otherwise, the system combines the module resource base path and the relative path specified in clientResourceRelativePath attribute. The resulting value is used as the module client resource path if it is a valid absolute path.

You can use this feature to implement versioning to avoid client-side caching issues without individually changing references to the resource files.

Example module directory structure

Example module.config

<?xml version="1.0" encoding="utf-8"?>
<module clientResourceRelativePath="1.5.0" >
  <!-- ... -->
    <add location="myScript" path="ClientResources/script.js" resourceType="Script" />
    <add location="myStyles" path="ClientResources/styles.css" resourceType="Style" />
  <!-- ... -->

Resource base path: ~/modules/SampleModule/

Client resource path: ~/modules/SampleModule/1.5.0/