# Localization

Source: https://lumeo.nativ.sh/docs/localization

# 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

-   [Culture & Localized Formatting](docs/culture) — date/number/currency formatting and per-component `Culture` overrides
-   [RTL Support](docs/rtl) — right-to-left layout
