Defer translation

Defer translation is a translation approach which is not SPA friendly because the website needs to be reloaded to take effect and all the resource will be loaded in the first load whether the user need it or not. However, this technique is easy to implement. In this tutorial, you will discover:

  • Current language and next load language concept.
  • Create a resource file.
  • Isolating resource files from component.
  • Eager loading resource files.
  • Determine selected language.
  • Build a switch language component.
You can download the example code used in this topic on GitHub.

Current language and next load language concept

In defer translation approach, you will have current language which is the language currently rendered in Blazor WebAssembly. The current language cannot be changed, even when you change the current language, the resource file will not be loaded. Therefore, the user cannot see the updated language until the website reloads. The current language is stored at the browser memory. In detail, the current language is stored at CultureInfo.DefaultThreadCurrentCulture and CultureInfo.DefaultThreadCurrentUICulture. The next language can be changed as long as the user wants, the next language will become the current language when the website reloads. There are many places for you to store the next load language, you can store the next load language in cookie, local storage. However, the next load language need to be stored in a persistent storage and cannot be stored in the browser memory. In this tutorial, we will use local storage as the storage for the next load language.


Create a resource file

From this section is the continuation of the Enable multiple languages in your website section of the previous tutorial Internalization and localization. To create a resource file, you need to have the component which is using that resource file first. Assuming you already have ChangeLanguageDemonstrate.razor component. You will need to create ChangeLanguageDemonstrate.resx as the fallback resource. The for each language, you create a respective resource file. All resource files must remain in the same folder as the component. A correct resource file collection is similar to the following image:

centralized-resource.png


Isolating resource files from component

You can isolate the resource files from its component.

  1. Create a folder to put the resource files.
  2. Re-construct the folder tree of the component. For example, if your component in the folder Pages, then you need to create a folder Pages. The following image illustrates the folder tree:

isolated-resource.png


Eager loading resource files

Once you have the resource files, you need to tell Blazor to eager loading them. If you don't isolate the resource files from the components, add the following code to your Program.cs:

builder.Services.AddLocalization();

If you isolate the resource files from the components, add the following code to your Program.cs:

builder.Services.AddLocalization(options => options.ResourcesPath = "BlazorSchoolResources");

In the code sample, BlazorSchoolResources is the root resource folder.


Determine selected language

The purpose of this step is to set the language when the user first load the website.

If you let the browser decide the website language, then you can skip this step.

If you want to set the priority between the language selection strategies, you can implement it on Program.cs. The following steps are an example for storing the language in the local storage strategy:

  1. Create JavaScript functions to access the local storage. For example, you can put the following code in the wwwroot/index.html.
<script>
    window.blazorCulture = {
        get: () => window.localStorage['BlazorCulture'],
        set: (value) => window.localStorage['BlazorCulture'] = value
    };
</script>
  1. Set the default language in your Program.cs. For example:
var host = builder.Build();

await SetWebsiteLanguage(host);
await host.RunAsync();

static async Task SetWebsiteLanguage(WebAssemblyHost host)
{
    var js = host.Services.GetRequiredService<IJSRuntime>();
    string userPreferenceLanguage = await js.InvokeAsync<string>("blazorCulture.get");
    string chosenLanguage = string.IsNullOrEmpty(userPreferenceLanguage) ? "en-US" : userPreferenceLanguage;
    CultureInfo.DefaultThreadCurrentCulture = new CultureInfo(chosenLanguage);
    CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo(chosenLanguage);
}
To use the above example, remove your await builder.Build().RunAsync() first.

Build a switch language component

The purpose of this step is to allow the user to switch the language in the UI. Once the user has selected the language, you will need to store it in the local storage/cookie or update the language parameter in the URL and force reload the website.

If you let the browser decide the website language, then you can skip this step.

If you let the user decide the website language, then you need to set the next load language based on your language selection strategy. The following code is an example for storing the language in the local storage strategy:

@inject IJSRuntime JSRuntime

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

@code {
    private void OnChangeLanguage(ChangeEventArgs e)
    {
        string selectedLanguage = e.Value?.ToString() ?? "en-US";
        InvokeAsync(() => JSRuntime.InvokeVoidAsync("blazorCulture.set", selectedLanguage));
    }
}
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-2025 Blazor School
An unhandled error has occurred. Reload 🗙