Localization of Blazor Components
29 Apr 202324 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 default resx file (SfResources.resx
) and the other required resx files based on the culture to be localized and add it into Resources folder.
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 to generate designer.cs
file.
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;
}
}
}
Register the ISyncfusionStringLocalizer
implementation to localize the Syncfusion Blazor components based on resources files added in application.
- For Blazor Server App, register the Syncfusion Blazor Service as follows,
- For .NET 6 and .NET 7 app, open the ~/Program.cs file and register the Syncfusion Blazor Service.
- For .NET 5 and .NET 3.X app, open the ~/Startup.cs file and register the Syncfusion Blazor Service.
- For Blazor WebAssembly App, register the Syncfusion Blazor Service in the client web app of ~/Program.cs file.
...
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 Server App
- For .NET 6 app, specify the static culture in ~/Program.cs file.
- For .NET 5 and .NET 3.X app, specify the static culture in ~/Startup.cs file.
...
var app = builder.Build();
app.UseRequestLocalization("de");
...
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseRequestLocalization("de");
...
}
Blazor WASM App
In 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,
- In
wwwroot/index.html
, prevent Blazor autostart by addingautostart="false"
attribute to Blazor’s<script>
tag.
<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.webassembly.js" autostart="false"></script>
<script>
Blazor.start({
applicationCulture: 'de'
});
</script>
...
</body>
Setting the culture in C# code
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");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("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 Server App
Set the app’s supported cultures. Also, ensure the app is configured to process controller actions by calling AddControllers
and MapControllers
.
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", "fr", "ar", "zh" };
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();
public class Startup
{
...
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddControllers();
services.AddServerSideBlazor();
services.AddSingleton<WeatherForecastService>();
services.AddSyncfusionBlazor();
//Register the Syncfusion locale service to localize Syncfusion Blazor components.
services.AddSingleton(typeof(ISyncfusionStringLocalizer), typeof(SyncfusionLocalizer));
services.Configure<RequestLocalizationOptions>(options =>
{
// Define the list of cultures your app will support
var supportedCultures = new List<CultureInfo>()
{
new CultureInfo("en-US"),
new CultureInfo("de"),
new CultureInfo("fr"),
new CultureInfo("ar"),
new CultureInfo("zh"),
};
// Set the default culture
options.DefaultRequestCulture = new RequestCulture("en-US");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRequestLocalization(app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>().Value);
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
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.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
}
}
Set the current culture in a cookie immediately after opening <body> tag of Pages/_Host.cshtml
.
@using Microsoft.AspNetCore.Localization
@using System.Globalization
@{
Layout = "_Layout";
this.HttpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(
new RequestCulture(
CultureInfo.CurrentCulture,
CultureInfo.CurrentUICulture)));
}
@using Microsoft.AspNetCore.Http
@using Microsoft.AspNetCore.Localization
@using System.Globalization
@{
Layout = null;
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"),
new CultureInfo("fr"),
new CultureInfo("ar"),
new CultureInfo("zh")
};
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>
Blazor WASM App
Set the BlazorWebAssemblyLoadAllGlobalizationData
property to true in the project file:
<PropertyGroup>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>
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.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).
using Microsoft.JSInterop;
using System.Globalization;
...
builder.Services.AddSyncfusionBlazor();
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
//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();
using Microsoft.JSInterop;
using System.Globalization;
namespace SyncfusionWasmLocalization
{
public class Program
{
public static async Task Main(string[] args)
{
...
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
@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"),
new CultureInfo("fr"),
new CultureInfo("ar"),
new CultureInfo("zh")
};
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 Shared/MainLayout.razor
to enable the culture switcher in all pages.
<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>
NOTE