BlazorLocalization.Extensions 10.3.0

dotnet add package BlazorLocalization.Extensions --version 10.3.0
                    
NuGet\Install-Package BlazorLocalization.Extensions -Version 10.3.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="BlazorLocalization.Extensions" Version="10.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="BlazorLocalization.Extensions" Version="10.3.0" />
                    
Directory.Packages.props
<PackageReference Include="BlazorLocalization.Extensions" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add BlazorLocalization.Extensions --version 10.3.0
                    
#r "nuget: BlazorLocalization.Extensions, 10.3.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package BlazorLocalization.Extensions@10.3.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=BlazorLocalization.Extensions&version=10.3.0
                    
Install as a Cake Addin
#tool nuget:?package=BlazorLocalization.Extensions&version=10.3.0
                    
Install as a Cake Tool

<div align="center">

BlazorLocalization logo

BlazorLocalization

Your users see text in their language. Always.

A modern localization library for ASP.NET Core — Blazor, MVC, Razor Pages, APIs
No .resx files. No rebuild to update a translation.

License: MIT NuGet

</div>

Inline translations · Pluggable providers · Plurals & ordinals · Over-the-air updates · Distributed caching


⭐ Quick Start

1. Install:

dotnet add package BlazorLocalization.Extensions

2. Register in Program.cs:

// Replaces the built-in services.AddLocalization():
builder.Services.AddProviderBasedLocalization();

3. Use in your code:

@inject IStringLocalizer<Home> Loc

<h1>@Loc.Translation(key: "Home.Title", message: "Welcome to our app")</h1>

<p>@(Loc.Translation(key: "Home.Greeting", message: "Hello, {Name}!", replaceWith: new { Name = user.Name })
    .For(locale: "da", message: "Hej, {Name}!")
    .For(locale: "de", message: "Hallo, {Name}!"))</p>

Your source text is always the fallback — users never see blank strings or raw keys. .For() adds inline translations for other languages right where you write the text.

See Examples for plurals, ordinals, enum display names, and more.

Note: You still need UseRequestLocalization() middleware for culture detection — see Configuration.


📦 Packages

Package Version Install
BlazorLocalization.Extensions <br/> Caches translations, supports plurals and inline translations, pluggable translation providers NuGet dotnet add package BlazorLocalization.Extensions
BlazorLocalization.Extractor <br/> CLI tool (blazor-loc) — Roslyn-based scanner that extracts source strings from .razor, .cs, and .resx files NuGet dotnet tool install -g BlazorLocalization.Extractor

Translation providers:

Package Version Install
BlazorLocalization.TranslationProvider.Crowdin <br/> Fetch translations over-the-air from Crowdin NuGet dotnet add package BlazorLocalization.TranslationProvider.Crowdin
JsonFile <br/> Load translations from flat JSON files on disk Ships with Extensions
PoFile <br/> Load translations from GNU Gettext PO files Ships with Extensions

🔌 Add a Provider

Translation providers are pluggable and optional. Use them when you have too many strings for inline .For(), or want to connect a translation management platform.

// JSON files on disk (ships with Extensions — no extra package):
builder.Services.AddProviderBasedLocalization(builder.Configuration)
    .AddJsonFileTranslationProvider();
// Or over-the-air from Crowdin (separate package):
// Configure your distribution hash in appsettings.json — see Crowdin Provider docs
builder.Services.AddProviderBasedLocalization()
    .AddCrowdinTranslationProvider();

The provider always wins when it has a translation. Inline .For() translations serve as a starting point for translators and a fallback.

See Providers for all available providers and their setup.


✨ Why BlazorLocalization?

IStringLocalizer is deeply embedded in ASP.NET Core — Blazor, MVC, Razor Pages, APIs. BlazorLocalization keeps it as the interface but replaces AddLocalization() and its ResourceManager / .resx backend entirely:

  • Over-the-air translations — FusionCache refreshes from your provider in the background. Change a translation, your app picks it up without redeployment
  • Source text fallback — if translations haven't loaded yet, users see your source text, never blank strings or keys
  • CLDR plural support — plural categories, ordinals, gender/select. ICU concepts, C# ergonomics
  • Distributed caching — L1 memory out of the box, optional L2 via any IDistributedCache (Redis, SQLite, etc.)
  • Pluggable providers — load translations from JSON files, Crowdin, a database, or any custom source. Stack multiple providers — first one with a translation wins

What you're leaving behind: .resx merge conflicts, rebuild-and-redeploy for every text change, no plural support, no distributed caching.

Built on Microsoft's IStringLocalizer · FusionCache · SmartFormat.NET


🎬 String Extraction

Already using IStringLocalizer? The Extractor scans your .razor, .cs, and .resx files and exports every translation string — no matter which localization backend you use.

blazor-loc interactive wizard demo

dotnet tool install -g BlazorLocalization.Extractor

# Interactive wizard — run with no arguments
blazor-loc

# Or go direct
blazor-loc extract ./src -f po -o ./translations

Upload the generated files to Crowdin, Lokalise, or any translation management system. See Extractor CLI for recipes, CI integration, and export formats.


Comparison

Feature Built-in .resx OrchardCore PO BlazorLocalization
Over-the-air updates
Distributed cache (Redis, etc.)
Plural support ✓ — CLDR 46, ordinals, select
Source text as fallback Key = text* ✓ — separate key + source text
Named placeholders ✓ — via SmartFormat
External provider support ✓ — pluggable
Merge-conflict-free ✗ — XML ✗ — PO files ✓ — with OTA providers. File-based providers are opt-in
Automated string extraction Manual Manual Roslyn-based CLI
Reusable definitions ✓ — define once, use anywhere
Standard IStringLocalizer
Battle-tested ✓ — 20+ years Production use, actively maintained

* OrchardCore uses the IStringLocalizer indexer key as both the lookup key and the source text. Updating the original text creates a new entry — existing translations are orphaned.


Documentation

Topic Description
Examples Translation() usage — simple, placeholders, plurals, ordinals, select, inline translations, reusable definitions
Extractor CLI Install, interactive wizard, common recipes, CI integration, export formats
Configuration Cache settings, appsettings.json binding, multiple providers, code-only config
Crowdin Provider Over-the-air translations from Crowdin — distribution hash, export formats, error handling
JSON File Provider Load translations from flat JSON files on disk
PO File Provider Load translations from GNU gettext PO files
Samples Runnable Blazor Server and Web API projects with full setup

FAQ

Can I load translations from a database?
Yes. Implement ITranslationProvider (one method) and BlazorLocalization handles caching, fallback, and hot-swapping. See the JsonFile provider as a reference.

Does this only work with Blazor?
No — anything that uses IStringLocalizer: Blazor, MVC, Razor Pages, Web APIs, minimal APIs.

Do I need a translation provider?
No. Inline translations work on their own. Add a provider when you're ready for external files or a translation platform.

Is this production-ready?
Used in production. Born from real frustration with .resx. If you find it useful, give it a ⭐.


Contributing

Contributions welcome! Each package has a CONTRIBUTING.md with architecture decisions, coding patterns, and how to run tests.

Built a translation provider for a platform not yet covered? Consider submitting it as a package.

License

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on BlazorLocalization.Extensions:

Package Downloads
BlazorLocalization.TranslationProvider.Crowdin

Crowdin translation provider for BlazorLocalization. Fetches translations over-the-air — update text without redeployment.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
10.3.0 103 4/1/2026
10.2.1 91 3/31/2026
10.2.0 85 3/31/2026
10.1.0 93 3/29/2026
10.0.2 97 3/27/2026