Deferred translation

🟥 Not applicable to Blazor WebAssembly

One of the biggest challenges of building multilingual websites is managing translations efficiently. Blazor provides a powerful feature called deferred translation, which enables the seamless translation of text in your web application. With deferred translation, when a user changes the language preference, the website remembers it for future visits, but the language selection may not take effect until the user refreshes the website. In this tutorial, we will cover:

  • Implementing the browser language strategy.
  • Implementing the cookies strategy.
  • Implementing the URL strategy.
  • Using the deferred translation.
You can download the example code used in this topic on GitHub.

Implementing the browser language strategy

The browser language strategy is one of the methods that can be used to determine a user's preferred language in a multilingual website.

When a user visits a website, their browser sends a request header that contains information about the user's preferred language(s). This information is based on the language settings that the user has configured in their browser.

The browser language strategy works by checking the value of the Accept-Language header in the incoming request, and then using that information to select the appropriate language for the website. If the website supports the user's preferred language, it will display content in that language. If the preferred language is not supported, the website may fall back to a default language or display an error message.

browser-language-example.png

  1. Create resource files (refer to the previous tutorial for more details).
  2. Register the resource files in Program.cs (refer to the previous tutorial for more details).
  3. Configure localization settings in Program.cs using the following code:
builder.Services.Configure<RequestLocalizationOptions>(options =>
{
    // You can set the default language using the following method:
    // options.SetDefaultCulture("fr");
    options.AddSupportedCultures(new[] { "en", "fr" });
    options.AddSupportedUICultures(new[] { "en", "fr" });
    options.RequestCultureProviders = new List<IRequestCultureProvider>()
        {
            new AcceptLanguageHeaderRequestCultureProvider()
        };
});

Implementing the cookies strategy

Blazor can use the cookie language selection strategy to determine a user's preferred language on a website. If a cookie with the preferred language exists, the website can display content in that language by default. It's worth noting that while cookies can be used for language selection, MDN recommends using alternative browser storage methods like localStorage, sessionStorage, or IndexedDB due to their better performance and security.

cookie-storage-example.png

  1. Create resource files (refer to the previous tutorial for more details).
  2. Register the resource files in Program.cs (refer to the previous tutorial for more details).
  3. Configure localization settings in Program.cs using the following code:
builder.Services.AddControllers();
builder.Services.AddLocalization(...);
builder.Services.Configure<RequestLocalizationOptions>(options =>
{
    // You can set the default language using the following method:
    // options.SetDefaultCulture("fr");
    options.AddSupportedCultures(new[] { "en", "fr" });
    options.AddSupportedUICultures(new[] { "en", "fr" });
    options.RequestCultureProviders = new List<IRequestCultureProvider>()
    {
        new CookieRequestCultureProvider()
    };
});

Why do we need controllers in Blazor Server?

Blazor is a Single Page Application (SPA) framework, and as such, there is typically only one request sent to the server. Cookies are attached to this request and changing them requires a new request. By introducing controllers, you can interpret the request and allow the Blazor Server to access and modify the cookies. In other words, controllers provide a mechanism for handling incoming requests and modifying the server state in response.

  1. Create a new folder named Controllers, inside the Controllers folder, add a new controller as below:

add-controller-to-blazor-server.png

[Route("[controller]/[action]")]
public class CultureController : Controller
{
    public IActionResult Set(string culture, string redirectUri)
    {
        if (culture is not null)
        {
            HttpContext.Response.Cookies.Append(CookieRequestCultureProvider.DefaultCookieName, CookieRequestCultureProvider.MakeCookieValue(new(culture, culture)));
        }

        return LocalRedirect(redirectUri);
    }
}
  1. Build the language selector component. This component will enable users to select their preferred language and redirect the request to the newly-created controller. The controller will then be used to modify the cookie value in the response.
@inject NavigationManager NavigationManager

<select @onchange="OnChangeLanguage">
    <option value="">Select</option>
    <option value="en">English</option>
    <option value="fr">France</option>
</select>

@code {
    private void OnChangeLanguage(ChangeEventArgs e)
    {
        var uri = new Uri(NavigationManager.Uri).GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
        var culture = CultureInfo.GetCultureInfo(e.Value as string);
        var cultureEscaped = Uri.EscapeDataString(culture.Name);
        var uriEscaped = Uri.EscapeDataString(uri);
        NavigationManager.NavigateTo($"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}", forceLoad: true);
    }
}

Implementing the URL strategy

The URL strategy allows users to easily switch to their preferred language or share a link with the preferred language.

url-example.png

  1. Create resource files (refer to the previous tutorial for more details).
  2. Register the resource files in Program.cs (refer to the previous tutorial for more details).
  3. Configure localization settings in Program.cs using the following code:
builder.Services.Configure<RequestLocalizationOptions>(options =>
{
    // You can set the default language using the following method: 
    // options.SetDefaultCulture("fr");
    options.AddSupportedCultures(new[] { "fr", "en" });
    options.AddSupportedUICultures(new[] { "fr", "en" });
    options.RequestCultureProviders = new List<IRequestCultureProvider>()
    {
        new QueryStringRequestCultureProvider()
    };
});
  1. Interpret the URL parameters in App.razor and set the language accordingly. Here is an example:
@inject NavigationManager NavigationManager
@inject IOptions<RequestLocalizationOptions> RequestLocalizationOptions

...

@code {
    protected override void OnInitialized()
    {
        var uri = new Uri(NavigationManager.Uri);
        var urlParameters = HttpUtility.ParseQueryString(uri.Query);
        var defaultCulture = RequestLocalizationOptions.Value.DefaultRequestCulture.Culture;
        var cultureProvider = RequestLocalizationOptions.Value.RequestCultureProviders.First(p => p is QueryStringRequestCultureProvider) as QueryStringRequestCultureProvider;
        CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo(urlParameters[cultureProvider.QueryStringKey] ?? defaultCulture.Name);
        CultureInfo.CurrentUICulture = CultureInfo.GetCultureInfo(urlParameters[cultureProvider.UIQueryStringKey] ?? CultureInfo.CurrentCulture.Name);
    }
}

Using the deferred translation

Once you have created all the required classes and prepared the translated resources, you can start using deferred translation. Here's an example:

@inject IStringLocalizer<ChangeLanguageDemonstrate> Localizer

<h3>ChangeLanguageDemonstrate</h3>
@Localizer["Hello Blazor School {0} {1}", "optional param1", "optional param2"]
BLAZOR SCHOOL
Designed and built with care by our dedicated team, with contributions from a supportive community. We strive to provide the best learning experience for our users.
Docs licensed CC-BY-SA-4.0
Copyright © 2021-2024 Blazor School
An unhandled error has occurred. Reload 🗙