---
title: Custom routing using URL patterns
related:
  - https://docs.kentico.com/13/developing-websites/implementing-routing/custom-routing-using-url-patterns/identifying-pages-based-on-url-parameters.md
  - https://docs.kentico.com/13/developing-websites/implementing-routing/configuring-forbidden-url-characters.md
  - https://docs.kentico.com/13/multilingual-websites/setting-up-multilingual-websites/setting-up-culture-detection.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).

In the custom routing mode MVC sites respond to incoming requests using standard [ASP.NET routing](https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/controllers-and-routing/asp-net-mvc-routing-overview-cs). Page URLs are determined by the routes that you register into your MVC application's routing table.

## Setting up custom routing

Under custom routing the project's entire routing configuration is fully within your control. You can implement the entire routing scheme using nothing but conventional routing provided by ASP.NET. Xperience offers the following supporting features you can incorporate into your project depending on your requirements:

1. [Page type URL patterns](#setting-page-type-url-patterns) – URL patterns map pages in the [content tree](https://docs.kentico.com/13/managing-website-content/working-with-pages.md) to actual URLs under which the pages are accessible via the MVC application. They ensure that the administration application knows the live site URLs of pages. This is for example necessary when using the [page builder](https://docs.kentico.com/13/developing-websites/page-builder-development.md) feature – the administration application needs to access and display a page served by the MVC application. Furthermore, URL patterns are necessary to generate correct page links when using the [text editor](https://docs.kentico.com/13/managing-website-content/editing-rich-text-content.md).
2. [Preview mode support](https://docs.kentico.com/13/developing-websites/retrieving-content/adding-preview-mode-support.md) – preview mode provides a way to view the latest version of pages before they are published. The Xperience administration application uses URLs generated by the preview mode to: preview unpublished versions of pages, enable editing via the [page builder](https://docs.kentico.com/13/developing-websites/page-builder-development.md) feature, and generate [preview links](https://docs.kentico.com/13/managing-website-content/working-with-pages/sending-links-to-unpublished-pages.md) for external users.
3. [Page data context](#initializing-the-page-data-context) – page data context holds information about the currently requested page. The system uses the initialized context to enable the page builder feature and its functionality. Additionally, certain extension methods require an initialized data context to function.

### Setting page type URL patterns

Page type URL patterns serve to inform the Xperience administration application about the correct live site URLs of pages. URL patterns need to match your MVC application's route templates.

You will usually only want to specify the property for page types that are used to represent distinct pages on the MVC site. Pages that only store content used when aggregated on a different page may not need their own URL pattern. For example, such pages could represent individual branches/offices/cafes of a company that you aggregate on a page that displays all the branches/offices/cafes in one catalog.

1. Make sure your site's [Presentation URL](https://docs.kentico.com/13/configuring-xperience/managing-sites/setting-domain-names-for-sites.md) is configured correctly.
2. Open the **Page types** application.
3. Edit () the corresponding page type.
4. Fill in the **URL pattern** under which you want the page to be accessible from the administration UI. You can use simple macro expressions for accessing [data of the current page](https://docs.kentico.com/13/custom-development/working-with-pages-in-the-api/page-database-structure.md) in the pattern, such as _{%NodeGUID%}_, _{%DocumentModifiedWhen.Month%}_, or _{%NodeAlias%}._ The _{%NodeAlias%}_ macro retrieves a page alias that allows you to create more SEO-friendly URLs. For example:

   _/{%DocumentCulture%}/Articles/{%NodeAlias%}_

   resolves into URL ' _http://www.example.com/en-US/Articles/On- Roasts'_ for a page in the 'en-US' culture with _Node alias_ 'On Roasts'. Your MVC application needs to expose such pages under an identical URL (i.e., have a corresponding route template registered in its routing table). For example:

   ```csharp

   routes.MapRoute(
       name: "Articles",
       url: "{culture}/Articles/{pageAlias}"
   );

   ```

   > **Note:** **Notes:**
   >
   > - Complex macro expressions including [macro methods](https://docs.kentico.com/13/macro-expressions/reference-macro-methods.md) are not available in the URL pattern.
   > - We do not recommend using query string parameters in URL patterns. The system removes any parameters when generating _Preview_ URLs for pages based on the pattern.
5. Click **Save**.

Editors can now access the pages of this type from the administration interface using the **Live site** button. They can also insert links to other pages in the [text editor](https://docs.kentico.com/13/managing-website-content/editing-rich-text-content.md), and [work with page builder widgets](https://docs.kentico.com/13/managing-website-content/adding-page-content-using-widgets.md) on the **Page** tab.

> **Tip:** To give content editors more control over the resulting URL, augment URL patterns (and their corresponding routes) with parameters configurable via the **Pages** application. See [Identifying pages based on URL parameters](https://docs.kentico.com/13/developing-websites/implementing-routing/custom-routing-using-url-patterns/identifying-pages-based-on-url-parameters.md).

### Initializing the page data context

Page data context holds information about the currently requested page. The system uses the context to:

- Initialize the [page builder](https://docs.kentico.com/13/developing-websites/page-builder-development.md) feature for the current page.
- Initialize a corresponding [page template](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-page-templates.md) without you needing to provide information about the page object to the _TemplateResult_ constructor.
- Provide page [URL resolution](https://docs.kentico.com/13/developing-websites/retrieving-content/displaying-page-content.md) from within views.

You need to initialize the data context whenever you wish to use one of these features. The initialization must occur within the scope of the request serving the given page.

To initialize the data context for the current request, get an instance of the **IPageDataContextInitializer** interface (we recommend using [dependency injection](https://docs.kentico.com/13/developing-websites/initializing-xperience-services-with-dependency-injection.md)) and call its **Initialize** method. Specify the given page _(TreeNode_ object) or its _DocumentID_ as the parameter of the _Initialize_ method. For example, you can initialize the page data context within the controller action that displays the page.

```csharp

        private readonly IPageRetriever pageRetriever;
        private readonly IPageDataContextInitializer pageDataContextInitializer;

        // Gets instances of required services using dependency injection
        public PageDataContextInitialization(IPageRetriever pageRetriever,
                                             IPageDataContextInitializer pageDataContextInitializer)
        {
            this.pageRetriever = pageRetriever;
            this.pageDataContextInitializer = pageDataContextInitializer;
        }

        public ActionResult Home()
        {
            // Retrieves a page from the Xperience database with the '/Home' node alias path
            TreeNode page = pageRetriever.Retrieve<TreeNode>(query => query
                                .Path("/Home", PathTypeEnum.Single))
                                .FirstOrDefault();

            // Responds with the HTTP 404 error when the page is not found
            if (page == null)
            {
                return HttpNotFound();
            }

            // Initializes the page data context using the retrieved page
            pageDataContextInitializer.Initialize(page);

            return View();
        }


```
