Better to fall asleep on Elm Street than use Blazor localization.
A modern localization library for .NET applications that uses YAML files instead of traditional .resx files. Works with any .NET application where IStringLocalizer dependency injection is available - from console applications to Blazor platforms, with automatic RTL/LTR handling.
- YAML-based localization - Readable
.yamlformat instead of.resxfiles - Microsoft IStringLocalizer compatibility with standard .NET localization API
- Embedded Resource integration with compile-time embedded translations
- File System support for direct YAML file reading
- Multi-platform Blazor support - same code across all Blazor platforms
- Automatic culture management with platform-specific storage (localStorage/cookie)
- RTL/LTR support for automatic right-to-left language handling
- Bootstrap theme integration with automatic CSS switching between RTL/LTR
- SEO-friendly rendering with static content + interactive componets
- Blazor GirCore - Linux desktop applications (WebKit + GTK4)
- Blazor Maui - Cross-platform desktop/mobile (Windows, macOS, iOS, Android, Tizen)
- Blazor WebAssembly - Standalone WebAssembly applications
- Blazor Web App - Server-side Blazor applications
- Blazor Web App Client - Hosted WebAssembly applications
- Everything else - Any platform/app where
IStringLocalizerdependency injection is available
- .NET 8.0 or later
Install the NuGet package
dotnet add package Yaml.Localization --version 10.0.0-rc.1Install the Blazor assets
libman install @blazor/assets@1.0.0 \
--provider unpkg \
--destination wwwroot \
--files css/bootstrap.min.css \
--files css/bootstrap.rtl.min.css \
--files js/blazor.body.min.js \
--files js/blazor.body.min.js.map \
--files js/blazor.head.min.js \
--files js/blazor.head.min.js.map \
--files js/blazor.web.head.min.js \
--files js/blazor.web.head.min.js.map \
--files js/bootstrap.bundle.min.js \
--files js/bootstrap.bundle.min.js.map"Hello World": "Hello World"
"Welcome {0}": "Welcome {0}"
"Language ({0})": "Language ({0})""Hello World": "Helló Világ"
"Welcome {0}": "Üdvözöljük {0}"
"Language ({0})": "Nyelv ({0})"Cultures:
- Name: en-US
Active: true
Default: true
- Name: hu
Active: true
- Name: de-DE
Active: true
- Name: es-ES
Active: true
- Name: ar
Active: true
Rtl: true
- Name: he-IL
Active: true
Rtl: true
Selector:
en-US: English
hu: Magyar
de-DE: Deutsch
es-ES: Español
ar: العربية
he-IL: עברית
CookieName: .lang
RedirectEndpoint: culture/set
<ItemGroup>
<Content Remove="I18N\*.yaml" />
<EmbeddedResource
Exclude="I18N\cultures.yaml"
Type="Non-Resx"
WithCulture="false"
Include="I18N\*.yaml"
LogicalName="$(RootNamespace).Lang.%(Filename).yaml"
/>
<Content Remove="I18N\cultures.yaml" />
<EmbeddedResource
Include="I18N\cultures.yaml"
LogicalName="CultureSettings.yaml"
/>
</ItemGroup>I18N\en.yaml→MyApp.Lang.en.yamlI18N\hu.yaml→MyApp.Lang.hu.yamlI18N\cultures.yaml→CultureSettings.yaml
<ItemGroup>
<EmbeddedResource
Exclude="Components\cultures.yaml"
Type="Non-Resx"
WithCulture="false"
Include="Components\**\*.razor*.yaml"
LogicalName="$(RootNamespace).$([System.String]::Copy('%(RelativeDir)').Replace('\','.').Replace('/','.'))$([System.String]::Copy('%(Filename)').Replace('.razor','')).yaml" />
<Content Remove="Components\cultures.yaml" />
<EmbeddedResource
Include="Components\cultures.yaml"
LogicalName="CultureSettings.yaml"
/>
</ItemGroup>
Components\cultures.yaml→CultureSettings.yamlComponents\Home.razor.en.yaml→MyApp.Components.Home.en.yamlComponents\Home.razor.hu.yaml→MyApp.Components.Home.hu.yaml
See the IPlatformService interface for platform-specific services.
- GirCore/Maui:
default! - WebApp:
InteractiveServer - WebApp WebAssembly:
InteractiveWebAssembly - WebAssembly:
InteractiveWebAssembly
builder.Services
// GirCore
.AddSingleton<IPlatformService, GirCorePlatformService>()
// Maui Desktop
.AddSingleton<IPlatformService, MauiPointerPlatformService>()
// Maui Mobile
.AddSingleton<IPlatformService, MauiTouchPlatformService>()
// Standalone WebAssembly
.AddScoped<IPlatformService, WebAssemblyPlatformService>()
// Blazor App
.AddScoped<IPlatformService, WebAppPlatformService>()
// Blazor App WebAssembly
.AddScoped<IPlatformService, WebAppWebAssemblyPlatformService>()
.AddScoped<ChangeThemeStore>()
.AddScoped<CultureSelectorStore>()
.AddYamlEmbeddedResourceLocalization(typeof(BlazorShared.Lang).Assembly);// immediately before calling MapRazorComponents.
app.SetWebAppYamlLocalization();@inject IStringLocalizer<Lang> L
<h1>@L["Hello World"]</h1>
<p>@L["Welcome {0}", "User"]</p><NavLink href="counter">@L["Counter"]</NavLink>
<NavLink href="weather">@L["Weather"]</NavLink>
<p>@L["About"]</p><CultureSelector @rendermode="PlatformService.RenderMode" />
<ChangeTheme @rendermode="PlatformService.RenderMode" />Cultures:
- Name: en-US
Active: true
Default: true
- Name: es-ES
Active: true
- Name: ar
Active: true
Rtl: true
- Name: he-IL
Active: true
Rtl: true<html lang="en" dir="ltr" data-bs-theme="auto">
<link rel="stylesheet" href="css/bootstrap.min.css" id="ltr-css" disabled>
<link rel="stylesheet" href="css/bootstrap.rtl.min.css" id="rtl-css" disabled>
<script>
window.BlazorLTRId = "ltr-css";
window.BlazorRTLId = "rtl-css";
</script>
<script src="js/blazor.head.min.js"></script>- Detects the active culture's RTL property
- Enable/disable the appropriate CSS file
- Updates the
<html dir="">attribute - Saves the setting
- GirCore/Maui localStorage
- WebAssembly cookie
<html lang="@CultureInfo.CurrentUICulture.TwoLetterISOLanguageName"
dir="@(CultureInfo.CurrentUICulture.TextInfo.IsRightToLeft ? "rtl" : "ltr")">
@if (CultureInfo.CurrentUICulture.TextInfo.IsRightToLeft)
{
<link rel="stylesheet" href="css/bootstrap.rtl.min.css" />
}
else
{
<link rel="stylesheet" href="css/bootstrap.min.css" />
}
<script>
window.BlazorLTRId = "ltr-css";
window.BlazorRTLId = "rtl-css";
</script>
<script src="js/blazor.web.head.min.js"></script>- Saves the setting to a cookie
Full working examples can be found in the samples folder:
- BlazorShared - Shared UI components and localization files
- BlazorGirCore - Linux desktop application with WebKit
- BlazorMaui - Cross-platform desktop/mobile application
- BlazorWasm - Standalone WebAssembly application
- BlazorWebApp - Server-side Blazor application
- BlazorWebAppClient - Hosted WebAssembly application
- GirCoreApp - Native GTK4 application with localization
- RTL/LTR language support (العربية, עברית, English, Magyar, Deutsch)
- Dark/Light/Auto theme switching
- Platform-specific culture handling
- SEO-friendly rendering for Web App
- BlazorShared
- BlazorShared.csproj
- I18N
- Lang.cs - Empty class for
IStringLocalizer<Lang>injection - wwwroot
- css
- bootstrap.min.css
- bootstrap.rtl.min.css
- js
- blazor.head.min.js - TypeScript reference
- blazor.web.head.min.js - TypeScript reference
- blazor.body.min.js - TypeScript reference
- bootstrap.bundle.min.js
- css
- BlazorGirCore
- BlazorGirCore.csproj
- Components
- Program.cs
- wwwroot
- BlazorMaui
- BlazorMaui.csproj
- Components
- MauiProgram.cs
- wwwroot
- BlazorWasm
- BlazorWasm.csproj
- Components
- Program.cs
- wwwroot
- BlazorWebApp
- BlazorWebApp.csproj
- Components
- Program.cs
- BlazorWebAppClient
- BlazorWebAppClient.csproj
- Components
- Program.cs
This project is licensed under the MIT License.
