---
title: Identifying pages based on URL parameters
related:
  - https://docs.kentico.com/13/developing-websites/implementing-routing.md
  - https://docs.kentico.com/13/developing-websites/implementing-routing/custom-routing-using-url-patterns.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).

When using the [custom routing scheme](https://docs.kentico.com/13/developing-websites/implementing-routing/custom-routing-using-url-patterns.md), you can give content editors control over a part of the page URL by adding parameters into URL patterns. This allows you to include suitable human-readable keywords in URLs, and improve the site's [SEO](https://en.wikipedia.org/wiki/Search_engine_optimization).

By default, pages in Xperience provide a [page alias](#setting-page-aliases) field for this purpose. The system automatically defines a page alias for every page, typically as a URL-safe version of its name in the content tree. Internally, the page alias is stored in the _NodeAlias_ field (column) of each page and you can retrieve it using the _{%NodeAlias%}_ macro expression (for example when [specifying URL patterns of page types](https://docs.kentico.com/13/developing-websites/implementing-routing/custom-routing-using-url-patterns.md)).

Since page aliases are controlled by content editors, they can change over time. Also, page aliases are only guaranteed to be unique within a given sub-section level of the content tree (under the same parent page). For example, only pages stored directly in the _/Articles_ section will have a unique page alias among each other. However, if one page is stored under _/Articles/March_ and another page is stored under _/Articles/May_, they can both have the same page alias. This is why you may not want to use page aliases as the only identifier when displaying pages.

The  **recommended practice**  for identifying pages with a page alias value in the URL is to combine it with another unique identifier, such as the  **NodeGUID** . This ensures that conflicts cannot occur and URLs remain valid even if a page's alias changes.

_NodeGUID_ values provide more stable URLs and links than _NodeIDs_, which may differ when hosting the same website on multiple instances (for example in environments that use [content staging](https://docs.kentico.com/13/deploying-websites/content-staging.md)).

Typically, a page alias is inserted into the [URL pattern](https://docs.kentico.com/13/developing-websites/implementing-routing/custom-routing-using-url-patterns.md) of a page type using a macro expression. For example, a URL pattern could look like the following: _/Articles/{%NodeGUID%}/{%NodeAlias%}_

### Setting page aliases

Usually, the page alias is something that describes the given content. One of the motivations for using page aliases to identify pages is to improve the site's [SEO](https://en.wikipedia.org/wiki/Search_engine_optimization).

Aliases build the _alias path_ of each page, which contains all parent pages up to the root of the site's content tree. For example, if you set a page's alias to _Media_, then the URL is: _//Media_

To define the page alias for pages:

1. Open the **Pages** application.
2. Select the page for which you want to define a page alias.
3. Open the **Properties -> General** tab **-> Advanced** section.
4. Enter a page alias into the **Page alias** field.
5. Click **Save**.

The page now uses the defined page alias as its identifier.

> **Tip:** **Tip**: You can also make pages available under any number of alternative URLs. While page aliases can affect the main URL of a page, alternative URLs can give you even more flexibility when it comes to providing short and relevant-looking links. For more information, see [Managing page URLs](https://docs.kentico.com/13/managing-website-content/working-with-pages/managing-page-urls.md).

### Identifying multilingual content when using page aliases

Page aliases remain the same for pages in different cultures. To distinguish pages in different cultures, you can include a language prefix in your URL patterns (for example using the _{%DocumentCulture%}_ macro), or create a custom page type field and use it instead of the page alias.

## Displaying pages based on a page alias

The following example shows how you can configure your MVC application to display articles that have a URL containing a page alias parameter, without any additional identifiers.

1. In your application's _RouteConfig.cs_ file, create a route for accessing articles based on a page alias. For example:

   ```csharp

   public class RouteConfig
   {
       public static void RegisterRoutes(RouteCollection routes)
       {
       ...
           // Maps a custom route that displays an article based on a provided page alias
           route = routes.MapRoute(
               name: "ArticleByPageAlias",
               url: "{culture}/Articles/{pageAlias}",
               defaults: new { culture = new SiteCultureConstraint(), controller = "Articles", action = "ShowByPageAlias" }
           );
       ...
       }
   };

   ```
2. Create a view model for your page type. For example:

   ```csharp

   // Encapsulates data that is sent to associated views
   public class ArticleViewModel
   {
       public string Title { get; set; }
       public string Summary { get; set; }
       public string Text { get; set; }
       public DocumentAttachment Teaser { get; set; }
       public string NodeAlias { get; set; }
       public string Url { get; set; }

       // Creates a view model instance for a given Article
       public static ArticleViewModel GetViewModel(Article article, IPageUrlRetriever pageUrlRetriever)
       {
           return new ArticleViewModel
           {
               PublicationDate = article.PublicationDate,
               RelatedArticles = article.Fields.RelatedArticles.OfType<Article>().Select(related => GetViewModel(related, pageUrlRetriever)),
               Summary = article.Fields.Summary,
               Teaser = article.Fields.Teaser,
               Text = article.Fields.Text,
               Title = article.Fields.Title,
               Url = pageUrlRetriever.Retrieve(article).RelativePath
           };
       }
   }

   ```
3. Retrieve articles based on a page alias. For example using the repository pattern:

   ```csharp

   public interface IArticleRepository
   {
   ...
       /// <summary>
       /// Returns the article with the specified page alias.
       /// </summary>
       /// <param name="pageAlias">The article page alias.</param>
       /// <returns>The article with the specified page alias, if found; otherwise, null.</returns>
       Article GetArticle(string pageAlias);
   ...
   }

   ```

   ```csharp

   public class ArticleRepository : IArticleRepository
   {
   ...
       /// <summary>
       /// Returns the article with the specified page alias. Uses a generated page type provider for the Article page type.
       /// </summary>
       /// <param name="pageAlias">The article page alias.</param>
       /// <returns>The article with the specified page alias, if found. Null otherwise.</returns>
       public Article GetArticle(string pageAlias)
       {
           return new DocumentQuery<Article>()
               .OnSite(mSiteName)
               .Culture(mCultureName)
               .WhereEquals("NodeAlias", pageAlias)
               .LatestVersion(mLatestVersionEnabled)
               .FirstOrDefault();
       }
   ...
   }

   ```
4. Add a controller action for retrieving articles based on a page alias.

   ```csharp

   public class ArticlesController : Controller
   {
       private readonly IPageUrlRetriever pageUrlRetriever;

       public ArticlesController(IPageUrlRetriever pageUrlRetriever)
       {
           this.pageUrlRetriever = pageUrlRetriever;
       }

   ...

       // GET: Articles/{pageAlias}
       public ActionResult ShowByPageAlias(string pageAlias)
       {
           // Retrieves an article based on the provided page alias
           var article = mArticleRepository.GetArticle(pageAlias);
           if (article == null)
           {
               return HttpNotFound();
           }

           // Constructs a view model and sends it to a related view
           return View("Show", ArticleViewModel.GetViewModel(article, pageUrlRetriever));
       }
   ...
   }

   ```
5. Display links to articles in views:

   ```csharp

   <a href="@Url.Content(Model.Url)">@article.Title </a>

   ```

## Displaying pages based on NodeGUID and a page alias

If you use both a _NodeGUID_ and page alias parameter in your URLs, use the _NodeGUID_ identifier to retrieve specific pages in your code. The [generated page type code](https://docs.kentico.com/13/developing-websites/generating-classes-for-xperience-objects.md) provides the required method by default.

```csharp

public static DocumentQuery<Article> GetArticle(Guid nodeGuid, string cultureName, string siteName)
{
    return new DocumentQuery<Article>().OnSite(siteName).Culture(cultureName).WhereEquals("NodeGUID", nodeGuid);
}

```

For URLs that only contain a page alias parameter (_NodeAlias_), you need to make sure the page alias is always unique. You can, to a certain degree, ensure this uniqueness by limiting how content editors are allowed to create new pages:

- [Allowed page type restrictions](https://docs.kentico.com/13/developing-websites/defining-website-content-structure/managing-page-types/limiting-the-pages-users-can-create.md#allowing-users-to-place-certain-pages-under-a-page-type) – by defining which page types users can place under the current page type.
- [Page scope restrictions](https://docs.kentico.com/13/developing-websites/defining-website-content-structure/managing-page-types/limiting-the-pages-users-can-create.md#specifying-which-pages-users-can-create-under-certain-paths) – by specifying which page types users can use when creating new pages under specified paths.

To retrieve pages using only the page alias:

```csharp

public static DocumentQuery<Article> GetArticle(string pageAlias, string cultureName, string siteName)
{
    return new DocumentQuery<Article>().WhereEquals("NodeAlias", pageAlias).OnSite(siteName).Culture(cultureName).TopN(1);
}

```

You can also use the full _NodeAliasPath_ to retrieve pages (for example _/Articles/March/On-Roasts_ for an article named _On Roasts_). This approach can be useful in scenarios where you have a highly structured content tree, and can build the alias path in your code according to other URL parameters.

```csharp

public static DocumentQuery<Article> GetArticle(string nodeAliasPath, string cultureName, string siteName)
{
    return new DocumentQuery<Article>().OnSite(siteName).Culture(cultureName).Path(nodeAliasPath);
}

```

See also: [Displaying page content](https://docs.kentico.com/13/developing-websites/retrieving-content/displaying-page-content.md)
