Local Storage Utility (Cookies) for Blazor WebAssembly App

Here is a local storage utility that relies on dependency injection which means a line of code must be added to the Program.cs file in the Blazor client/WebAssembly app.

Here is example usage of the LocalStorage utility

@page "/localstorage"
@inject Utilities.ILocalStorage LocalStorage

<h3>Local Storage</h3>

<div>
@if (data != null)
{
	foreach (var s in data)
	{
	<p>@s</p>
	}
}
</div>

@code {
	string[] data;

	protected override async Task OnInitializedAsync()
	{
		await base.OnInitializedAsync();
		string[] values = new[] { "token", "username", "email", DateTime.Now.ToString() };

		// save array of user data
		await LocalStorage.SaveStringArrayAsync("user", values);

		// retrieve array of user data
		data = await LocalStorage.GetStringArrayAsync("user");

		// delete user data
		await LocalStorage.RemoveAsync("user");
	}
}

Here is the code for the LocalStorage utility. It relies on no libraries other than those which are included with Blazor WebAssembly.

// LocalStorage.cs
using System.Threading.Tasks;
using Microsoft.JSInterop;

namespace Utilities
{
	public interface ILocalStorage
	{
		/// <summary>
		/// Remove a key from browser local storage.
		/// </summary>
		/// <param name="key">The key previously used to save to local storage.</param>
		public Task RemoveAsync(string key);

		/// <summary>
		/// Save a string value to browser local storage.
		/// </summary>
		/// <param name="key">The key to use to save to and retrieve from local storage.</param>
		/// <param name="value">The string value to save to local storage.</param>
		public Task SaveStringAsync(string key, string value);

		/// <summary>
		/// Get a string value from browser local storage.
		/// </summary>
		/// <param name="key">The key previously used to save to local storage.</param>
		/// <returns>The string previously saved to local storage.</returns>
		public Task<string> GetStringAsync(string key);

		/// <summary>
		/// Save an array of string values to browser local storage.
		/// </summary>
		/// <param name="key">The key previously used to save to local storage.</param>
		/// <param name="values">The array of string values to save to local storage.</param>
		public Task SaveStringArrayAsync(string key, string[] values);

		/// <summary>
		/// Get an array of string values from browser local storage.
		/// </summary>
		/// <param name="key">The key previously used to save to local storage.</param>
		/// <returns>The array of string values previously saved to local storage.</returns>
		public Task<string[]> GetStringArrayAsync(string key);
	}

	public class LocalStorage : ILocalStorage
	{
		private readonly IJSRuntime jsruntime;
		public LocalStorage(IJSRuntime jSRuntime)
		{
			jsruntime = jSRuntime;
		}

		/// <summary>
		/// Remove a key from browser local storage.
		/// </summary>
		/// <param name="key">The key previously used to save to local storage.</param>
		public async Task RemoveAsync(string key)
		{
			await jsruntime.InvokeVoidAsync("localStorage.removeItem", key).ConfigureAwait(false);
		}

		/// <summary>
		/// Save a string value to browser local storage.
		/// </summary>
		/// <param name="key">The key to use to save to and retrieve from local storage.</param>
		/// <param name="value">The string value to save to local storage.</param>
		public async Task SaveStringAsync(string key, string value)
		{
			await jsruntime.InvokeVoidAsync("localStorage.setItem", key, value).ConfigureAwait(false);
		}

		/// <summary>
		/// Get a string value from browser local storage.
		/// </summary>
		/// <param name="key">The key previously used to save to local storage.</param>
		/// <returns>The string previously saved to local storage.</returns>
		public async Task<string> GetStringAsync(string key)
		{
			return await jsruntime.InvokeAsync<string>("localStorage.getItem", key).ConfigureAwait(false);
		}

		/// <summary>
		/// Save an array of string values to browser local storage.
		/// </summary>
		/// <param name="key">The key previously used to save to local storage.</param>
		/// <param name="values">The array of string values to save to local storage.</param>
		public async Task SaveStringArrayAsync(string key, string[] values)
		{
			if (values != null)
				await jsruntime.InvokeVoidAsync("localStorage.setItem", key, string.Join('\0', values)).ConfigureAwait(false);
		}

		/// <summary>
		/// Get an array of string values from browser local storage.
		/// </summary>
		/// <param name="key">The key previously used to save to local storage.</param>
		/// <returns>The array of string values previously saved to local storage.</returns>
		public async Task<string[]> GetStringArrayAsync(string key)
		{
			var data = await jsruntime.InvokeAsync<string>("localStorage.getItem", key).ConfigureAwait(false);
			if (!string.IsNullOrEmpty(data))
				return data.Split('\0');
			return null;
		}
	}
}

The Progam.cs file must be modified as such (just one line of code is added).

// Program.cs
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.DependencyInjection;

namespace BlazorExample.Client
{
	public class Program
	{
		public static async Task Main(string[] args)
		{
			var builder = WebAssemblyHostBuilder.CreateDefault(args);

			// This AddSingleton line of code is for Uilities.LocalStorage to function - notice placement!
			builder.Services.AddSingleton<Utilities.ILocalStorage, Utilities.LocalStorage>();

			builder.RootComponents.Add<App>("app");

			builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

			await builder.Build().RunAsync();
		}
	}
}

Coding Video

https://youtu.be/qrVJegfOt68