BlazorLocalization.Extensions.Abstractions 10.4.0

dotnet add package BlazorLocalization.Extensions.Abstractions --version 10.4.0
                    
NuGet\Install-Package BlazorLocalization.Extensions.Abstractions -Version 10.4.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.Abstractions" Version="10.4.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="BlazorLocalization.Extensions.Abstractions" Version="10.4.0" />
                    
Directory.Packages.props
<PackageReference Include="BlazorLocalization.Extensions.Abstractions" />
                    
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.Abstractions --version 10.4.0
                    
#r "nuget: BlazorLocalization.Extensions.Abstractions, 10.4.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.Abstractions@10.4.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.Abstractions&version=10.4.0
                    
Install as a Cake Addin
#tool nuget:?package=BlazorLocalization.Extensions.Abstractions&version=10.4.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. Add the using to _Imports.razor (or the individual .razor file):

@using BlazorLocalization.Extensions

4. Use in your code:

@inject IStringLocalizer<Home> Loc

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

<p>@(Loc.Translation(key: "Home.Greeting", sourceMessage: "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) — inspect translation health and extract source strings from .razor, .cs, and .resx files NuGet dotnet tool install -g BlazorLocalization.Extractor
BlazorLocalization.Analyzers <br/> Catches localization mistakes at compile time — empty keys, duplicates, migration hints NuGet dotnet add package BlazorLocalization.Analyzers

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


🎬 CLI Tool — Inspect & Extract

A Roslyn-based CLI that understands both BlazorLocalization's Translation() API and Microsoft's built-in IStringLocalizer["key"] + .resx — no code changes or adoption required. Point it at your project and go.

dotnet tool install -g BlazorLocalization.Extractor

Inspect: Translation Health Audit

blazor-loc inspect ./src

You get a table of every translation key, where it's used, its source text, which locales have it, and whether anything is wrong. Spot duplicate keys with conflicting values, IStringLocalizer calls the scanner couldn't resolve, and .resx entries that no code references anymore — across hundreds of files in seconds.

Extract: Keep Translations in Sync

Without tooling, keeping your translation platform in sync with your code means manually copying strings — every key, every language, every time something changes. There's no built-in way to get translation strings out of a .NET project and into Crowdin, Lokalise, a database, or anywhere else.

blazor-loc extract ./src -f po -o ./translations

One command scans your entire codebase and exports every source string to PO, i18next JSON, or generic JSON. Run it in CI on every merge and your translation platform always has the latest strings.

Interactive Wizard

Run with no arguments for a guided walkthrough:

blazor-loc interactive wizard demo

blazor-loc

See Extractor CLI for all 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
Translation audit + extraction Manual Manual Roslyn-based CLI — inspect and export
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, inspect & extract commands, interactive wizard, CI integration, export formats
Analyzers Compile-time rules — empty keys, duplicates, migration from IStringLocalizer indexer
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 net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos 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.Abstractions:

Package Downloads
BlazorLocalization.Extensions

Drop-in IStringLocalizer replacement for ASP.NET Core. Pluggable translation providers, plural support, no .resx files.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
10.4.0 121 4/22/2026
10.3.0 133 4/22/2026