---
title: Adding preview mode support
related:
  - https://docs.kentico.com/13/developing-websites/mvc-development-overview.md
  - https://docs.kentico.com/13/developing-websites/implementing-routing/custom-routing-using-url-patterns.md
  - https://docs.kentico.com/13/managing-website-content/working-with-pages/sending-links-to-unpublished-pages.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).

Preview mode in Xperience provides a way to view the latest version of pages before they are published (for example when using [Workflow](https://docs.kentico.com/13/managing-website-content/working-with-pages/using-workflows.md)).

To use the preview mode, you need to set up and configure the related functionality. The configuration differs based on your site's [routing mode](https://docs.kentico.com/13/developing-websites/implementing-routing.md):

- On sites using [content tree-based](https://docs.kentico.com/13/developing-websites/implementing-routing/content-tree-based-routing.md) routing, preview mode works automatically for all [page types](https://docs.kentico.com/13/developing-websites/defining-website-content-structure/managing-page-types.md) with the [URL feature](https://docs.kentico.com/13/developing-websites/defining-website-content-structure/managing-page-types/creating-page-types.md) enabled.
- On sites running in the [custom routing](https://docs.kentico.com/13/developing-websites/implementing-routing/custom-routing-using-url-patterns.md) mode, you need to specify the URL pattern for your page types (in the administration application). The URL pattern is used to create URLs to the content presented by the external application.

Preview URLs for pages are used in the following scenarios:

- When viewing pages in **Preview** mode in the **Pages** application.
- When editing pages via the [page builder](https://docs.kentico.com/13/developing-websites/page-builder-development.md) on the **Page** tab of the **Pages** application.
- When generating preview links for pages in **Pages -> Properties -> URLs -> Preview URL**. See: [Sending links to unpublished pages](https://docs.kentico.com/13/managing-website-content/working-with-pages/sending-links-to-unpublished-pages.md)

The preview URLs the system generates for pages consist of additional information, such as language version and a hash for validating the URL. The [integration package](https://docs.kentico.com/13/developing-websites/starting-with-mvc-development/installing-xperience-integration-packages.md) in your MVC application validates and processes the preview URL. The page is then displayed through the standard [routing process](https://docs.kentico.com/13/developing-websites/implementing-routing.md).

> **Note:** You need to manually ensure that your application displays the **latest versions of pages** in preview mode. See [Loading the latest versions of pages](#loading-the-latest-versions-of-pages) for details.

## Preview mode and cookie SameSite requirements

Preview mode is used by the Xperience administration to preview content from the live site application. The feature relies on certain cookies transmitted between the two applications to work correctly.

If your administration and live site applications are hosted on separate domains, you need to configure the system to send cookies with the appropriate _SameSite_ mode when communicating under preview mode. See [Configuring cookie SameSite mode](https://docs.kentico.com/13/developing-websites/working-with-cookies/configuring-cookie-samesite-mode.md).

## Configuring the maximum URL length

The preview URLs that the system generates for pages can be very long (they contain information about the context of the page and validation hashes). We recommend increasing the maximum allowed URL length for the application used to present the content.

1. Edit your MVC application's web.config file.
2. Set the **maxUrlLength** attribute of the **httpRuntime** element in the **system.web** section (512 should be a large enough value):

   ```xml

   <system.web>
   ...
       <httpRuntime targetFramework="4.8" maxUrlLength="512" />
   ...
   </system.web>

   ```

The application can now correctly process the preview URLs generated by the system.

## Clickjacking protection and preview mode

If your MVC application is protected against cross-site request forgery and clickjacking attacks using the [ValidateAntiForgeryToken attribute](https://docs.microsoft.com/en-us/dotnet/api/system.web.mvc.validateantiforgerytokenattribute), your application automatically sends the [X-Frame-Options HTTP header](https://en.wikipedia.org/wiki/Clickjacking#X-Frame-Options) with the _SAMEORIGIN_ framing policy. The system _**automatically disables the header**_ for preview URLs. This allows users to preview content handled by the MVC application in the Xperience administration interface, even when running the administration on a different domain.

Because the preview URLs could potentially be vulnerable to clickjacking attacks, the system automatically adds the [Content Security Policy](https://en.wikipedia.org/wiki/Content_Security_Policy) (CSP) HTTP response header with the _frame-ancestors_ policy, and sets the Xperience administration site's domain as a valid source. This allows you to display previewed pages in the Xperience administration, while preventing embedding on any other domains.

> **Note:** **Important**
>
> If you manually apply the _X-Frame-Options_ header in your MVC site's web.config file, the preview mode and all related features (such as the [page builder](https://docs.kentico.com/13/developing-websites/page-builder-development.md) and [form builder](https://docs.kentico.com/13/developing-websites/form-builder-development.md)) in the Xperience administration display a blank page instead of the previewed content.
>
> If you set _CSP_ headers on your own, make sure to always whitelist the Xperience administration parent site using the _frame-ancestors_ policy. Otherwise the preview mode and all related features will not display content.

## Excluding tracking scripts for preview mode

If you use third-party analytics or tracking scripts on your website (for example Google Tag Manager scripts), we strongly recommend that you disable them for preview mode. The preview URLs are intended for internal use within the Xperience administration interface or for viewing unpublished pages. Exposing preview URLs to third parties and having them affect your website's analytics data is typically not desired.

To exclude tracking scripts for preview mode, use conditions that [evaluate whether preview mode is enabled for requests](#checking-whether-preview-mode-is-enabled-for-requests). You can add the conditions directly around the script code within your site's views, or within related business code that you use to include the scripts.

## Checking whether preview mode is enabled for requests

Use the following code to check whether preview mode is enabled for a request:

<!-- 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.

```csharp

using Kentico.Content.Web.Mvc;
using Kentico.Web.Mvc;
using System.Web;

...

bool previewEnabled = HttpContext.Current.Kentico().Preview().Enabled;

```

The location where you need to check the request context for preview mode depends on the implementation of your MVC application. For example, directly in the code of your controllers or when registering repositories that [retrieve page content](https://docs.kentico.com/13/developing-websites/retrieving-content/displaying-page-content.md).

> **Tip:** **Tip**: You can get the current page culture from the context of the preview request:
>
> ```csharp
>
> using Kentico.Content.Web.Mvc;
> using Kentico.Web.Mvc;
> using System.Web;
>
> ...
>
> string cultureName = HttpContext.Current.Kentico().Preview().CultureName;
>
> ```

<!-- 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.

```csharp

using Kentico.Content.Web.Mvc;
using Kentico.Web.Mvc;
using Microsoft.AspNetCore.Http;

...

bool previewEnabled = HttpContext.Kentico().Preview().Enable;

```

The location where you need to check the request context for preview mode depends on the implementation of your live site application. For example, directly in the code of your controllers or when registering repositories that [retrieve page content](https://docs.kentico.com/13/developing-websites/retrieving-content/displaying-page-content.md).

> **Tip:** **Tip**: You can get the current page culture from the context of the preview request:
>
> ```csharp
>
> using Kentico.Content.Web.Mvc;
> using Kentico.Web.Mvc;
> using Microsoft.AspNetCore.Http;
>
> ...
>
> string cultureName = HttpContext.Kentico().Preview().CultureName;
>
> ```

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

## Checking whether edit mode is enabled for requests

Use the following code to check whether edit mode (i.e., editing of pages on the Page builder tab in the Pages application) is enabled for a request:

<!-- 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.

```csharp

using Kentico.Web.Mvc;
using Kentico.PageBuilder.Web.Mvc;
using System.Web;

...

bool editModeEnabled = HttpContext.Current.Kentico().PageBuilder().EditMode;

```

The location where you need to check the request context for edit mode depends on the implementation of your MVC application. For example, in the configuration of a Page builder component that you want to work differently in edit mode and on the live site.

<!-- 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.

```csharp

using Kentico.Web.Mvc;
using Kentico.PageBuilder.Web.Mvc;
using Microsoft.AspNetCore.Http;

...

bool editModeEnabled = HttpContext.Kentico().PageBuilder().EditMode;

```

The location where you need to check the request context for edit mode depends on the implementation of your live site application. For example, in the configuration of a Page builder component that you want to work differently in edit mode and on the live site.

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

## Loading the latest versions of pages

For requests that have preview mode enabled, you need to ensure that your code loads the [latestversions](https://docs.kentico.com/13/custom-development/working-with-pages-in-the-api.md#retrieving-pages-under-workflow) of pages instead of the _published_ versions. It is recommended to use the **IPageRetriever** interface (available in the _Kentico.Content.Web.Mvc_ namespace), as it automatically ensures that you have the correct version of content. For more information about retrieving page data, see [Displaying page content](https://docs.kentico.com/13/developing-websites/retrieving-content/displaying-page-content.md).

```csharp

private readonly IPageRetriever pageRetriever;

// Gets an instance of the IPageRetriever service using dependency injection
public ExampleController(IPageRetriever pageRetriever)
{
    this.pageRetriever = pageRetriever;
}

public ActionResult Index()
{
    // Retrieves pages of 'Article' page type that are in the '/Articles/May' section of the content tree
    var articles = pageRetriever.Retrieve<Article>( query => query
                    .Path("/Articles/May", PathTypeEnum.Children));
}

```

> **Note:** **Retrieving content under workflow in AJAX calls**
>
> When retrieving the latest edited version of content under workflow within an AJAX call, you need to ensure that the call's URL is authenticated. Use the **AuthenticateUrl** extension method (available in the _Kentico.Content.Web.Mvc_ namespace) to add an appropriate authentication hash to a specified URL.
>
> ```xml
>
> $.ajax({
>   url: '@Url.Kentico().AuthenticateUrl("url")',
>   type: 'get',
>
>   ...
> });
>
> ```

If you use [data caching](https://docs.kentico.com/13/configuring-xperience/configuring-caching/caching-on-mvc-sites.md) with _DocumentQuery_/_MultiDocumentQuery_ for your pages, you need to disable it for preview mode. This ensures that caching works correctly for standard requests, but is not used for the different content displayed in preview mode.

> **Info:** **Preview mode and controller output caching**
>
> If you use caching of controller output in your MVC application ([OutputCache](https://docs.microsoft.com/en-us/dotnet/api/system.web.mvc.outputcacheattribute) attributes), the [Xperience integration package](https://docs.kentico.com/13/developing-websites/starting-with-mvc-development/installing-xperience-integration-packages.md) in your MVC application automatically ensures that the output cache is not used for page requests in preview mode.

The preview mode is now configured for the Xperience application that you use to manage your website's content.

> **Tip:** [Install](https://docs.kentico.com/13/installation/installing-xperience.md) the _Dancing Goat MVC sample site_ to see an advanced example of an MVC application that uses preview mode.
