What is the easiest way to create and read cookies on Blazor server side.
It seems all the solutions out there is for Blazor Web-assembly, and whenever I use those the Response.Cookies.Append("") and Request.Cookies[] options do not work.
5 Answers
Inside the wwwroot/index.html
(Blazor WebAssembly) or Pages/_Host.cshtml
(Blazor Server), write the following javascript code:
<script>
window.WriteCookie = {
WriteCookie: function (name, value, days) {
var expires;
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toGMTString();
}
else {
expires = "";
}
document.cookie = name + "=" + value + expires + "; path=/";
}
}
window.ReadCookie = {
ReadCookie: function (cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
}
</script>
Then, write the following sample code into the Razor component (.razor):
@inject IJSRuntime JsRuntime;
<button class="btn" @onclick="WriteCookies">
Write Cookie
</button>
<button class="btn" @onclick="ReadCookies">
Read Cookie
</button>
<p>The cookie is @myCookieValue</p>
@code {
public string myCookieValue { get; set; } = "";
protected async Task WriteCookies()
{
await JsRuntime.InvokeAsync<object>("WriteCookie.WriteCookie", "cookieName", "cookieValue", DateTime.Now.AddMinutes(1));
}
protected async Task ReadCookies()
{
myCookieValue= await JsRuntime.InvokeAsync<string>("ReadCookie.ReadCookie", "cookieName");
}
}

- 1,620
- 23
- 37
-
When I tried the code document.cookie always returned empty string inside a component. – panpawel May 06 '21 at 14:57
-
I believe the WriteCookie function's third param takes a C# DateTime so the javascript should look more like "var date = new Date(days);" and omit the "setTime" method. I'd change the "days" variable to "dateTime" as well. – Blackey Dec 06 '22 at 00:21
-
it is don't work – Роман Тимохов Mar 13 '23 at 08:40
I found a great solution to the Blazor Server Side Cookie issue using local storage.
Firstly, grab the NuGet Blazored LocalStorage using the following command:
Install-Package Blazored.LocalStorage
I had to update my System.Text.Json, do this from https://www.nuget.org/packages/System.Text.Json/
Add the following to Startup.cs in:
public void ConfigureServices(IServiceCollection services)
{
services.AddBlazoredLocalStorage(); // local storage
services.AddBlazoredLocalStorage(config =>
config.JsonSerializerOptions.WriteIndented = true); // local storage
}
Or in latest .NET versions
using Blazored.LocalSorage;
var builder = WebApplication.CreateBuilder(args);
// add after builder initialization:
builder.Services.AddBlazoredLocalStorage(); // local storage
builder.Services.AddBlazoredLocalStorage(config => config.JsonSerializerOptions.WriteIndented = true); // local storage
On your Razor page (I used Index.razor to test):
@page "/"
@inject Blazored.LocalStorage.ILocalStorageService localStorage
<button @onclick="HandleSubmit">Create Cookie</button> @* Create your cookie *@
@code{
public async Task HandleSubmit()
{
await localStorage.SetItemAsync("cookieName", "Jason Bourne");
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
var cookieContent = await localStorage.GetItemAsync<string>("cookieName");
if (cookieContent == null)
{
Console.WriteLine("Cookie is blank");
}
else
{
Console.WriteLine("We have a cookie with contents: " + cookieContent);
}
}
}

- 1,308
- 12
- 23

- 265
- 1
- 2
- 7
-
9LocalStorage is not the same as a cookie though. Technically the other answer is the correct answer. – Michael Z. Mar 17 '21 at 04:01
-
2Both option will work only on or after OnAfterRenderAsync, if you want to call before OnAfterRenderAsync, neither will work. – Snekithan Feb 09 '23 at 00:49
No offense to the others, but these answers are probably more complicated than you need them.
You can use JavaScript Interop to do whatever you want client side. That way, you have direct control over everything, instead of relying on libraries or plugins.

- 3,413
- 2
- 11
- 16
-
1Couldn't agree more! No extras ever, stay bareboned as much as you can, and control everything yourself. It is an absolutely critical way to program. It is inevitable to run into issues that you will never be able to fix relying on such things. Only stick to the primary frameworks provided by Microsoft. – user2455808 Mar 29 '23 at 15:12
If you want to access Cookies from Blazor Component you need inject IHttpContextAccessor like below
[Inject]
IHttpContextAccessor HttpContextAccessor { get; set; }
and then you can access Cookies from Request object using the injected HttpContextAccessor
var token = httpContextAccessor.HttpContext.Request.Cookies["access_token"];
To set access token, use:
CookieOptions options = new CookieOptions();
options.Expires = DateTime.Now.AddDays(1);
httpContextAccessor.HttpContext.Response.Cookies.Append("access_token", response.access_token, options);
if you want to access Cookies from Service then you need to add IHttpContextAccessor using dependency injection in constructor of your service as below:
public AccessoryService(HttpClient httpClient,
IHttpContextAccessor HttpContextAccessor)
{
this.httpClient = httpClient;
httpContextAccessor = HttpContextAccessor;
}
pls add services.AddHttpContextAccessor(); on startup for dependency injection.
finally you can call api using the token that retrieve from Request object:
public async Task<IEnumerable<AccessoryDto>> GetAccessories()
{
var token = httpContextAccessor.HttpContext.Request.Cookies["access_token"];
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer",token);
var accessories = await httpClient.GetFromJsonAsync<AccessoryDto[]>("api/accessory");
return accessories;
}

- 5,370
- 1
- 21
- 33
-
4Just a note, to use IHttpContextAccessor you need to inject `services.AddHttpContextAccessor();` on startup. – Lucca Ferri Oct 23 '21 at 04:56
-
-
5How is this code works? Since Blazor server side request are WebSocket based with SignalR. Since it is not HTTP based then `HttpContext` will be NULL as mentioned here https://github.com/dotnet/aspnetcore/issues/18183 – Major Jan 31 '22 at 19:15
-
2You should never use IHttpContextAccessor/HttpContext directly or indirectly in the Razor components of Blazor Server apps. https://learn.microsoft.com/en-us/aspnet/core/fundamentals/http-context?view=aspnetcore-7.0#avoid-ihttpcontextaccessorhttpcontext-in-razor-components – redrobot Mar 17 '23 at 10:02
Using all the above examples. I came up with this
Javascript
const Empty = '';
window.Cookie = {
Read: function () {
return (document.cookie == Empty) ? '[name]=[value]' : decodeURIComponent(document.cookie);
},
Write: function (name, value, days) {
document.cookie = name + '=' + value + this.ExpireOn(days) + ';path=/';
},
ExpireOn: function (days) {
return Number.isFinite(days) ? ';expires=' + new Date().AddDay(days).toGMTString() : Empty;
}
}
Date.prototype.AddDay = function(days) {
this.setDate(this.getDate() + days);
return this;
}
Add cookie.cs
namespace Blazor;
public class Cookie
{
private IDictionary<string, string> _values;
private readonly IJSRuntime _js;
public Cookie(IJSRuntime js) => _js = js;
public async Task<string> Get(string name) => (await Read()).TryGetValue(name, out var val) ? val : string.Empty;
public async Task Set(string name, string val, int? days = null)
{
await Write(name, val, days);
(await Read()).UpSert(name, val);
}
private async Task<IDictionary<string, string>> Read() =>
_values ??= (await _js.InvokeAsync<string>(COOKIE.READ))
.Split(STR.SEMICOLON)
.Select(nv => nv.Split(STR.EQUAL))
.ToDictionary(nv => nv.First().Trim(), nv => nv.Last().Trim());
private async Task Write(string name, string val, int? days) => await _js.InvokeAsync<string>(COOKIE.WRITE, name, val, days);
}
Add Scope
services.AddScoped<Cookie>();
Inject Cookie into component and use it inside OnAfterRenderAsync. Example
protected async override Task OnAfterRenderAsync(bool firstRender)
{
if (!firstRender)
return;
var val = await Cookie.Get(COOKIE.LANG.NAME);
_selectedValue = string.IsNullOrEmpty(val) ? Cache.DefaultLang : val;
_mudSelect?.SelectedValuesChanged.InvokeAsync();
}
This approach can be used with local storage or session storage. You just need to write minimum javascript to read/write it on client side and a wrapper on server side. Cookie.cs can be injected to any component and use as a user data session storage.
IHttpContext Accessor is not the Blazor way. Anything client side should be accessible via IJSRuntime.

- 19
- 1