Store Data of Your Blazor App in the Local Storage and in the Session Storage
To store local data, today’s browsers support a local storage and a session storage. The difference between the two is that the session storage is only available per tab, and the stored data is deleted once you close the tab with the application. The local storage on the other side stores data across sessions. Even when you close the browser and when you re-open it again, the data of the local storage is still there. It will be there as long until you delete it.
So, the difference between the two is how long the data is stored. Beside that, they work exactly the same. Both can store key/value pairs, and those key/value pairs are stored in plain text.
In this blog post, let’s look at how to use the local storage and the session storage in your Blazor App.
In the first Blazor versions, you had to use JavaScript Interop to add or remove key/value pairs from the local storage or from the session storage. By default, both storages store the data in plain text, and a user can open the developer tools of their browser to view the data. This means that if you want to store sensible data, you have to protect it.
To help you with all of this, Microsoft released a preview of the NuGet package Microsoft.AspNetCore.ProtectedBrowserStorage that helps you to store protected data in the local storage and also in the session storage. With the release candidate of .NET 5.0, they renamed the NuGet package to Microsoft.AspNetCore.Components.ProtectedBrowserStorage, and with the release of .NET 5.0, they included the functionality directly in .NET 5.0.
But note: That functionality relies on ASP.NET Core data protection, which is only available on the server, but not in the client. This means for you that you can use it in a Blazor Server App, but not in a Blazor WebAssembly App (see also this GitHub issue here and here the official docs)
That means for you: If you want to use the classes from Microsoft in your Blazor Server app to store data in the local storage or in the session storage, you don’t have to add a reference to a NuGet package. Everything is already available by default in your Blazor Server app. Let’s look at this.
How to Use the Local Storage
Let’s create a brand-new Blazor Server App with .NET 5.0. Replace the code in the Index.razor file with the code that you see in the following code snippet. Note at the top the using directive for the namespace Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
. This namespace contains the ProtectedLocalStorage
class that gets injected into the index component with the @inject
directive. The instance is stored in a BrowserStorage
property.
The component contains an input field and three buttons to save, read, and delete the the data of that input field to/from the local storage. In the code block you can see in the Save
method how the method SetAsync
is used to store the string from the input field under the key name
in the local storage. In the Read
method the GetAsync
method is used to read the value of the name
key from the local storage. In the Delete
method, the key name
and its value are deleted from the local storage.
@page "/"
@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage
@inject ProtectedLocalStorage BrowserStorage
<h1>Local Storage!</h1>
<input class="form-control" @bind="currentInputValue" />
<button class="btn btn-secondary" @onclick="Save">Save</button>
<button class="btn btn-secondary" @onclick="Read">Read</button>
<button class="btn btn-secondary" @onclick="Delete">Delete</button>
@code {
string currentInputValue;
public async Task Save()
{
await BrowserStorage.SetAsync("name", currentInputValue);
}
public async Task Read()
{
var result = await BrowserStorage.GetAsync<string>("name");
currentInputValue = result.Success ? result.Value : "";
}
public async Task Delete()
{
await BrowserStorage.DeleteAsync("name");
}
}
That’s it. So, add the above to the Index.razor file of a new Blazor Server app, and then run the application. Enter something into the input field and click the Save button. In the screenshot below I entered the text Thomas, I clicked the Save button, and then I opened the developer tools. Under the Application tab you can see the local storage and also the session storage. As you can see, in the local storage under the key name the value Thomas is stored. But you can’t see that it’s the value Thomas, as it is protected. Now, when you remove the text from the input field and when you click the Read button, the value Thomas is read from the local storage, and the input field will display it again. Also close the browser and start the application again, then you’ll see that the data in the local storage is still there, and you can click the Read button to read it into the input field.
How to Use the Session Storage
Using the Session Storage works exactly the same way. Just take the code snippet from above, and instead of injecting the ProtectedLocalStorage
class, you inject the ProtectedSessionStorage
class:
@inject ProtectedSessionStorage BrowserStorage
That’s it! Both classes have the same public APIs, as they both inherit from the base class ProtectdBrowserStorage
. That base class defines the methods SetAsync
, GetAsync
, and DeleteAsync
.
Behind the scences, JavaScript Interop is used to access the browser’s storage. When you look for example at the constructor of the ProtectedLocalStorage
class, you can see that it has an IJSRuntime
parameter:
public ProtectedLocalStorage(IJSRuntime jsRuntime, IDataProtectionProvider dataProtectionProvider);
Luckily all these constructor parameters are injected for you when you use Blazor’s dependency injection with the @inject
directive like we did in this blog post.
Use Browser Storage in Blazor WebAssembly
As mentioned, in Blazor WebAssembly you can’t use those classes to access the local storage and the session storage, as they depend on ASP.NET Core data protection, which is a server-side technology.
In Blazor WebAssebmly, you have to use JavaScript Interop – or you can reference a third-party NuGet package that wraps that JavaScript Interop code for you.
In the following code snippet I use the IJSRuntime
to access the localStorage
JavaScript API of the browser to store data. You can create a new Blazor WebAssembly app and you can replace the code of your Index.razor component with the following code to play around with it. The following code would also work in a Blazor Server app.
@page "/"
@inject IJSRuntime JSRuntime
<h1>Local Storage!</h1>
<input class="form-control" @bind="currentInputValue" />
<button class="btn btn-secondary" @onclick="Save">Save</button>
<button class="btn btn-secondary" @onclick="Read">Read</button>
<button class="btn btn-secondary" @onclick="Delete">Delete</button>
@code {
string currentInputValue;
public async Task Save()
{
await JSRuntime.InvokeVoidAsync("localStorage.setItem", "name", currentInputValue);
}
public async Task Read()
{
currentInputValue = await JSRuntime.InvokeAsync<string>("localStorage.getItem", "name");
}
public async Task Delete()
{
await JSRuntime.InvokeAsync<string>("localStorage.removeItem", "name");
}
}
Note that the code snippet above does not protect your data. In the screenshot below you can see that the value Thomas is visibile in plain text in the developer tools of the browser. Be aware of this. Depending on the data that you are storing in the local storage, this can be a problem or not.
Of course, you can wrap the JavaScript Interop code to access the local storage for example in a service class that you inject into your Blazor component. If you want to learn how to do this and if you want to learn more about JavaScript Interop in Blazor applications, please take a look at my Pluralsight course:
Pluralsight courseJavaScript Interop in Blazor applications
Happy coding,
Thomas
Comments (10)
Excellent teacher! yes, my confusion was between ProtectedBrowserStorage and the one injected, in this case ProtectedLocalStorage. The example is very clear, I did a test and it works! fantastic, love your explanation, clear. Thank you so much!
Thank you Guillermo, happy to read that it is working now for you. Thomas
Nice article. Simple, direct and complete with the necessary details/comments.
What about IndexedDB ?
Also a valid option
Will you show an example about that?
Happened to see this page when I am searching the difference between session storage & local storage. Nice job!
For Blazor WebAssebmly Blazored.LocalStorage package already supports it now.
I did your PluralSight course on Blazor Server EF Core. Was very helpful. So many bad “tutorials” on Youtube.
Here I read that I can save Session data on Browsers’ local storage.
I would like to store this data in a LOCAL database (MSSQLServer or whatever) of the user, client-side and then remove it from local browser storage.
Otherwise I would be responsible for his/her data server-side.
How would I do that?
I suppose I cannot do that from the Blazor app, because that is only client-side HTML: No C# there.
Hey Erik, thank you for the feedback, I’m happy to read that you liked the Blazor Server EF Core course.
You cannot access a local MSSQLServer directly from the browser. For this you would need a REST API that you can call from the browser.
So, you have these options
a) Store data in the browser. There are local storage, but also IndexDb you can look at.
b) Store data in a traditional database. Then you have to call a REST API (or use Blazor Server) to access the database
Hope this helps,
Thomas
I am a beginner, and I am suffering from a lot of difficulties while saving data in local storage but this awesome website helped me a lot thanks a lot sir