---
title: Working with cookies
related:
  - https://docs.kentico.com/13/developing-websites/working-with-cookies/reference-xperience-cookies.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).

A cookie is a small piece of data that a website asks your browser to store on your computer or mobile device. The cookie allows the website to "remember" your actions or preferences over time.

Xperience provides an extensible framework, built around [cookie levels](#cookie-levels), for manipulating cookies – from assigning specific levels of allowed cookies to users and contacts, to [registering custom cookies](#registering-custom-cookies) and their corresponding cookie levels.

## Setting the default cookie level

A site's default cookie level determines which cookies the system stores in users' browsers by default. To set the default cookie level:

1. Open **Settings** application and select the **System** category.
2. Under the Cookies heading, select a **Default cookie level**.
   - For an overview of individual cookie levels, see [Cookie levels](#cookie-levels).
3. Click **Save**.

The system now uses the selected cookie level when evaluating which cookies should be stored in users' browsers.

> **Note:** **_All cookies_ level required for On-line marketing features to work correctly in Xperience**
>
> Xperience [On-line marketing features](https://docs.kentico.com/13/on-line-marketing-features.md) only work fully for visitors who have their cookie level set to **All cookies**.
>
> For example, the system does not track [contacts](https://docs.kentico.com/13/on-line-marketing-features/managing-your-on-line-marketing-features/contact-management/working-with-contacts.md) for visitors whose allowed cookie level is only _System_ or _Essential_. Contacts may still be created in certain cases for visitors without the required cookie level, e.g., if they submit data through a form or subscribe to a newsletter, but such contacts only store the provided data and do not track the visitor.

### Cookie levels

Xperience classifies cookies into several levels according to their purpose. The levels allow you to set cookie levels for users. The following are the default levels available in the cookie API (_CMS.Helpers.CookieLevel_ class):

| Cookie level      | Description                                                                                                                                                                                                                                                                                                                                                                                                              |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **None (-1000)**  | Absolutely no cookies are allowed, including the cookie that stores the cookie level selected for users. This makes sense only if you want to disable absolutely every cookie by default.                                                                                                                                                                                                                                |
| **System (-100)** | This level allows the session cookie, and the _CookieLevel_ cookie used to store the cookie level selected by the user. In terms of the end user and the Cookie law, this means  _**"Cookies are not allowed"**_.                                                                                                                                                                                                        |
| **Essential (0)** | Cookies required for all website functionality needed by site visitors. This includes authentication, language selection, etc. From the visitor's perspective, this means  _**"Allow only cookies that I may need, but do not track me"**_.                                                                                                                                                                              |
| **Editor (100)**  | Cookies required for correct administration interface functionality. For example used to track the selected view mode, remember tabs and sliders, etc.                                                                                                                                                                                                                                                                   |
| **Visitor (200)** | All cookies that are not assigned to an explicit level are considered to be cookies identifying the visitor, i.e. user tracking cookies, which are not really needed, but are useful for the site owner if using Xperience Enterprise marketing features.<br>This level is used for all custom cookies by default. You can [register custom cookies](#registering-custom-cookies) to adjust their assigned cookie level. |
| **All (1000)**    | Allows all cookies, no matter what their level is. From the site visitor's perspective this means  _**"Allow all cookies now and in the future"**_.                                                                                                                                                                                                                                                                      |

The numbers associated with each cookie level are integer constants, which allows you to further customize the granularity of available cookie levels. The levels '_None_' and '_All_' are set to an absolute value of 1000 to provide enough space for future Xperience updates or developer-specified custom levels.

> **Info:** Automatic [tracking of contacts](https://docs.kentico.com/13/on-line-marketing-features/managing-your-on-line-marketing-features/contact-management/working-with-contacts.md) and their [activities](https://docs.kentico.com/13/on-line-marketing-features/managing-your-on-line-marketing-features/contact-management/tracking-contact-activities.md) only works for new visitors if the **Default cookie level** setting is set to '_Visitor_' or '_All_'. For more information, see [Working with consents](https://docs.kentico.com/13/configuring-xperience/data-protection/gdpr-compliance/working-with-consents.md).

> **Info:** **Automatic cookie consent for administrators and editors**
>
> If a user signs in to the Xperience administration interface, cookies are automatically enabled to provide full editing functionality. The system assumes that working in the administration interface identifies the user as staff, so there is no need for cookie consent.

## Registering custom cookies

If your website uses any custom or third-party cookies, we recommend that you register them with an appropriate cookie level. Unregistered cookies are processed with the _Visitor_ level by default.

When a visitor adjusts their allowed cookie level (for example by accepting or revoking a [consent](https://docs.kentico.com/13/configuring-xperience/data-protection/gdpr-compliance/working-with-consents.md)), the system automatically clears all cookies that have a higher level from the visitor's browser. You may also encounter problems with custom or third-party cookies not being stored if your site's **System -> Default cookie level** setting has a lower value than _Visitor_, for example when managing [tracking consent](https://docs.kentico.com/13/configuring-xperience/data-protection/gdpr-compliance/working-with-consents.md).

To register custom cookies, you need to add custom code to your project. Call the **CookieHelper.RegisterCookie** method (available in the **CMS.Helpers** namespace of the Xperience API), with the following parameters:

- **string name** – the name of the cookie that you are registering.
- **int level** – an integer value representing the cookie level required to use the cookie. You can access the default level values in the _CookieLevel_ enumeration.

To ensure that your cookies are recognized correctly, call the _RegisterCookie_ method at the beginning of the application's life cycle – either during the initialization of a [custom module class](https://docs.kentico.com/13/custom-development/creating-custom-modules/initializing-modules-to-run-custom-code.md), or within suitable startup code if you are [using the Xperience API in an external application](https://docs.kentico.com/13/integrating-3rd-party-systems/using-the-xperience-api-externally.md).

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

> **Info:** **Handling cookies in ASP.NET Core**
>
> When setting cookies in ASP.NET Core projects, there is an option to use the [CookieOptions.IsEssential](https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.cookieoptions.isessential?view=aspnetcore-6.0) property.
>
> ```csharp
>
> var cookieOptions = new CookieOptions
> {
>     IsEssential = true
> };
>
> // Adds the cookie to the response cookie collection
> HttpContext.Response.Cookies.Append("cookieName", "cookieValue", cookieOptions);
>
> ```
>
> Cookies that are not registered by the Xperience **CookieHelper** are seen as _Visitor_ level cookies by the Xperience system, but the **CookieOptions.IsEssential** option overrides the system cookie settings as it is handled directly by the framework. As a result, such cookies are always set for visitors, even if they are not registered using the **CookieHelper**.

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

### Example

The following example demonstrates how to register a custom cookie named _CustomCookie_ with the _Essential_ cookie level:

1. Open the Xperience live site project in Visual Studio.
2. Create a [custom module class](https://docs.kentico.com/13/custom-development/creating-custom-modules/initializing-modules-to-run-custom-code.md).
   - We recommend adding the class into a custom _Class Library_ project within the solution.
3. Override the module's **OnInit** method and call the **CookieHelper.RegisterCookie** method.

   ```csharp

   using CMS;

   using CMS.DataEngine;
   using CMS.Helpers;

   // Registers the custom module into the system
   [assembly: RegisterModule(typeof(CustomInitializationModule))]

   public class CustomInitializationModule : Module
   {
       // Module class constructor, the system registers the module under the name "CustomInit"
       public CustomInitializationModule()
           : base("CustomInit")
       {
       }

       // Contains initialization code that is executed when the application starts
       protected override void OnInit()
       {
           base.OnInit();

           // Registers the "CustomCookie" with the 'Essential' cookie level
           // Ensures that the cookie is preserved for visitors who change their allowed cookie level below 'Visitor'
           CookieHelper.RegisterCookie("CustomCookie", CookieLevel.Essential);
       }
   }

   ```

The _CustomCookie_ is now registered and can be used by visitors with the _Essential_ and above cookie level (based on your site's [default cookie level](#setting-the-default-cookie-level), the users' [preferred cookie level](#allowing-users-to-choose-their-preferred-cookie-level), or other custom actions such as [consent agreements](https://docs.kentico.com/13/configuring-xperience/data-protection/gdpr-compliance/working-with-consents.md)).

## Setting cookies

You can use the Xperience API to create and set custom cookies into a user's browser. Call the **CookieHelper.SetValue** method within the scope of an HTTP request:

> **Note:** **CookieHelper.SetValue in hotfix 13.0.165 and newer**
>
> With version 13.0.165, the following overload of the `SetValue` method
>
> ```csharp noheader
> CookieHelper.SetValue(string name, string value, DateTime expires, string path = null, bool? httpOnly = null, string domain = null, SameSiteMode sameSiteMode = SameSiteMode.Lax, bool secure = false)
> ```
>
> was made obsolete and replaced with `SetValue(CookieHelperValueSettingParameters parameters)`. The `CookieHelperValueSettingParameters` object contains the parameters from the obsolete method and can be used identically, with one exception. `CookieHelperValueSettingParameters.Secure` is now nullable and `null` by default, which means Xperience uses the value provided by the framework (`false` in most cases).
>
> <!-- 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.
>
> Additionally, the method and all its overloads now reflect the **requireSSL** _web.config_ attribute on the _httpCookies_ element.
>
> ```xml noheader
> <httpCookies requireSSL="true" />
> ```
>
> In older versions, the _requireSSL_ configuration was suppressed by the optional `secure` attribute of the now-obsolete `SetValue` method, which defaulted to `false` unless explicitly set.
>
> Explicitly configuring `CookieHelperValueSettingParameters.Secure` when setting cookies overrides the _web.config_ value.
>
> <!-- dev-model:mvc end -->

```csharp
using CMS.Helpers;

// Saves a custom cookie named "CustomCookie" to the current visitor's browser,
// with "CustomValue" as its value and an expiration time of 1 year
CookieHelper.SetValue("CustomCookie", "CustomValue", DateTime.Now.AddYears(1));
```

Cookies set using _CookieHelper_ use the **Lax** [SameSite mode](https://docs.kentico.com/13/developing-websites/working-with-cookies/configuring-cookie-samesite-mode.md) by default. To specify a different _SameSite_ mode, add an additional parameter with a value from the **CMS.Base.SameSiteMode** enumeration when setting the cookie:

```csharp
// With hotfix 13.0.164 and older
CookieHelper.SetValue("CustomCookie", "CustomValue", DateTime.Now.AddYears(1), sameSiteMode: SameSiteMode.Strict);

// Adds the Secure attribute to the cookie with 'SameSite=None'. 
// The user agent will include the cookie in an HTTP request only if the request is transmitted over a secure channel (typically HTTPS).
CookieHelper.SetValue("CustomCookie", "CustomValue", DateTime.Now.AddYears(1), sameSiteMode: SameSiteMode.None, secure: true);

// With hotfix 13.0.165 and newer
CookieHelper.SetValue(new CookieHelperValueSettingParameters {
                Name = "CustomCookie",
                Value = "CustomValue",
                Expires = DateTime.Now.AddYears(1),
                SameSiteMode = SameSiteMode.Strict
            });

// Adds the Secure attribute to the cookie with 'SameSite=None'. 
// The user agent will include the cookie in an HTTP request only if the request is transmitted over a secure channel (typically HTTPS).
CookieHelper.SetValue(new CookieHelperValueSettingParameters {
                Name = "CustomCookie",
                Value = "CustomValue",
                Expires = DateTime.Now.AddYears(1),
                SameSiteMode = SameSiteMode.None,
                Secure = true
            });
```

## Allowing users to choose their preferred cookie level

In compliance with the cookie law, you can allow users to select their preferred cookie level. Use the **SetCurrentCookieLevel** method provided by the **ICurrentCookieLevelProvider** service.

The following code snippets demonstrate the usage of the _ICurrentCookieLevelProvider_ API on a basic example. The code allows users to set their preferred cookie level via a simple form.

```csharp title="CookieLevelController.cs"

using System.Web.Mvc;
using System.Collections.Generic;

using CMS.Helpers;

public class CookieLevelController : Controller
{
    private readonly ICurrentCookieLevelProvider cookieLevelService;

    // Initializes instances of required services using dependency injection
    public CookieLevelController(ICurrentCookieLevelProvider cookieLevelService)
    {
        this.cookieLevelService = cookieLevelService;
    }

    public ActionResult Index()
    {
        // Creates a list with the three default levels of cookie compliance relevant for site visitors.
        // The CookieLevel class is used to directly extract integer values corresponding to each cookie level
        // so that no additional mapping is necessary.
        var cookieLevels = new List<object>() {
                new { label = "Essential", value = CookieLevel.Essential },
                new { label = "Visitor", value = CookieLevel.Visitor },
                new { label = "All", value = CookieLevel.All }
            };

        return View(new SelectList(cookieLevels, "value", "label"));
    }

    // Sets the cookie level for the current user
    // The value passed into the action from the corresponding view directly corresponds to one of the system's 
    // cookie levels thanks to the CookieLevel class.
    [HttpPost]
    public ActionResult SetCookieLevel(int SelectedValue)
    {
        // Sets the cookie level for the current user to the level corresponding to the provided value
        cookieLevelService.SetCurrentCookieLevel(SelectedValue);

        return RedirectToAction(nameof(Index));
    }
}

```

The corresponding view contains a drop-down selectors that allows users to select the desired level of cookies.

```xml title="Index.cshtml"

@model SelectList

@using (Html.BeginForm("SetCookieLevel", "CookieLevel", FormMethod.Post))
{
    @Html.DropDownListFor(x => x.SelectedValue, Model)
    <input type="submit" value="Select" />
}


```
