Localization of Blazor Components
22 May 202424 minutes to read
Localization is the process of translating the application resources into different languages for specific cultures. You can localize the Syncfusion Blazor components by adding a resource file for each language.
Localization of Syncfusion Blazor Components
The following two steps can be used to localize Syncfusion Blazor components based on culture. You can find the example codes in the below repository,
NOTE
Adding culture based resx files
Syncfusion components can be localized using the Resource .resx
files. You can find the default and culture based localization files in the following GitHub repository.
NOTE
You can get default and culture based resource files from GitHub.
Copy the default resx file (SfResources.resx
) and the other required resx files based on the culture to be localized and add them to the Resources folder. If you are implementing in a .NET MAUI Blazor app, create a LocalizationResources folder and add them into it.
NOTE
Update the localization files whenever you upgrade the Syncfusion NuGet packages in the application to avoid the issues occur due to localization strings.
After adding the resource file in the application, double click default resx (SfResources.resx
) file and open Resource Editor. In the Resource Editor, change Access Modifier option as Public .
Create and register localization service
ISyncfusionStringLocalizer which acts as a middleware to connect the Syncfusion Blazor UI components and resource files, uses ResourceManager to provide culture specific resources at runtime. Create a class implementing ISyncfusionStringLocalizer
. In the newly created class, return the ResourceManager
created in the above step for ResourceManager property and change GetText method to return localized string using resource manager.
In the following code, SyncfusionLocalizer
class implements ISyncfusionStringLocalizer
interface and ResourceManager
configured to return the cached ResourceManager instance of default resource file created in Adding culture based resx files step.
using Syncfusion.Blazor;
public class SyncfusionLocalizer : ISyncfusionStringLocalizer
{
public string GetText(string key)
{
return this.ResourceManager.GetString(key);
}
public System.Resources.ResourceManager ResourceManager
{
get
{
// Replace the ApplicationNamespace with your application name.
return ApplicationNamespace.Resources.SfResources.ResourceManager;
//For .Net Maui Blazor App
// Replace the ApplicationNamespace with your application name.
//return ApplicationNamespace.LocalizationResources.SfResources.ResourceManager;
}
}
}
Register the ISyncfusionStringLocalizer
and Syncfusion Blazor Service
in the ~/Program.cs file of your app.
-
If you create a Blazor Web App with an Interactive render mode such as
WebAssembly or Auto
, you need to ensure the registration of theSyncfusionLocalizer and Syncfusion Blazor
services in both ~/Program.cs files. -
For MAUI Blazor App, register the Syncfusion Blazor Service in the ~/MauiProgram.cs file.
using Syncfusion.Blazor;
...
builder.Services.AddSyncfusionBlazor();
// Register the locale service to localize the SyncfusionBlazor components.
builder.Services.AddSingleton(typeof(ISyncfusionStringLocalizer), typeof(SyncfusionLocalizer));
...
Statically set the culture
If you don’t want to change culture dynamically, you can set it statically by following the procedures below.
Blazor Web App and Blazor WASM App
In Blazor Web App and Blazor WASM app, you can set culture statically in Blazor’s start option or in C# code.
Setting the culture Blazor’s start option
The app’s culture can be set in JavaScript by setting applicationCulture
in Blazor’s start option by following the steps below,
-
For
Blazor Web App
, prevent Blazor autostart by addingautostart="false"
attribute to the Blazor<script>
tag in the ~/Components/App.razor file. -
For
Blazor WebAssembly App
, prevent Blazor autostart by addingautostart="false"
attribute to Blazor’s<script>
tag in the wwwroot/index.html file.
<body>
...
<script src="_framework/blazor.web.js" autostart="false"></script>
...
</body>
<body>
...
<script src="_framework/blazor.webassembly.js" autostart="false"></script>
...
</body>
- Add the script block below Blazor’s
<script>
tag and before the closing </body> tag to start blazor with specific culture.
<body>
...
<script src="_framework/blazor.web.js" autostart="false"></script>
<script>
Blazor.start({
webAssembly: {
applicationCulture: 'de'
}
});
</script>
...
</body>
<body>
...
<script src="_framework/blazor.webassembly.js" autostart="false"></script>
<script>
Blazor.start({
applicationCulture: 'de'
});
</script>
...
</body>
Setting the culture in C# code
For Blazor Web App & Blazor WASM App
, you can set culture in C# code alternative for setting the culture Blazor’s start option. Set the CultureInfo.DefaultThreadCurrentCulture
and CultureInfo.DefaultThreadCurrentUICulture
in Program.cs
to the same culture before line that builds and runs the WebAssemblyHostBuilder
(await builder.Build().RunAsync();
).
using System.Globalization;
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("de-DE");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("de-DE");
Blazor Server App
- For .NET 6 & .NET 7 app, specify the static culture in ~/Program.cs file.
...
var app = builder.Build();
app.UseRequestLocalization("de-DE");
...
MAUI Blazor App
In a MAUI Blazor app, you can set the culture in C# code by configuring the CultureInfo.DefaultThreadCurrentCulture
and CultureInfo.DefaultThreadCurrentUICulture
in MauiProgram.cs
to the same culture. Ensure that this configuration is done before the line that builds and runs the MauiApp.CreateBuilder()
(i.e., return builder.Build();
).
using System.Globalization;
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("de-DE");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("de-DE");
Dynamically set the culture
The culture can be set dynamically based on user’s preference. The following example demonstrates how to use a localization cookie to store user’s localization preference.
Blazor Web App and Blazor WASM App
For Blazor Web App and Blazor WASM App
, set the BlazorWebAssemblyLoadAllGlobalizationData
property to true in the project file:
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
-
For Blazor Web App, add JS function in
~/Components/App.razor
file (after Blazor’s<script>
tag and before the closing</body>
), to get and set the user’s selected culture in the browser local storage. -
For Blazor WASM App, add JS function in
wwwroot/index.html
file (after Blazor’s<script>
tag and before the closing</body>
), to get and set the user’s selected culture in the browser local storage.
<script src="_framework/blazor.web.js"></script>
<script>
window.cultureInfo = {
get: () => window.localStorage['BlazorCulture'],
set: (value) => window.localStorage['BlazorCulture'] = value
};
</script>
<script src="_framework/blazor.webassembly.js"></script>
<script>
window.cultureInfo = {
get: () => window.localStorage['BlazorCulture'],
set: (value) => window.localStorage['BlazorCulture'] = value
};
</script>
In Program.cs
use JS interop to call above function and retrieve the user’s culture selection from local storage. If local storage doesn’t contain a culture for the user, the code sets a default value of United States English (en-US).
If you create a Blazor Web App with an Interactive render mode such as WebAssembly or Auto
, you need to ensure the registration of the SyncfusionLocalizer and Syncfusion Blazor
services in both ~/Program.cs files.
using Microsoft.JSInterop;
using System.Globalization;
...
builder.Services.AddSyncfusionBlazor();
//Register the Syncfusion locale service to localize Syncfusion Blazor components.
builder.Services.AddSingleton(typeof(ISyncfusionStringLocalizer), typeof(SyncfusionLocalizer));
var host = builder.Build();
//Setting culture of the application
var jsInterop = host.Services.GetRequiredService<IJSRuntime>();
var result = await jsInterop.InvokeAsync<string>("cultureInfo.get");
CultureInfo culture;
if (result != null)
{
culture = new CultureInfo(result);
}
else
{
culture = new CultureInfo("en-US");
await jsInterop.InvokeVoidAsync("cultureInfo.set", "en-US");
}
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
await builder.Build().RunAsync();
Create CultureSwitcher
component to set the user’s culture selection into browser local storage via JS interop and to force reload the page using the updated culture.
@using System.Globalization
@inject IJSRuntime JSRuntime
@inject NavigationManager NavigationManager
<select @bind="Culture">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
@code {
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("de-DE"),
new CultureInfo("fr-FR"),
new CultureInfo("ar-AE"),
new CultureInfo("zh-HK")
};
private CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
var js = (IJSInProcessRuntime)JSRuntime;
js.InvokeVoid("cultureInfo.set", value.Name);
NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true);
}
}
}
}
Add the CultureSwitcher
component to ~/MainLayout.razor
to enable the culture switcher in all pages. If you create a Blazor Web App with an interactivity location as Per page/component
, you need to ensure the set a render mode at the CultureSwitcher
component instance in the ~/MainLayout.razor
file.
<div class="page">
....
<main>
<div class="top-row px-4">
<CultureSwitcher @rendermode="@InteractiveAuto" />
....
</div>
</main>
</div>
<div class="page">
....
<main>
<div class="top-row px-4">
<CultureSwitcher />
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
</div>
</main>
</div>
Blazor Server App and Blazor Web App (Interactive Server)
Set the app’s supported cultures. Also, ensure the app is configured to process controller actions by calling AddControllers
and MapControllers
.
If you create a Blazor Web App with an Interactive render mode as Server
make sure to include the registration of SyncfusionLocalizer and Syncfusion Blazor services in the ~/Program.cs files.
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>();
builder.Services.AddControllers();
builder.Services.AddSyncfusionBlazor();
//Register the Syncfusion locale service to localize Syncfusion Blazor components.
builder.Services.AddSingleton(typeof(ISyncfusionStringLocalizer), typeof(SyncfusionLocalizer));
var supportedCultures = new[] { "en-US", "de-DE", "fr-FR", "ar-AE", "zh-HK" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
var app = builder.Build();
app.UseRequestLocalization(localizationOptions);
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.MapControllers();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
builder.Services.AddControllers();
builder.Services.AddSyncfusionBlazor();
builder.Services.AddLocalization();
var supportedCultures = new[] { "en-US", "de-DE", "fr-FR", "ar-AE", "zh-HK" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
.AddSupportedUICultures(supportedCultures);
var app = builder.Build();
app.UseRequestLocalization(localizationOptions);
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.MapControllers();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");
app.Run();
For .NET 6 and 7 set the current culture in a cookie immediately after opening <body> tag of Pages/_Host.cshtml
.
For .NET 8 set the current culture in a cookie in App component file
@using Microsoft.AspNetCore.Http
@using Microsoft.AspNetCore.Localization
@using System.Globalization
@{
HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture)));
}
@using System.Globalization
@using Microsoft.AspNetCore.Localization
@code {
[CascadingParameter]
public HttpContext? HttpContext { get; set; }
protected override void OnInitialized()
{
HttpContext?.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture)));
}
}
To provide UI to allow a user to select a culture, use a redirect-based approach with a localization cookie. The app persists the user’s selected culture via a redirect to a controller. The controller sets the user’s selected culture into a cookie and redirects the user back to the original URI.
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
[Route("[controller]/[action]")]
public class CultureController : Controller
{
public IActionResult SetCulture(string culture, string redirectUri)
{
if (culture != null)
{
HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(culture)));
}
return LocalRedirect(redirectUri);
}
}
Create CultureSwitcher
component and place it inside shared folder to perform the initial redirection when the user selects a culture.
@using System.Globalization
@inject NavigationManager NavigationManager
@inject HttpClient Http
<p>
<label>
Select your locale:
<select @bind="Culture">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
</label>
</p>
@code {
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("de-DE"),
new CultureInfo("fr-FR"),
new CultureInfo("ar-AE"),
new CultureInfo("zh-HK")
};
protected override void OnInitialized()
{
Culture = CultureInfo.CurrentCulture;
}
private CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
var uri = new Uri(NavigationManager.Uri)
.GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
var cultureEscaped = Uri.EscapeDataString(value.Name);
var uriEscaped = Uri.EscapeDataString(uri);
NavigationManager.NavigateTo(
$"Culture/SetCulture?culture={cultureEscaped}&redirectUri={uriEscaped}",
forceLoad: true);
}
}
}
}
Add the CultureSwitcher
component to Shared/MainLayout.razor
to enable the culture switcher in all pages.
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<CultureSwitcher />
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
</div>
<article class="content px-4">
@Body
</article>
</main>
</div>
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<CultureSwitcher></CultureSwitcher>
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
</div>
<article class="content px-4">
@Body
</article>
</main>
</div>
MAUI Blazor App
In App.xaml.cs
, use Preferences to retrieve the user’s stored culture selection. If the storage doesn’t contain a culture for the user, the code sets a default value of United States English (en-US).
using System.Globalization;
namespace LocalizationMauiBlazor
{
public partial class App : Application
{
public App()
{
InitializeComponent();
var language = Preferences.Get("language", "en-US");
var culture = new CultureInfo(language);
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
MainPage = new MainPage();
}
}
}
Create CultureSwitcher
component to store the user’s culture selection via Preferences and to force reload the page using the updated culture.
@using System.Globalization
@inject NavigationManager NavigationManager
<select @bind="Culture">
@foreach (var culture in supportedCultures)
{
<option value="@culture">@culture.DisplayName</option>
}
</select>
@code {
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
new CultureInfo("de-DE"),
new CultureInfo("fr-FR"),
new CultureInfo("ar-AE"),
new CultureInfo("zh-HK")
};
private CultureInfo Culture
{
get => CultureInfo.CurrentCulture;
set
{
if (CultureInfo.CurrentCulture != value)
{
CultureInfo.DefaultThreadCurrentCulture = value;
CultureInfo.DefaultThreadCurrentUICulture = value;
Preferences.Set("language", value.Name);
NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true);
}
}
}
}
Add the CultureSwitcher
component to Layout/MainLayout.razor
to enable the culture switcher on all pages.
@inherits LayoutComponentBase
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
</div>
<article class="content px-4">
<CultureSwitcher />
@Body
</article>
</main>
</div>
NOTE