D20Tek.Blazor.BrowserStorage
1.1.3
dotnet add package D20Tek.Blazor.BrowserStorage --version 1.1.3
NuGet\Install-Package D20Tek.Blazor.BrowserStorage -Version 1.1.3
<PackageReference Include="D20Tek.Blazor.BrowserStorage" Version="1.1.3" />
<PackageVersion Include="D20Tek.Blazor.BrowserStorage" Version="1.1.3" />
<PackageReference Include="D20Tek.Blazor.BrowserStorage" />
paket add D20Tek.Blazor.BrowserStorage --version 1.1.3
#r "nuget: D20Tek.Blazor.BrowserStorage, 1.1.3"
#:package D20Tek.Blazor.BrowserStorage@1.1.3
#addin nuget:?package=D20Tek.Blazor.BrowserStorage&version=1.1.3
#tool nuget:?package=D20Tek.Blazor.BrowserStorage&version=1.1.3
D20Tek.Blazor.BrowserStorage
A modern, lightweight .NET library that provides typed, asynchronous access to the browser's localStorage and sessionStorage APIs for Blazor WebAssembly and client-side render modes. Built using JavaScript interop, this library eliminates the need for manual serialization, raw JS calls, or string-based key management. It offers a clean, strongly-typed C# API with full dependency injection support.
This package was inspired by Blazored.LocalStorage/SessionStorage. Once I realized that it was deprecated and removed from NuGet.org, I needed my own implementation to use across my Blazor apps. While building on the basic functionality, D20Tek.Blazor.BrowserStorage provides additional features and a more modern, flexible API. The most significant difference is that GetAsync<T> returns a StorageResult<T> instead of throwing an exception when a key is not found, allowing for more graceful handling of missing keys.
Table of Contents
- Features
- Supported Platforms
- Installation
- Quick Start Guide
- Usage
- Configuration
- API Reference
- Sample Applications
- Testing
- Migration from Blazored.LocalStorage
- License
Why This Library Exists
Blazor does not provide a built‑in way to access localStorage or sessionStorage from .NET. The only way to use browser storage is to call JavaScript manually through IJSRuntime, which leads to several problems:
- You must write JS interop boilerplate for every read/write.
- Storage access becomes stringly‑typed, error‑prone, and repetitive.
- You have to handle JSON serialization yourself.
- There’s no clean way to expose storage as a typed .NET service.
- Previously used Blazored.LocalStorage package for these purposes, but that has been deprecated and no longer available.
For a framework that encourages strong typing, DI, and clean architecture, browser storage ends up feeling like a low‑level workaround. And this library exists to fix that.
D20Tek.Blazor.BrowserStorage provides:
- A fully typed storage API
- A clean async interface
- Zero‑boilerplate JSON handling
- A simple, DI‑friendly .NET service
- Support for both localStorage and sessionStorage
- A modern API designed for Blazor WebAssembly and Blazor SSR
It gives Blazor developers a first‑class, standard way to use browser storage, without having to touch JavaScript.
Features
- Typed, async API: Read and write any serializable .NET type with generic
GetAsync<T>andSetAsync<T>methods. No manual JSON handling required. - Result-based reads and writes:
GetAsync<T>returns aStorageResult<T>andSetAsync<T>/RemoveAsync/ClearAllAsyncreturn aStorageResult, each with anIsSuccessflag and an optionalErrorMessage. Missing keys, corrupt values, quota-exceeded, and blocked-storage conditions surface as results rather than exceptions. - Availability probing:
IsAvailableAsyncdetects whether browser storage is usable (private mode, disabled site data, quota exhausted) and caches the result. - localStorage and sessionStorage: Full support for both browser storage mechanisms through
ILocalStorageServiceandISessionStorageService. - Bulk operations:
SetMultipleAsyncandRemoveMultipleAsyncextension methods for batch read/write scenarios, with fail-fast semantics that return the first failingStorageResult. - Key prefix namespacing: Configure a prefix string (for example,
"myapp_") that is automatically prepended to all keys, preventing collisions between multiple applications or modules sharing the same origin. - Change notifications: Subscribe to the
Changedevent on either service to receiveStorageChangedEventArgswhenever a value is added, modified, or removed. - Configurable JSON serialization: Provide custom
JsonSerializerOptionsfor scenarios that require specific naming policies, converters, or formatting. - Flexible service lifetimes: Register services as Scoped (default), Singleton, or Transient to match your application's architecture.
- Lightweight and focused: No external dependencies beyond the standard Microsoft.JSInterop and Microsoft.Extensions packages.
Supported Platforms
| Target Framework | Status |
|---|---|
| .NET 9.0 | Supported |
| .NET 10.0 | Supported |
This library is designed for Blazor WebAssembly and Blazor client-side interactive render modes. It is not intended for server-side Blazor (Blazor Server), where Microsoft's built-in ProtectedLocalStorage and ProtectedSessionStorage should be used instead.
Installation
Install the package via the .NET CLI:
dotnet add package D20Tek.Blazor.BrowserStorage
Or via the NuGet Package Manager in Visual Studio:
Install-Package D20Tek.Blazor.BrowserStorage
Quick Start Guide
1. Register services in Program.cs
Register both localStorage and sessionStorage services with a single call:
using D20Tek.Blazor.BrowserStorage;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services.AddBrowserStorage();
await builder.Build().RunAsync();
If you only need one of the two storage types, you can register them individually:
builder.Services.AddLocalStorage();
// or
builder.Services.AddSessionStorage();
2. Inject the service into a component
@inject ILocalStorageService LocalStorage
@inject ISessionStorageService SessionStorage
Or in a code-behind file:
[Inject]
private ILocalStorageService LocalStorage { get; set; } = default!;
3. Read and write values
// Write a value
var writeResult = await LocalStorage.SetAsync("username", "Alice");
if (!writeResult.IsSuccess)
{
// Storage may be full, disabled, or otherwise unavailable.
Console.WriteLine(writeResult.ErrorMessage);
}
// Read a value
var result = await LocalStorage.GetAsync<string>("username");
if (result.IsSuccess)
{
Console.WriteLine(result.Value); // "Alice"
}
Usage and Configuration
For detailed usage instructions covering all storage operations (reading, writing, removing, checking keys, enumerating, bulk operations, and change notifications) as well as configuration options (key prefixing, custom JSON serialization, and service lifetimes), see the Detailed Getting Started Guide.
API Reference
For a complete reference of all public interfaces, methods, events, extension methods, and types, see the API Reference.
Sample Applications
The repository includes two sample Blazor WebAssembly applications that demonstrate the library's features in realistic scenarios:
PreferenceDashboard
A settings and preferences dashboard that uses localStorage to persist visual preferences (theme, accent color, and font family) across browser sessions, and sessionStorage to track dismissal of a "What's New" banner within the current tab.
Features demonstrated: GetAsync<T>, SetAsync<T>, ContainsKeyAsync, ClearAllAsync, key prefix namespacing, and the Changed event.
SampleQuiz
An interactive tech trivia game with 100 questions across .NET, Azure, and Windows categories. The application uses localStorage for persistent data such as player profiles, high scores, and game statistics, and sessionStorage for current quiz state with recovery on page refresh.
Features demonstrated: Complex object serialization, StorageResult<T> for first-time player detection, SetMultipleAsync for batch result saving, RemoveMultipleAsync for session cleanup, GetKeysAsync and LengthAsync for storage statistics, and ClearAllAsync for data reset.
Testing
For unit and component tests, install the companion package D20Tek.Blazor.BrowserStorage.Testing. It ships in-memory implementations of ILocalStorageService and ISessionStorageService plus bUnit BunitContext extensions so you can test components that depend on browser storage without spinning up a real browser or mocking IJSRuntime by hand.
dotnet add package D20Tek.Blazor.BrowserStorage.Testing
using var ctx = new BunitContext();
ctx.AddBrowserStorage(o => o.KeyPrefix = "app_");
ctx.GetLocalStorage().Seed("prefs", new UserPreferences { Theme = "Dark" });
var cut = ctx.Render<PreferencesPanel>();
cut.Find("button.reset").Click();
Assert.False(ctx.GetLocalStorage().Snapshot.ContainsKey("app_prefs"));
See docs/testing.md for the full guide — seeding, Snapshot inspection, availability simulation, and cross-tab Changed event simulation. For the complete list of public types, methods, and extensions in the testing package, see the Testing API Reference.
Migration from Blazored.LocalStorage
If you are migrating from the Blazored.LocalStorage and Blazored.SessionStorage packages, see the Migration Guide for a detailed comparison of methods, return types, and registration patterns.
Used by
Used in my Blazor projects and internal apps.
License
This project is licensed under the MIT License. See the LICENSE file for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.11)
- Microsoft.Extensions.Options (>= 10.0.11)
- Microsoft.JSInterop (>= 10.0.11)
-
net9.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 9.0.12)
- Microsoft.Extensions.Options (>= 9.0.12)
- Microsoft.JSInterop (>= 9.0.12)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on D20Tek.Blazor.BrowserStorage:
| Package | Downloads |
|---|---|
|
D20Tek.Blazor.BrowserStorage.Testing
Testing companion for D20Tek.Blazor.BrowserStorage. Provides in-memory implementations of ILocalStorageService and ISessionStorageService plus bUnit TestContext extensions so Blazor components that depend on browser storage can be unit- and component-tested without a real browser or hand-rolled IJSRuntime fakes. |
GitHub repositories
This package is not used by any popular GitHub repositories.
Initial release with full localStorage and sessionStorage support for Blazor WebAssembly. Includes typed async API, result-based reads, bulk operations, change notifications, key prefixing, and configurable service lifetimes.