---
title: Retrieve page content
related:
  - https://docs.kentico.com/documentation/developers-and-admins/api/content-item-api/content-item-query-api.md
  - https://docs.kentico.com/documentation/developers-and-admins/api/content-item-api/reference-content-item-query.md
  - https://docs.kentico.com/documentation/developers-and-admins/development/caching/data-caching.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).

Web page content is stored in the database and [edited](https://docs.kentico.com/documentation/business-users/website-content.md) through the administration interface using the content tree in [website channel applications](https://docs.kentico.com/documentation/business-users/website-content/edit-and-publish-pages.md).

Xperience by Kentico provides the [ContentRetriever API](https://docs.kentico.com/documentation/developers-and-admins/api/content-item-api/content-retriever-api.md) as the primary and recommended approach for retrieving page content. This API simplifies content retrieval with built-in caching, context awareness, and optimized performance.

The ContentRetriever API works with:

- [Generated content type classes](https://docs.kentico.com/documentation/developers-and-admins/api/generate-code-files-for-system-objects.md) – classes generated by the system that allow you to work with [content type](https://docs.kentico.com/documentation/developers-and-admins/development/content-types.md) fields using strongly-typed objects. These classes also allow access to all general page data (page title, ID, GUID, creation date, publish date, etc.).
- Custom data transfer objects (advanced use case) – using custom DTOs grants you control over the mapping logic. See [Custom model mapping](https://docs.kentico.com/documentation/developers-and-admins/api/content-item-api/content-retriever-api.md#custom-model-mapping).

You can also use:

- [Parameter objects for configuring retrieval behavior](https://docs.kentico.com/documentation/developers-and-admins/api/content-item-api/content-retriever-api.md#configurable-retrieval-behavior) (language, caching, security, etc.)
- [Optional query configuration for advanced scenarios](https://docs.kentico.com/documentation/developers-and-admins/api/content-item-api/content-retriever-api.md#optional-query-configuration)

The implementation and complexity of the retrieval and management code depend on your preferences and project requirements, and can range from simple method calls within controller actions to custom solutions utilizing repository and service patterns. Install the [sample Dancing Goat](https://docs.kentico.com/documentation/developers-and-admins/installation.md#available-project-templates) project to view a reference implementation.

## Retrieve page data

To retrieve web page content, use the `IContentRetriever` service from the `Kentico.Content.Web.Mvc` namespace:

The service provides built-in caching, channel context awareness, and optimal retrieval performance. You can use the `IContentRetriever` to [Retrieve the current page](https://docs.kentico.com/documentation/developers-and-admins/api/content-item-api/reference-content-retriever-api.md#retrieve-the-current-page), [Retrieve pages of a single content type](https://docs.kentico.com/documentation/developers-and-admins/api/content-item-api/reference-content-retriever-api.md#retrieve-pages-of-a-single-content-type), and more. See [Reference - ContentRetriever API](https://docs.kentico.com/documentation/developers-and-admins/api/content-item-api/reference-content-retriever-api.md#page-queries) for a list of all available methods.

```csharp title="Sample page retrieval"
using System;
using System.Threading.Tasks;

using CMS.Websites;
using Kentico.Content.Web.Mvc;

// IContentRetriever service obtained via constructor dependency injection
public class CustomComponent(IContentRetriever contentRetriever)
{
    public async Task PageRetrieval()
    {
        // Retrieves pages of the 'ArticlePage' content type from the /Articles section
        var pages = await contentRetriever.RetrievePages<ArticlePage>(
            new RetrievePagesParameters
            {
                PathMatch = PathMatch.Children("/Articles"),
            });

        // Displays the page data
        foreach (var page in pages)
        {
            Console.WriteLine(page.ArticleTitle);
            Console.WriteLine(page.ArticlePageSummary);
        }
    }
}
```

For scenarios requiring advanced query customization, you can use the [content item query API](https://docs.kentico.com/documentation/developers-and-admins/api/content-item-api/content-item-query-api.md):

- `ContentItemQueryBuilder` class with the `ForWebsite` query parametrization method – to create and parametrize custom queries specifically for retrieving website data.
- `IContentQueryExecutor` interface and its `GetMappedWebPageResult` method – to execute custom queries and map the results to model classes.

### Retrieve multilingual page data

To retrieve web page content in a specific language using the `IContentRetriever`, specify the desired language when calling the retrieval methods by providing them with a `RetrievePagesParameters` object with the `LanguageName` property set. If you omit the language, the method will return results in the [primary language](https://docs.kentico.com/documentation/developers-and-admins/configuration/languages.md#set-up-a-new-language) of the website channel.

```csharp title="Sample multilingual page retrieval"
using Kentico.Content.Web.Mvc;

// ...

// Retrieves pages in the Spanish language
var pages = await contentRetriever.RetrievePages<ArticlePage>(
    new RetrievePagesParameters { LanguageName = "es" }
);
```

> **Info:** **Pages in fallback language**
>
> If the desired language variant of a page doesn't exist, the query returns the page data in the [fallback language](https://docs.kentico.com/documentation/developers-and-admins/configuration/languages.md), if fallbacks are configured and unless the `UseLanguageFallbacks` property of the `RetrievePagesParameters` object is explicitly set as `false`.

### Filter pages based on content tree structure

You can set the query to only include pages from a certain section of the content tree or omit pages from a section using the `PathMatch` property of the `RetrievePagesParameters` object. PathMatch expressions can be combined to more accurately specify what pages are included in the query.

- `Single` – only retrieves a single page that corresponds to the specified tree path.
  - E.g., `PathMatch.Single(path: "/Articles/Coffee_processing_techniques")`
- `Children` – recursively retrieves all children of a specified parent page, excluding the parent page from the query. You can also specify a nesting level to limit the depth of recursion.
  - E.g., `PathMatch.Children(path: "/Articles", nestingLevel: 3)`
- `SkipChildren` – recursively exclude all children of a specified parent page from the query, except for the parent page. You can also specify a nesting level to limit the depth of recursion.
  - E.g., `PathMatch.SkipChildren(path: "/Articles/Coffee", nestingLevel: 3)`
- `Section` – recursively retrieves all children of a specified parent page, including the parent page in the query. You can also specify a nesting level to limit the depth of recursion.
  - E.g., `PathMatch.Section(path: "/Articles", nestingLevel: 3)`
- `SkipSection` – recursively exclude all children and the specified parent page from the query. You can also specify a nesting level to limit the depth of recursion.
  - E.g., `PathMatch.SkipSection(path: "Articles/Coffee", nestingLevel: 3)`

> **Tip:** **Combine PathMatch expressions**
>
> If you need to combine multiple `PathMatch` expressions, use [content item query](https://docs.kentico.com/documentation/developers-and-admins/api/content-item-api/content-item-query-api.md) and pass an array as the argument to the `ForWebsite` method.
>
> ```csharp title="Example - Combine PathMatch expressions"
> using CMS.ContentEngine;
> using CMS.Websites;
>
> // ...
>
> var builder = new ContentItemQueryBuilder()
>                     .ForContentType(
>                         "My.ArticlePage",
>                         config => config
>                             .ForWebsite(
>                                 websiteChannelName: "MyWebsiteChannel",
>                                 pathMatches: new PathMatch[]{
>                                     PathMatch.Children("/Articles"),
>                                     PathMatch.SkipSection("/Articles/Coffee_processing_techniques")
>                                 }
>                             )
>                     );
> ```

### Filter pages based on tags

You can limit the retrieval to only retrieve pages with the specified tags using the `additionalQueryConfiguration` parameter with the `Where` method and its `WhereContainsTags` condition:

```csharp title="Example - Filter by tags"
using CMS.ContentEngine;
using CMS.Websites;

using Kentico.Content.Web.Mvc;

// ...

// Retrieves pages that contain both "coffee" and "processing" tags
var pages = await contentRetriever.RetrievePages<ArticlePage>(
    new RetrievePagesParameters 
    { 
        PathMatch = PathMatch.Children("/Articles") 
    },
    query => query.Where(where => where.WhereContainsTags("coffee", "processing")),
    new RetrievalCacheSettings(cacheItemNameSuffix:
        $"{nameof(WhereParameters.Where)}|{nameof(WhereParameters.WhereContainsTags)}|coffee|processing"));
```

See [Retrieve content items](https://docs.kentico.com/documentation/developers-and-admins/development/content-retrieval/retrieve-content-items.md#filter-content-items-based-on-tags) for more information on working with tags.

### Page security configuration

Pages can be [secured](https://docs.kentico.com/documentation/business-users/website-content/secure-pages.md) using a three-tier content access model. Depending on the access settings configured for a page, the system determines whether the visitor is allowed to view the content:

- **Public** – the page is accessible to all visitors without restrictions.
- **Secured** – the page requires the visitor to be an [authenticated member](https://docs.kentico.com/documentation/developers-and-admins/development/registration-and-authentication.md).
- **Secured with member roles** – the page requires the visitor to be an authenticated member who belongs to at least one of the designated [member roles](https://docs.kentico.com/documentation/developers-and-admins/development/registration-and-authentication/member-roles.md).

By default, the `IContentRetriever` does not include secured pages in the query results. You can change this behavior by setting the `IncludeSecuredItems` property of the `RetrievePagesParameters` object to `true`:

```csharp title="Example - Include secured pages"
using Kentico.Content.Web.Mvc;

// ...

var pages = await contentRetriever.RetrievePages<ArticlePage>(
    new RetrievePagesParameters 
    { 
        IncludeSecuredItems = true // Includes secured pages in the results
    });
```

#### Check access with HasAccess

The `HasAccess` extension method on `IContentItemFieldsSource` is the recommended way to check whether a visitor has access to a retrieved content item. The method evaluates the page's security state, the visitor's authentication status, and the visitor's member role assignments in a single call:

```csharp title="Example - Check access using HasAccess"
using Kentico.Content.Web.Mvc;

// ...

// Retrieves secured pages
var pages = await contentRetriever.RetrievePages<ArticlePage>(
    new RetrievePagesParameters 
    { 
        IncludeSecuredItems = true
    });

foreach (var page in pages)
{
    // Checks if the current visitor has access to the page
    bool canAccess = page.HasAccess(HttpContext.User);
}
```

`HasAccess` returns `true` if:

- The page is not secured (public).
- The page is secured and the visitor is authenticated (when no specific member roles are required).
- The page is secured with member roles and the visitor is authenticated **and** belongs to at least one of the required roles.

You can use the result to conditionally display content in Razor views:

```cshtml title="Reflect page security in views"
@using Kentico.Content.Web.Mvc

@if (Model.Page.HasAccess(User))
{
    <p>@Model.PageContent</p>
}
else if (User.Identity.IsAuthenticated)
{
    <p>
        You do not have the required member role to view this page.
    </p>
}
else
{
    <p>
        Sign in to view this page.
    </p>
}
```

> **Info:** **Additional security properties**
>
> The secured state of a retrieved page is available through `page.SystemFields.ContentItemIsSecured`. To see which member roles are required for a secured page, access `page.SystemFields.ContentItemRequiredMemberRoleNames`, which returns an `IReadOnlyCollection<string>` of role code names. For unsecured pages, the collection is empty.

#### Authentication and authorization responses

When a visitor requests a secured page that they are not allowed to view, the system distinguishes between _Not authenticated_ and _Forbidden_ responses based on visitor state. See [Authentication and authorization responses](https://docs.kentico.com/documentation/developers-and-admins/development/registration-and-authentication.md#authentication-and-authorization-responses) for details.

## Work with retrieved page data

You can access various types of data from retrieved page objects:

- Content type fields – the data that is editable in a page's _Content_ view mode. The set of available fields is configurable via the [field editor](https://docs.kentico.com/documentation/developers-and-admins/customization/field-editor.md).
- System fields – available under the `SystemFields` property of the retrieved page objects. Access `WebPage*` fields for web page data and `ContentItem*` for data of the underlying content item.
- Page URL – see [Retrieve page URLs](https://docs.kentico.com/documentation/developers-and-admins/development/content-retrieval/retrieve-page-content/retrieve-page-urls.md).

```csharp title="Access page data"
using Kentico.Content.Web.Mvc;

// ...

// Retrieves a page
var page = await contentRetriever.RetrievePages<ArticlePage>();

// Accesses the ID of the parent
var parentId = page.SystemFields.WebPageItemParentID;

// Accesses the code name of the page object
var pageName = page.SystemFields.WebPageItemName;
```

### Access page field data

The fields available in a page's _Content_ view mode are specific to its [content type](https://docs.kentico.com/documentation/developers-and-admins/development/content-types.md). You can see the fields that each content type uses:

- In **Content types** (application) → edit a content type → **Fields** tab
- In the corresponding _\__ database table

You can access specific fields of a content type directly using strongly typed properties when using [generated content type classes](https://docs.kentico.com/documentation/developers-and-admins/api/generate-code-files-for-system-objects.md):

```csharp title="Access content type fields"
using Kentico.Content.Web.Mvc;

// ...

// Retrieves a page
var page = await contentRetriever.RetrievePages<ArticlePage>();

// Accesses the 'Text' field of the page
var pageText = page.ArticlePageText;

// Accesses the 'Teaser' field of the page
var pageImage = page.ArticlePageTeaser.FirstOrDefault();
```

> **Note:** **Resolving HTML tags and relative URLs**
>
> Fields which are populated by the **Rich text editor** form component may contain HTML tags and relative links. To ensure that the content is displayed correctly when rendered in Razor views, use the `Html.Raw` method, which disables HTML encoding for the values.
>
> ```cshtml
> @Html.Raw(Model.<RichTextFieldProperty>)
> ```

> **Info:** **Automatic URL resolving**
>
> The system provides page output filtering functionality that automatically resolves all virtual relative URLs to their absolute form. This filter ensures that links added by content editors into page content work correctly, even if you do not explicitly handle URL resolving in your code.

### Date and time fields

`DateTime` fields and system properties of retrieved pages always have values in the time zone of the server where the application is running. If you wish to display values in a different time zone (e.g., in a website visitor's local time), perform a [time conversion](https://learn.microsoft.com/en-us/dotnet/standard/datetime/converting-between-time-zones)  using the standard .NET API.

## Access context of the current request

Xperience by Kentico provides interfaces that help you access information about the current context.

### Access context of the current channel

To retrieve information about the website channel context of the current request, use an instance of the `IWebsiteChannelContext` interface (e.g., obtained via [dependency injection](https://docs.kentico.com/documentation/developers-and-admins/development/website-development-basics/dependency-injection.md))  from the `CMS.Websites.Routing` namespace.

Access the following properties:

- `WebsiteChannelID` – the ID of the current website channel.
- `WebsiteChannelName` – code name of the current website channel.
- `IsPreview` – a boolean value that, if `true`, signifies whether the current request is made in preview (Page Builder or the preview mode in a website channel application).

### Access current preferred language

To retrieve the preferred language of the current request, use the `Get` method of the `IPreferredLanguageRetriever` interface (e.g., obtained via [dependency injection](https://docs.kentico.com/documentation/developers-and-admins/development/website-development-basics/dependency-injection.md)).

Note that the preferred language of the request can be different from the actual language of the retrieved content. For example, if language variant of a page does not exist in the preferred language, [fallback](https://docs.kentico.com/documentation/developers-and-admins/configuration/languages.md) language variant is retrieved.

```csharp title="Retrieve currently preferred language"
using System.Threading.Tasks;

using Kentico.Content.Web.Mvc.Routing;

// IPreferredLanguageRetriever service obtained via constructor dependency injection
public class CustomComponent(IPreferredLanguageRetriever preferredLanguageRetriever)
{
    public async Task LanguageRetrieval()
    {
        // Retrieves the code name of the preferred language
        string languageName = preferredLanguageRetriever.Get();
    }
}
```

## Retrieve pages for preview

The ContentRetriever API automatically handles preview context, retrieving the appropriate page versions based on the current request context:

- For the live site, retrieves published versions according to security claims
- For preview and builders, retrieves the latest available version regardless of workflow state or security

You can use the `IsForPreview` parameter of the `RetrievePagesParameters` object to force either only preview or only live data.

```csharp title="Always retrieve latest data"
using Kentico.Content.Web.Mvc;

// ...

var pages = await contentRetriever.RetrievePages<ArticlePage>(
    new RetrievePagesParameters 
    { 
        IsForPreview = true // Force retrieval of preview data
    });
```

### Add preview context to URLs

You may encounter problems in Preview mode on pages that send requests to a custom API endpoint, which uses `IWebsiteChannelContext` to [access the current channel](#access-context-of-the-current-channel) in its implementation. To ensure that such endpoints work correctly in Preview mode, you need to add preview context data to the endpoint URL.

```cshtml title="Example"
@using Kentico.Content.Web.Mvc

const endpointUrl = @Url.Kentico().ApplyPreviewContext("url");
```

The `ApplyPreviewContext` Razor extension method adds various parameters to the endpoint URL, which ensure that `IWebsiteChannelContext` is able to identify the channel, where the previewed page belongs, regardless of the domain used to access the admin UI.

## Retrieve folders

To retrieve the folders from the content tree of a website channel (e.g., to create a page under the folder), use the `Retrieve` method of the `IWebPageFolderRetriever` interface (e.g., obtained via [dependency injection](https://docs.kentico.com/documentation/developers-and-admins/development/website-development-basics/dependency-injection.md)).

```csharp title="Retrieve folders"
using System.Linq;
using System.Threading.Tasks;

using CMS.Websites;
using CMS.Websites.Routing;

// Services obtained via constructor dependency injection
public class CustomComponent(IWebPageFolderRetriever folderRetriever, IWebsiteChannelContext channelContext)
{
    public async Task FolderRetrieval()
    {
        // Retrieves a folder from the specified path
        WebPageFolder folder = (await folderRetriever.Retrieve(
            channelContext.WebsiteChannelName, PathMatch.Children("/Articles"))).FirstOrDefault();

        // Use the WebPageFolder object to access information about the folder
        int id = folder.ContentItemID;
    }
}
```
