HomeDev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideLegal TermsGitHubNuGetDev CommunitySubmit a ticketLog In


Describes routing in Optimizely Content Management System (CMS).

The Uniform Resource Locator (URL), a web address, is a character string reference to a resource. In most web browsers, the URL is inside an address bar at the top of a web page. URLs carry information from the browser to the server required to enact a desired action. Routing rewrites a URL to make it more user-friendly. 

A rewritten URL, known as Friendly or Search Engine Friendly  (SEF) URL, provides shorter, more relevant-looking web page links. By default, the routing system in Optimizely Content Management System (CMS) uses System.Web.Routing, with specific segments added for language, node, and a partial route. Routing is automatically handled based on content type. The language segment will set the language of the page, and the node segment will set the page reference from the URL. 

The technique adds a degree of separation between the files used to generate a web page and the presented URL. The partial route lets you set the routed data to something other than PageData, for example, catalog content in an Optimizely Customized Commerce solution. Such a partial route is usually registered in an initialization module.

Default routes

CMS registers several routes by default.

  • Shell modules have routes registered to support routing to gadgets.
  • CMS also registers several routes by default.
    • CMS registers routes in GlobalBase during initialization; you can override the RegisterRoutes method in Global.asax.cs to customize the registered routes or add additional routes.
    • The class EPiServer.Global also exposes the RoutesRegistrating and RoutesRegistered events, where you can perform custom registrations.
    • The namespace EPiServer.Web.Routing contains some extension methods for the class RouteCollection. You can use those extension methods to register a site route or a partial router. See Partial routing.
  • Among the default routes, there is one set up for each:
    • routing a simple address.
    • routing for sites (can be several sites in a multi-site environment).
    • routing pages/content from the root (that is, pages or content not under any start page).
  • The “ordinary” MVC route “{controller}/{action}” also is registered to support partial requests through Html.RenderAction. However, you cannot directly browse to those routes.

CMS registers the routes in the order above. The order is important because the first route checks whether the URL matches its route and routes the page through that route if it does. If the URL does not match the first route, the next route gets its chance.

MVC and Web Forms

You can route a URL through the MVC and Web Forms routing framework. The routing first locates the content routed to from the URL. After it locates the content, the framework queries the EPiServer.Web.TemplateResolver instance for the template used to render the request. The template can be an MVC controller or a Web Form. Depending on whether the template is a Web Form or an MVC controller, a suitable httpHandler is set to handle the request. If no content matches the URL or if no template matches the routed content, a 404 (not found) is returned.

Extend routing

You can extend routing in several levels. Events are exposed during incoming routing and the creation of outgoing URLs to customize routing. You also can modify the default URL pattern for content routing to handle a part of the URL. You can also add your routes.


The EPiServer.Web.Routing.IContentRouteEvents interface exposes the events RoutingContent and RoutedContent, which are raised during incoming routing. It raises RoutingContent events before executing the default routing implementation, and the content that matches the request is set in an event handler. It raises RoutedContent events after executing the default routing, and the routed content is replaced in an event handler. During outgoing URL generation, the CreatingVirtualPath and CreatedVirtualPath events are raised where event handlers can modify the generated URLs.

Modify content routes

CMS bases the built-in content routing on a registered URL pattern, where an implementation handles each pattern of an EPiServer.Web.Routing.Segments.ISegment interface. You can implement custom ISegment types and register them as part of the content routing.

By default, CMS registers content routing with a pattern of {language}/{node}/{partial}/{action}.

  • {language} – In the URL, an optional part might state the language.
  • {node} – Used to specify the CMS page or content in the URL, it will follow the site structure and contain page names after the start page on the site, down to the requested page. For example, in the structure start > news > firstNews, the URL part handled by {node} part would be /news/firstNews.
  • {partial} – If something is remaining in the URL after the page or content routing, any registered EPiServer.Web.Routing.IPartialRouter that matches the type of located page gets a chance to route the remainder of the URL.
  • {action} – The remaining part is checked for a valid action for an MVC controller. If the requested action is myAction (MVC), the whole URL is http://mySite/news/firstNews/myAction.

The MapContentRoute extension method takes the route's name, the URL pattern, and default values as arguments. Each part in the URL pattern for content routing, for example, {node} or {partial}, is handled by an implementation of EPiServer.Web.Routing.Segments.ISegment. You can extend content routing with ISegment implementations.

The following example shows how to add a route:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Routing;

using EPiServer.Web.Routing;

namespace CodeSamples {
  /// <summary>
  /// Code sample class containing cref examples on how to register a route
  /// </summary>
  public static class RegisterCustomRouteExample {
    /// <summary>
    /// Register a route which makes 'shop/' in the beginning of the url valid.
    /// This method should only be called when the site starts, for example in 'Application_Start' (Global.asax).
    /// </summary>
    public static void RegisterShopRoute() {
      // Register a route, which will make all url:s with 'shop/' before page names route to the page last in the list of page names
      // For example, http://mySite/shop/News/ListOfNews/FirstNews/ will route to the 'FirstNews' page. 

      RouteTable.Routes.MapContentRoute(name: "customRoute",
        url: "shop/{node}/{partial}/{action}",
        defaults: new {
          action = "index"
        contentRootResolver: (s) => s.StartPage);

Implement a custom route

You can also add custom route implementations. The order of the routes is important because the first route handling a request prevents the following routes from routing the request. So, when registering custom routes, decide whether it should be registered before or after the default routes.

URL length limitation

ASP.NET has multiple checks that validate the length of the URL and the path in Windows. Under normal circumstances, the default settings are enough, but to support long URLs, add the following configuration:

<httpRuntime maxUrlLength="1024" relaxedUrlToFileSystemMapping="true"/>