In this article we will discuss the possibility of adding multilingual capability to your Blazor Assembly application.
Microsoft’s documentation tells us that the language used in your application is based on the user’s language preference in the browser.
This information is returned by the Javascript function :
navigator.language //"en-US" navigator.languages //["en-US", "zh-CN", "ja-JP"]
If you are working in a context where your users are using a computer where the choice of browser language is set by the infrastructure administrators, this can quickly make the user experience you are trying to set up harmful.
Here are the various steps for setting up language selection in your Blazor WebAssembly applications
1. Inform your application that it is multilingual
You need to add a package nuget package to add localization capabilities :
Microsoft.AspNetCore.Localization
Microsoft.Extensions.Localization
If you are using Visual Studio, you can use the Package NuGet tool.
If you can alter your csproj file with adding these line :
<ItemGroup>
<!-- Other dependencies-->
<PackageReference Include="Microsoft.AspNetCore.Localization" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="3.1.7" />
<!-- These versions are the latest at the writing post time -->
</ItemGroup>
On the using section of your program.cs
file, you can insert these using statements :
using System.Globalization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.JSInterop;
Once inserted, you need to register the localization middleware and retrieve the current navigator culture by invoking an interop Javascript call
public class Program
{
public static async Task Main(string[] args)
{
// ...
builder.Services.AddLocalization(opts => { opts.ResourcesPath = "Resources"; });
var host = builder.Build();
var jsInterop = host.Services.GetRequiredService<IJSRuntime>();
var result = await jsInterop.InvokeAsync<string>("blazorCulture.get");
if (result != null)
{
var culture = new CultureInfo(result);
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
}
// ...
}
In this example, I’m using the translated resources files based on the resx way. More details on Microsoft Docs.
You can enhance your translation experience in Visual Studio using the Resx Manager extension.
2. Include Interop Javascript function
In order to make your interop call available, you need to add in your index.html
or where you store static Javascript method a method in order to retrieve or set a way to store your application culture. You can add the following code to make it possible :
window.blazorCulture = {
get: () => window.localStorage['BlazorCulture'],
set: (value) => window.localStorage['BlazorCulture'] = value
};
pssst: Don’t forget to encapsulate with
<script></script>
tags if you add this statement in a html file.
3. Allow your user to change language
Somewhere in your application, in a .razor
file, you need to add the following statement to allow you user to change language:
<strong>Culture:</strong>
<select @bind="Culture">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
@code {
private CultureInfo[] supportedCultures = new[]
{
// French language
new CultureInfo("fr"),
// English language
new CultureInfo("en"),
// Dutch language
new CultureInfo("nl"),
};
private CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
var js = (IJSInProcessRuntime)JSRuntime;
js.InvokeVoid("blazorCulture.set", value.Name);
Nav.NavigateTo(Nav.Uri, forceLoad: true);
}
}
}
}
The codes used in the supportedCultures array are based on the rfc5646.
4. Translation your Blazor View and go to the next level of your application
When you had configured everything above, and your application resource file is created, you can start to make localization in your view.
For make it, we will use the IStringLocalizer
or IStringLocalizer<T>
, because IHtmlLocalizer
, IViewLocalizer
, and Data Annotations localization are ASP.NET Core MVC scenarios and not supported in Blazor apps.
In a .razor
file, we will inject the localizer object and use the dictionary getter to make the magic happens.
@inject IStringLocalizer<Index> localizer
<h1>@localizer["Title"]</h1>
In this exemple, the Index
passed in the generic argument is the resource file.
Run your application, and use it with globalization for improve user experience.