This project provides JSON-based Blazor localization support. It is a extension of the standard Microsoft.Extensions.Localization package.
Json files can be embedded in the assemblies or stay as static assets on the HTTP host side.
Don't hesitate to post issues, pull requests on the project or to fork and improve the project.
Package | Nuget.org | Pre-release |
---|---|---|
SoloX.BlazorJsonLocalization | ||
SoloX.BlazorJsonLocalization.WebAssembly | ||
SoloX.BlazorJsonLocalization.ServerSide |
BlazorJsonLocalization project is written by Xavier Solau. It's licensed under the MIT license.
You can checkout this Github repository or you can use the NuGet packages:
Install using the command line from the Package Manager:
Install-Package SoloX.BlazorJsonLocalization -version 1.0.3-alpha.3
Install-Package SoloX.BlazorJsonLocalization.WebAssembly -version 1.0.3-alpha.3
Install-Package SoloX.BlazorJsonLocalization.ServerSide -version 1.0.3-alpha.3
Install using the .Net CLI:
dotnet add package SoloX.BlazorJsonLocalization --version 1.0.3-alpha.3
dotnet add package SoloX.BlazorJsonLocalization.WebAssembly --version 1.0.3-alpha.3
dotnet add package SoloX.BlazorJsonLocalization.ServerSide --version 1.0.3-alpha.3
Install editing your project file (csproj):
<PackageReference Include="SoloX.BlazorJsonLocalization" Version="1.0.3-alpha.3" />
<PackageReference Include="SoloX.BlazorJsonLocalization.WebAssembly" Version="1.0.3-alpha.3" />
<PackageReference Include="SoloX.BlazorJsonLocalization.ServerSide" Version="1.0.3-alpha.3" />
Note that you can find code examples in this repository at this location: src/examples
.
If you are going to embed your Json files in your Assemblies, you just need the SoloX.BlazorJsonLocalization package to enable the localization support.
A few lines of code are actually needed to setup the BlazorJsonLocalizer.
You just need to use the name space SoloX.BlazorJsonLocalization
to get access to
the right extension methods and to add the services in your ServiceCollection
:
- For Blazor WebAssembly:
Update your Main
method in the Program.cs
file:
// Here we are going to store the Json files in the project 'Resources' folder.
builder.Services.AddJsonLocalization(
builder => builder.UseEmbeddedJson(
options => options.ResourcesPath = "Resources"));
By default the current culture is going to be taken from the browser settings. But it can be easily set by code with this simple code:
var cultureInfo = CultureInfo.GetCultureInfo(name);
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
You can find an example in the project repository in src/examples/SoloX.BlazorJsonLocalization.Example.Wasm
.
- For Blazor Server Side:
First add the using Microsoft.AspNetCore.Localization
directive and update your
ConfigureServices
method in the Startup.cs
file:
// Here we are going to store the Json files in the project 'Resources' folder.
services.AddJsonLocalization(
builder => builder.UseEmbeddedJson(
options => options.ResourcesPath = "Resources"),
ServiceLifetime.Singleton);
// AspNet core standard localization setup to get culture from the
// Browser
var supportedCultures = new List<CultureInfo>
{
new CultureInfo("en"),
new CultureInfo("fr")
};
services.Configure<RequestLocalizationOptions>(options =>
{
options.DefaultRequestCulture = new RequestCulture("en");
options.SupportedUICultures = supportedCultures;
});
Note that it is also possible to provide custom JsonSerializerOptions
in the JsonSerializerOptions
options property.
// Here we are going to store the Json files in the project 'Resources' folder
// and we provide custom JsonSerializerOptions.
services.AddJsonLocalization(
builder => builder.UseEmbeddedJson(
options =>
{
options.ResourcesPath = "Resources";
options.JsonSerializerOptions = yourCustomOptions;
}),
ServiceLifetime.Singleton);
And update your Configure
method in the Startup.cs file:
// AspNet core standard localization setup to get culture from the
// Browser
app.UseRequestLocalization();
With this configuration, you will be able to get the culture from the browser. If you want to
define the culture by code you can go to the Microsoft documentation:
Provide UI to choose the culture.
You will find a nice solution for this purpose.
In addition you can find an example in the BlazorJsonLocalizer project repository in
src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide
.
Let's say that we are going to use the localization in the Index
page. The first thing to do
is to create your Json resource files that are actually going to contain the translated text.
You will add the Json files in the project "Resources" folder (since we have defined it in the
options ResourcesPath
property).
The folders hierarchy is also important to avoid name collision so if your component is in a
sub-folder your Json files must also be in the same sub-folder.
For example if your
Index
page is in thePages
sub-folder, your Index Json files must be in the same sub-folder:Resources/Pages
withResources
the resources path defined in the options.
The file must be named with the component name (In our case Index
) and suffixed with CultureInfo
name or the
ISO2 language code:
File name | Description |
---|---|
Index-fr.json | French translated text. |
Index-de.json | German translated text. |
Index-en.json | English translated text. |
Index.json | Since there is no language code, this file is going to be used as fall back when the language is unknown. |
Note that if you want to get the localization resources for your component
MyComponent
and for the FrenchCultureInfo
(fr-FR) the factory will first try to loadMyComponent-fr-FR.json
. If the file is not found, it will try to loadMyComponent-fr.json
and finally if the file is still not found, it will fall back to the fileMyComponent.json
The content of the file is using a conventional Json syntax for example the English Json file will look like this:
{
"Hello": "Hello world!",
"Welcome": "Welcome to your new app."
}
and the French file:
{
"Hello": "Bonjour tout le monde!",
"Welcome": "Bienvenue dans votre nouvelle application."
}
Warning: the Json file should use UTF8 encoding in order to easily handle accents or specific character set.
The Json file need to be declared as Embedded resources in order to be shipped in the Assembly. You can do it this way in your csproj file specifying every json file manually:
<ItemGroup>
<EmbeddedResource Include="Resources\Pages\Index-fr.json" />
<EmbeddedResource Include="Resources\Pages\Index.json" />
</ItemGroup>
Or using the wildcards version:
<ItemGroup>
<EmbeddedResource Include="Resources\**\*.json" />
</ItemGroup>
You will need to inject the IStringLocalizer<Index>
in the Index
class:
[Inject]
private IStringLocalizer<Index> L { get; set; }
or using the razor syntax in the Index.razor
file:
@inject IStringLocalizer<Index> L
with the using
declared in your _Imorts.razor
:
@using Microsoft.Extensions.Localization
Once the localizer is available you can just use it like this in the Index.razor
file:
@page "/"
<h1>@L["Hello"]</h1>
@L["Welcome"]
Basically you need to do almost the same as above except for the following points.
Your resource files are not embedded any more and they are located in the wwwroot
folder
of your project with the same naming rules.
In addition of the SoloX.BlazorJsonLocalization package you will need the SoloX.BlazorJsonLocalization.WebAssembly extension package.
The registration of your services will look like this in the Program.cs
file:
// Here we are going to store the Json files in the project 'wwwroot/Resources' folder.
builder.Services.AddWebAssemblyJsonLocalization(
builder => builder.UseHttpHostedJson(
options =>
{
options.ApplicationAssembly = typeof(Program).Assembly;
options.ResourcesPath = "Resources";
}));
Note that naming your static asset file, you can change the expected file name by using the
NamingPolicy
delegate. So instead of naming your fileMyComponent-fr.json
you can customize it like thisMyComponent.fr.json?v=1.0.0.1
it by setting theNamingPolicy
delegate to something like:// Here we are going to change the culture separator to a dot `.` instead of a `-` // and add a version querystring to help with cache busting builder.Services.AddWebAssemblyJsonLocalization( builder => builder.UseHttpHostedJson( options => { options.ApplicationAssembly = typeof(Program).Assembly; options.ResourcesPath = "Resources"; options.NamingPolicy = (basePath, cultureName) => string.IsNullOrEmpty(cultureName) ? new Uri($"{basePath}.json?v=1.0.0.1", UriKind.Relative) : new Uri($"{basePath}.{cultureName}.json?v=1.0.0.1", UriKind.Relative); }));
In addition of the SoloX.BlazorJsonLocalization package you will need the SoloX.BlazorJsonLocalization.ServerSide extension package.
The registration of your services will look like this in your ConfigureServices
method in the
Startup.cs
file:
// Here we are going to store the Json files in the project 'wwwroot/Resources' folder.
services.AddServerSideJsonLocalization(
builder => builder.UseHttpHostedJson(
options =>
{
options.ApplicationAssembly = typeof(Program).Assembly;
options.ResourcesPath = "Resources";
}));
Since the Json resources are static assets, they need to be loaded through HTTP to be used in your
components. Thanks to a cache system, this will occur only once for each of your components but it
may be useful to override the OnInitializedAsync
method with a L.LoadAsync()
like this to make
sure your refresh your localized text once the localization data are available:
[Inject]
private IStringLocalizer<Index> L { get; set; }
protected override async Task OnInitializedAsync()
{
await L.LoadAsync();
await base.OnInitializedAsync();
}
Note that as long as the translation resources are not loaded the IStringLocalizer will always return
...
unless you use theEnableDisplayKeysWhileLoadingAsync
method in theJsonLocalizationOptionsBuilder
.