---
title: Enabling content tree-based routing
related:
  - https://docs.kentico.com/13/developing-websites/implementing-routing/content-tree-based-routing.md
  - https://docs.kentico.com/13/developing-websites/implementing-routing/content-tree-based-routing/setting-up-content-tree-based-routing.md
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

[Content tree-based](https://docs.kentico.com/13/developing-websites/implementing-routing/content-tree-based-routing.md) routing needs to be enabled in both the live site application and the **Settings** application in the administration interface.

If you are switching to content tree-based routing from [custom routing](https://docs.kentico.com/13/developing-websites/implementing-routing/custom-routing-using-url-patterns.md) with page type URL patterns, you can [manually preserve the former URLs](#preserving-former-urls-when-switching-to-content-tree-based-routing) to make the transition smoother. The URLs need to be preserved before you enable content tree-based routing.

### Xperience administration application

The Xperience administration application needs to have its **Routing** mode set to _Based on content tree_. New installations of Xperience have this mode set by default:

> **Note:** **Changing routing modes**
>
> Changing the routing mode to _Based on content tre&#x65;_&#x6F;r configuring some of the optional settings causes the system to (re)generate a URL for every [suitable page](https://docs.kentico.com/13/developing-websites/implementing-routing/content-tree-based-routing.md), so the operation may be time-consuming (depending on the performance of the hosting environment).
>
> When changing the routing mode back to _Custom_, the system deletes all generated URLs. Make sure you [register appropriate routes](https://docs.kentico.com/13/developing-websites/implementing-routing/custom-routing-using-url-patterns.md) into your live site application's routing table before transitioning, otherwise your website will stop working correctly.

1. Open the **Settings** application in the Xperience administration application.
2. Switch to the **URLs and SEO** tab.
3. Under the **Routing** section, select **Based on content tree** for the **Routing mode** setting.
   - The setting is site-specific – each site can be configured to use a different [routing mode](https://docs.kentico.com/13/developing-websites/implementing-routing.md).
4. (Optional) Under the **[Content tree-based routing](https://docs.kentico.com/13/configuring-xperience/managing-sites/configuring-settings-for-sites/settings-urls-and-seo.md)** section:
   - Set the **Home page** and **Home page URL behavior** settings to let the system handle redirection to your website home page. Using a unified home page URL is highly recommended, because it prevents the duplicate content problem on your website's most important URL.
   - Set the **URL format for multilingual sites**setting, to determine the format in which page URLs are generated on multilingual sites.
     - If you choose the _Language prefix_ URL format, you can also **Hide language prefixes for the default culture** and **Use culture aliases as language prefixes**. See [Configuring URLs for multilingual websites](https://docs.kentico.com/13/multilingual-websites/setting-up-multilingual-websites/configuring-urls-for-multilingual-websites.md).
   - Configure the **Enforce lowercase URLs** setting to ensure lowercasing of the virtual (relative) parts of URLs. By default, the system generates URLs in a lowercase format.
   - Set the **Use URLs with trailing slash** setting to specify how the trailing slash is handled in URLs.
   - Enable the **Store former URLs** setting if you want the system to keep track of [changes made to page URLs](https://docs.kentico.com/13/managing-website-content/working-with-pages/managing-page-urls.md#former-urls) and perform redirects from former to current URLs.
     - To prevent accumulation of various temporary URLs as former URLs, we recommend enabling this setting only on live websites (i.e. production environments).
5. **Save** the changes.

The administration application is now configured to use content tree-based routing.

### Live site application

On the side of the live site application, you need to enable content tree-based routing as a feature used by your project.

<!-- dev-model:mvc start -->

**MVC 5 development model.** Applies only when building with ASP.NET MVC 5. If this page also covers ASP.NET Core, that version is in its own block.

1. Open your MVC project in Visual Studio.
2. Enable the page routing feature at the start of your application's life cycle, for example in the **Application\_Start** method of your project's **Global.asax** file.

   > **Info:** MVC projects created by the [installer](https://docs.kentico.com/13/installation/installing-xperience.md) contain the _ApplicationConfig_ class, whose _RegisterFeatures_ method is called in the _Application\_Start_ method by default. You can use this class to encapsulate all of your _ApplicationBuilder_ code (enabling and configuring of Xperience MVC features).

   > **Note:** **Note**: The feature must be enabled **before** you register routes into the application's _RouteTable_. The _Kentico().MapRoutes()_ method adds routes that handle automatic routing when the feature is enabled.
3. Call the  **UsePageRouting**  method of the  _ApplicationBuilder_  instance.

   ```csharp

   using Kentico.Content.Web.Mvc.Routing;
   using Kentico.Web.Mvc;

   ...

   protected void Application_Start()
   {
       ...

       // Gets the ApplicationBuilder instance
       // Allows you to enable and configure selected Xperience MVC integration features
       ApplicationBuilder builder = ApplicationBuilder.Current;

       // Enables content tree-based routing
       builder.UsePageRouting();

       ...
   }

   ```

Content tree-based routing is now enabled for the live site application. The _Kentico().MapRoutes()_ method called in your application's _RouteConfig_ registers a general route that matches URLs generated by the system for page types with the [URL feature](https://docs.kentico.com/13/developing-websites/defining-website-content-structure/managing-page-types/creating-page-types.md) enabled.

<!-- dev-model:mvc end -->

<!-- dev-model:core start -->

**ASP.NET Core development model.** Applies only when building with ASP.NET Core. If this page also covers MVC 5, that version is in its own block.

1. Open your live site project in Visual Studio.
2. Edit your application's startup class (**Startup.cs** by default).
3. [Enable](https://docs.kentico.com/13/developing-websites/developing-xperience-applications-using-asp-net-core/starting-with-asp-net-core-development/enabling-xperience-features-in-asp-net-core-applications.md) the page routing feature by:

   1. Calling the **UsePageRouting** method of the _IFeaturesBuilder_ delegate passed to the _IServiceCollection.AddKentico_ method within _ConfigureServices_.
   2. [Enabling membership features](https://docs.kentico.com/13/managing-users/user-registration-and-authentication/integrating-xperience-membership.md) for the application (required due to authorization checks performed by the routing feature).

      ```csharp

      using Kentico.Content.Web.Mvc.Routing;
      using Kentico.Web.Mvc;

      ...

      public void ConfigureServices(IServiceCollection services)
      {
          ...
          // Enables and configures Xperience features
          services.AddKentico(features =>
          {
              // Enables content tree-based routing
              features.UsePageRouting();
              ... 
          });

          // Membership configuration
          ...
      }

      ```

Content tree-based routing is now enabled for the live site application. The _Kentico().MapRoutes()_ method called in your application's startup pipeline registers a general route that matches URLs generated by the system for page types with the [URL feature](https://docs.kentico.com/13/developing-websites/defining-website-content-structure/managing-page-types/creating-page-types.md) enabled.

<!-- dev-model:core end -->

Continue by [configuring your project](https://docs.kentico.com/13/developing-websites/implementing-routing/content-tree-based-routing/setting-up-content-tree-based-routing.md).

## Preserving former URLs when switching to content tree-based routing

If you want to enable content tree-based routing on a site that uses [customrouting](https://docs.kentico.com/13/developing-websites/implementing-routing/custom-routing-using-url-patterns.md) based on page type URL patterns, and you want to make sure the pages are still accessible under the old "custom" URLs, you can use the following code snippet to preserve the old URLs as [former URLs](https://docs.kentico.com/13/managing-website-content/working-with-pages/managing-page-urls.md#former-urls). The code stores your URLs in the table for the **Former URLs** application and maps them to the corresponding pages in the content tree. This ensures that when requested, the old URLs are redirected to their corresponding new URLs (once you enable content tree-based routing and the [former URLs feature](https://docs.kentico.com/13/configuring-xperience/managing-sites/configuring-settings-for-sites/settings-urls-and-seo.md)).

You can run the code snippet, for example, as part of a [console application](https://docs.kentico.com/13/integrating-3rd-party-systems/using-the-xperience-api-externally.md) or within the initialization code of a [custom module](https://docs.kentico.com/13/custom-development/creating-custom-modules/initializing-modules-to-run-custom-code.md).

> **Note:** **Important**
>
> You need to run the code BEFORE you enable content tree-based routing, i.e. the _Routing mode_ [setting](https://docs.kentico.com/13/configuring-xperience/managing-sites/configuring-settings-for-sites/settings-urls-and-seo.md) needs to be set to _Custom_.

```csharp title="Manually storing former URLs"

using System.Collections.Generic;

using CMS.DataEngine;
using CMS.DocumentEngine.Internal;

namespace CMS.DocumentEngine
{
    public class CustomUrlsBackup
    {
        /// <summary>
        /// This is an example code snippet that generates former URL paths for pages with a URL pattern.
        /// Former URLs are generated only for existing culture versions of pages.
        /// </summary>
        /// <param name="siteIdentifier">Site identifier (site code name or ID).</param>
        public void BackupUrls(SiteInfoIdentifier siteIdentifier)
        {
            var classesWithUrl = GetClassesWithUrl(siteIdentifier);

            foreach (var classWithUrl in classesWithUrl)
            {
                new DocumentQuery(classWithUrl)
                    .AllCultures()
                    .OnSite(siteIdentifier)
                    .ForEachPage(pagesInBatch => ProcessBatch(pagesInBatch, siteIdentifier), 100);
            }
        }

        // Loads all page types with a specified URL pattern and the 'URL' feature enabled
        private IList<string> GetClassesWithUrl(SiteInfoIdentifier siteIdentifier)
        {
            return DataClassInfoProvider.GetClasses()
                .Column("ClassName")
                .WhereNotEmpty("ClassURLPattern")
                .WhereTrue("ClassIsDocumentType")
                .WhereTrue("ClassHasURL")
                .OnSite(siteIdentifier)
                .GetListResult<string>();
        }

        // Saves the former URLs for a batch of pages
        private void ProcessBatch(DocumentQuery pagesInBatch, SiteInfoIdentifier siteIdentifier)
        {
            foreach (var page in pagesInBatch)
            {
                var formerUrl = CreateFormerUrlInfo(siteIdentifier, page);
                PageFormerUrlPathInfo.Provider.Set(formerUrl);
            }
        }

        // Creates a former URL for the specified page,
        // based on its current live site URL (resolved URL pattern)
        private PageFormerUrlPathInfo CreateFormerUrlInfo(int siteId, TreeNode page)
        {
            var urlPath = DocumentURLProvider.GetUrl(page);
            urlPath = PageUrlPathNormalizer.Normalize(urlPath.TrimStart('~')).Path;

            return new PageFormerUrlPathInfo
            {
                PageFormerUrlPathCulture = page.DocumentCulture,
                PageFormerUrlPathNodeID = page.NodeID,
                PageFormerUrlPathSiteID = siteId,
                PageFormerUrlPathUrlPath = urlPath                
            };
        }
    }
}


```
