State Persistence Strategies: Using IndexedDB
In this lesson, you will learn how to leverage IndexedDB via Blazor JS Interop to persist your application state, ensuring your users don't lose their progress during a page refresh.
While localStorage is simple, it is limited to string data and synchronous access. For complex objects or larger data sets, IndexedDB is the browser’s built-in, high-performance NoSQL database. Because Blazor runs on the client, we can use JS Interop to bridge the gap between our C# logic and this persistent storage.
The Workflow
To persist state, we treat IndexedDB as an asynchronous store. Whenever our Blazor state changes, we serialize the state to JSON and send it to a small JavaScript helper function that handles the IndexedDB transaction.
Here is how you might structure a basic save operation using IJSRuntime:
// Inside your component or service
private async Task SaveStateAsync(AppState state)
{
var json = JsonSerializer.Serialize(state);
await JS.InvokeVoidAsync("indexedDbHelper.save", "user_prefs", json);
}
private async Task<AppState?> LoadStateAsync()
{
var json = await JS.InvokeAsync<string>("indexedDbHelper.get", "user_prefs");
return json != null ? JsonSerializer.Deserialize<AppState>(json) : null;
}
Why IndexedDB?
Unlike simple key-value storage, IndexedDB allows for structured data indexing and handles much larger payloads. When your Blazor component initializes (perhaps in OnInitializedAsync), you can check this store to "rehydrate" your application state. This creates a seamless experience where a user can refresh their browser and find their input fields, draft content, or UI preferences exactly as they left them.
By encapsulating this in a service injected via the Blazor DI Container, you keep your components clean while ensuring the UI remains responsive. The asynchronous nature of these calls also ensures that your UI thread doesn't hang while the database transaction completes.
Key Takeaway: Use IndexedDB via JS Interop to move beyond simple string-based storage, allowing you to persist complex application state reliably across browser sessions.