Localization

  • 6 minutes to read

A culture is a set of options that include information about the writing system, the calendar, the sort order of strings, and dates and numbers formats. Localization is the process of adapting an application to a particular language and culture. DevExpress Blazor components ship with localizable resources for UI elements, such as button captions, menu items, error messages, and dialog boxes.

Localization Overview

In Blazor applications, DevExpress components use the standard localization mechanism from the .NET framework - Satellite Resource Assemblies (libraries that contain translated resources). For more information, refer to the following MSDN article: Creating Satellite Assemblies.

View Example: How to localize DevExpress Blazor components

Predefined Satellite Assemblies

DevExpress components contain predefined satellite resource assemblies for the following localizations:

  • German
  • Spanish
  • Japanese
  • Russian

You can add these localizations to your application in two ways.

Project Wizard

This approach is applicable when you create a new project:

  1. Run the New Project wizard from the DevExpress template gallery.
  2. Switch to the Localization tab and select a culture.

    Project Wizard Localization

  3. Optional. Switch to the Settings tab and set the Add Rich Text Editor Resources option to True to register the Rich Text Editor‘s resources in your application.
  4. Click the Create Project button.
  5. The localization package is added in the Dependencies section of your Solution Explorer.

    Spanish Package is added

NuGet Packages

This approach is applicable if you want to add localization to an existing project or if you use a Microsoft Blazor Template to create a project:

  1. In Visual Studio, select ToolsNuGet Package ManagerManage NuGet Packages for Solution.
  2. In the invoked dialog, select the DevExpress package source.
  3. Find the DevExpress.Blazor.XX NuGet package with the required culture and install it.

    Optional. Find the DevExpress.Blazor.RichEdit.XX NuGet package with the required culture and install it to localize the Rich Text Editor.

    localization NuGet Packages

  4. The localization package is added in the Dependencies section of your Solution Explorer.

    Spanish Package is added

Satellite Assemblies for Other Cultures

To download satellite assemblies for DevExpress Blazor components that correspond to other cultures, use an approach that corresponds to your application’s hosting model.

Blazor Server

Use the DevExpress Localization Service to create a custom set of satellite assemblies, modify resources, and download assemblies.

Ensure that the major version of the satellite assemblies (for instance, v21.2) matches the major version of the DevExpress Blazor package in the project. For more information on how to prepare and download resource assemblies, view the following video: DevExpress Localization: Getting Started.

Localization Service

Follow the steps below to add downloaded assemblies to your Blazor Server application.

  1. Create a subdirectory in the application’s EXE file directory (usually in the bin\Debug\netcoreappX.X\ subdirectory) with a name that corresponds to the newly generated resource culture (for example, bin\Debug\netcoreappX.X\fr - to translate your application into French).
  2. Unpack the archive with resources generated by the DevExpress Localization Service and copy the DevExpress.Blazor.v21.2.resources.dll file to the newly created subdirectory.
  3. Rebuild the application.

Blazor WebAssembly

Use the DevExpress Localization Service to create a custom set of satellite assemblies, modify resources, and download assemblies.

Ensure that the major version of the satellite assemblies (for instance, v21.2) matches the major version of the DevExpress Blazor package in the project. For more information on how to prepare and download resource assemblies, view the following video: DevExpress Localization: Getting Started.

Localization Service

Follow the steps below to add downloaded assemblies to your Blazor WebAssembly application.

  1. Install the Microsoft.Extensions.Localization NuGet package.
  2. Create the Resources folder in your Blazor project and register this folder in the Program.cs file:

    builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
    
  3. Extract the downloaded resources.
  4. Copy the LocalizationRes.resx and LocalizationRes.fr.resx files from the DevExpressLocalizedResources_2021.2_fr\src\DevExpress.Blazor\Resources folder to your project’s Resources folder.
  5. Create a localization service.

    using DevExpress.Blazor.Localization;
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Resources;
    using System.Threading.Tasks;
    
    public class DemoLocalizationService : DxLocalizationService, IDxLocalizationService { 
        string IDxLocalizationService.GetString(string key) {
            var culture = CultureInfo.CurrentUICulture.Name;
            string value = null;
            switch(culture) {
                case "fr-FR":
                    value = new ResourceManager("BlazorClientApp.Resources.LocalizationRes", typeof(DemoLocalizationService).Assembly).GetString(key);
                    break;
            }
            return value ?? base.GetString(key);
        }
    }
    
  6. Register this service in the Program.cs file:

    builder.Services.AddSingleton(typeof(IDxLocalizationService), typeof(DemoLocalizationService));
    
  7. Enable the BlazorWebAssemblyLoadAllGlobalizationData property in the project file:

    <PropertyGroup>
        <BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
    </PropertyGroup>
    
  8. Rebuild the application.

Change a Culture

After you add localization resources to your application, all Blazor components use resources that correspond to the current culture.

For more information on Blazor globalization and localization, refer to the Microsoft documentation.

Blazor Server

To change the culture in Blazor Server applications, add a Razor expression to the Pages/_Host.cshtml file’s <body>:

@using System.Globalization
@using Microsoft.AspNetCore.Localization

<body>
    @{
        this.HttpContext.Response.Cookies.Append(
            CookieRequestCultureProvider.DefaultCookieName,
            CookieRequestCultureProvider.MakeCookieValue(
                new RequestCulture(
                    new CultureInfo("fr-FR")
            )));
    }
</body>

After that, register the localization middleware in the Startup.cs file:

public class Startup {
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env){
        var supportedCultures = new[] { "fr-FR" };
        var localizationOptions = new RequestLocalizationOptions().SetDefaultCulture(supportedCultures[0])
            .AddSupportedCultures(supportedCultures)
            .AddSupportedUICultures(supportedCultures);

        app.UseRequestLocalization(localizationOptions);
    ...
    }
}

To implement a UI that allows users to change the culture at runtime, use the approach from the following example on GitHub: How to localize DevExpress Blazor components.

@using System.Globalization

@inject IJSRuntime JSRuntime
@inject NavigationManager Nav

<strong>Culture:</strong>
<div class="d-inline-block" style="margin-bottom:2rem">
    <DxComboBox Data="@SupportedCultures.Cultures"
                TextFieldName="NativeName"
                @bind-Value="@Culture">
    </DxComboBox>
</div>

@code {
    CultureInfo Culture {
        get => CultureInfo.CurrentCulture;
        set {

            var cultureName = value.Name;
            var uri = new Uri(Nav.Uri)
                .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
            var query = $"?culture={Uri.EscapeDataString(cultureName)}&" +
                $"redirectUri={Uri.EscapeDataString(uri)}";

            Nav.NavigateTo("/Culture/SetCulture" + query, forceLoad: true);
        }
    }
}

Blazor WebAssembly

To change the culture in Blazor WebAssembly applications, add the following code to the Program.Main method:

using System.Globalization;

public class Program {
   public static async Task Main(string[] args) {
        CultureInfo cultureInfo = CultureInfo.CreateSpecificCulture("fr-FR"); 
        CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
        CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
    }
}     

To get the name of the culture from the client and localize DevExpress Blazor components based on this culture, add the following code to the Program.Main method:

using Microsoft.JSInterop;
using DevExpress.Blazor.Localization;

public class Program {
    public static async Task Main(string[] args) {
        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;
        }
    }
}

To change the culture dynamically, enable the BlazorWebAssemblyLoadAllGlobalizationData property in the project file (if you have not already done it):

<PropertyGroup>
    <BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>

To implement a UI that allows users to change the culture at runtime, use the approach from the following example on GitHub: How to localize DevExpress Blazor components.

@using  System.Globalization
@inject IJSRuntime JSRuntime
@inject NavigationManager Nav

<strong>Culture:</strong>
<div class="d-inline-block" style="margin-bottom:2rem">
    <DxComboBox Data="@SupportedCultures.Cultures"
                TextFieldName="NativeName"
                @bind-Value="@Culture">
    </DxComboBox>
</div>

@code { 
    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);
            }
        }
    }
}