Lumeo

Localization

How Lumeo picks the locale for component strings, dates, and numbers — and the Blazor WASM gotcha you need to know about.

Setting the default locale

Blazor WASM does NOT auto-detect the browser locale. Lumeo's components use CultureInfo.CurrentCulture for date/number formatting and ILumeoLocalizer (which reads CultureInfo.CurrentUICulture) for component strings — both default to en-US until you set them.

That's why a DatePicker shows "Mon", "Tue" in English even when the browser is configured for de-DE: the runtime never propagated the OS / browser preference into CurrentCulture.

Pin a culture in Program.cs

The simplest fix is to set DefaultThreadCurrentCulture and DefaultThreadCurrentUICulture on the CultureInfo static, before the host runs:

using System.Globalization;

var builder = WebAssemblyHostBuilder.CreateDefault(args);

// Hardcoded — replace with your preferred default
var culture = new CultureInfo("de-DE");
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;

builder.Services.AddLumeo();
await builder.Build().RunAsync();

Detect the browser locale at startup

For a UX that adapts to the user's browser, read navigator.language via JS interop before RunAsync():

using System.Globalization;
using Microsoft.JSInterop;

var builder = WebAssemblyHostBuilder.CreateDefault(args);

builder.Services.AddLumeo();
var host = builder.Build();

// Read navigator.language, fall back to en-US.
var js = host.Services.GetRequiredService<IJSRuntime>();
var browserLocale = await js.InvokeAsync<string>("eval", "navigator.language");
var culture = new CultureInfo(string.IsNullOrEmpty(browserLocale) ? "en-US" : browserLocale);
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;

await host.RunAsync();

Component strings (ILumeoLocalizer)

Lumeo ships with English and German default translations for all built-in component strings (close buttons, "no results", pagination labels, etc). The lookup order is:

  • Exact culture match (e.g. de-DE)
  • Neutral / parent culture (de)
  • English fallback (en)
  • The key itself (so unresolved keys are visible, never silently empty)

Override or extend translations in your AddLumeo call:

builder.Services.AddLumeo(opts =>
{
    // Override a single key for an existing culture
    opts.Add("de", "DataGrid.NoData", "Keine Datensätze");

    // Add a whole new culture
    opts.AddMany("fr", new Dictionary<string, string>
    {
        ["DataGrid.NoData"] = "Aucune donnée",
        ["Pagination.Previous"] = "Précédent",
    });
});

See also