{"id":24151323,"url":"https://github.com/xaviersolau/blazorjsonlocalization","last_synced_at":"2025-04-04T18:04:17.562Z","repository":{"id":40253896,"uuid":"338338681","full_name":"xaviersolau/BlazorJsonLocalization","owner":"xaviersolau","description":"Provides JSON-based Blazor localization support. ","archived":false,"fork":false,"pushed_at":"2025-03-15T14:54:57.000Z","size":756,"stargazers_count":52,"open_issues_count":3,"forks_count":5,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-28T17:06:35.012Z","etag":null,"topics":["blazor","dotnet","i18n","json","l10n","localization","web"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xaviersolau.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-12T14:16:39.000Z","updated_at":"2025-03-16T19:58:56.000Z","dependencies_parsed_at":"2023-10-03T04:45:54.319Z","dependency_job_id":"cc876719-1430-4781-a4ff-6c708e37b604","html_url":"https://github.com/xaviersolau/BlazorJsonLocalization","commit_stats":{"total_commits":85,"total_committers":5,"mean_commits":17.0,"dds":"0.14117647058823535","last_synced_commit":"a3efbcef0fbbda267288b9b60eaa12088351ee46"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xaviersolau%2FBlazorJsonLocalization","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xaviersolau%2FBlazorJsonLocalization/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xaviersolau%2FBlazorJsonLocalization/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xaviersolau%2FBlazorJsonLocalization/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xaviersolau","download_url":"https://codeload.github.com/xaviersolau/BlazorJsonLocalization/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247226212,"owners_count":20904465,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blazor","dotnet","i18n","json","l10n","localization","web"],"created_at":"2025-01-12T09:15:12.182Z","updated_at":"2025-04-04T18:04:17.540Z","avatar_url":"https://github.com/xaviersolau.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# BlazorJsonLocalization\n\nThis project provides JSON-based Blazor localization support. It is a extension of the standard\n**Microsoft.Extensions.Localization** package.\n\nJson files can be embedded in the assemblies or stay as static assets on the HTTP host side.\n\nDon't hesitate to post issues, pull requests on the project or to fork and improve the project.\n\n## Project dashboard\n\n[![Build - CI](https://github.com/xaviersolau/BlazorJsonLocalization/actions/workflows/build-ci.yml/badge.svg)](https://github.com/xaviersolau/BlazorJsonLocalization/actions/workflows/build-ci.yml)\n[![Coverage Status](https://coveralls.io/repos/github/xaviersolau/BlazorJsonLocalization/badge.svg?branch=main)](https://coveralls.io/github/xaviersolau/BlazorJsonLocalization?branch=main)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n\n| Package                                    | Nuget.org | Pre-release |\n|--------------------------------------------|-----------|-----------|\n|**SoloX.BlazorJsonLocalization**            |[![NuGet Beta](https://img.shields.io/nuget/v/SoloX.BlazorJsonLocalization.svg)](https://www.nuget.org/packages/SoloX.BlazorJsonLocalization)|[![NuGet Beta](https://img.shields.io/nuget/vpre/SoloX.BlazorJsonLocalization.svg)](https://www.nuget.org/packages/SoloX.BlazorJsonLocalization)|\n|~~*SoloX.BlazorJsonLocalization.WebAssembly*~~|[![NuGet Beta](https://img.shields.io/nuget/v/SoloX.BlazorJsonLocalization.WebAssembly.svg)](https://www.nuget.org/packages/SoloX.BlazorJsonLocalization.WebAssembly)|[![NuGet Beta](https://img.shields.io/nuget/vpre/SoloX.BlazorJsonLocalization.svg)](https://www.nuget.org/packages/SoloX.BlazorJsonLocalization)|\n|**SoloX.BlazorJsonLocalization.ServerSide** |[![NuGet Beta](https://img.shields.io/nuget/v/SoloX.BlazorJsonLocalization.ServerSide.svg)](https://www.nuget.org/packages/SoloX.BlazorJsonLocalization.ServerSide)|[![NuGet Beta](https://img.shields.io/nuget/vpre/SoloX.BlazorJsonLocalization.svg)](https://www.nuget.org/packages/SoloX.BlazorJsonLocalization)|\n\n## License and credits\n\nBlazorJsonLocalization project is written by Xavier Solau. It's licensed under the MIT license.\n\n * * *\n\n## Features\n\n* Enable Json based localization with embedded Json files.\n* Enable Json based localization with hosted Json files.\n* Assembly scoped localizer support.\n* Structured Json support with complex objects.\n* Localizer inheritance.\n* Localizer fall back.\n* Multi-Line Json string value.\n* Both WebAssembly and Server Side support.\n* [Code first localization support](documents/LocalizationGen.md).\n\n## Installation\n\nYou can checkout this Github repository or you can use the NuGet packages:\n\n**Install using the command line from the Package Manager:**\n```bash\nInstall-Package SoloX.BlazorJsonLocalization -version 3.0.0-alpha.1\nInstall-Package SoloX.BlazorJsonLocalization.WebAssembly -version 3.0.0-alpha.1\nInstall-Package SoloX.BlazorJsonLocalization.ServerSide -version 3.0.0-alpha.1\n```\n\n**Install using the .Net CLI:**\n```bash\ndotnet add package SoloX.BlazorJsonLocalization --version 3.0.0-alpha.1\ndotnet add package SoloX.BlazorJsonLocalization.WebAssembly --version 3.0.0-alpha.1\ndotnet add package SoloX.BlazorJsonLocalization.ServerSide --version 3.0.0-alpha.1\n```\n\n**Install editing your project file (csproj):**\n```xml\n\u003cPackageReference Include=\"SoloX.BlazorJsonLocalization\" Version=\"3.0.0-alpha.1\" /\u003e\n\u003cPackageReference Include=\"SoloX.BlazorJsonLocalization.WebAssembly\" Version=\"3.0.0-alpha.1\" /\u003e\n\u003cPackageReference Include=\"SoloX.BlazorJsonLocalization.ServerSide\" Version=\"3.0.0-alpha.1\" /\u003e\n```\n\n\u003e Find out the [Breaking changes](documents/BreakingChanges.md) from one version to another.\n\n\u003e Note that from version 3.0.* the `SoloX.BlazorJsonLocalization.WebAssembly` package is obsolete.\n\n## How to use it\n\nNote that you can find code examples in this repository at this location: `src/examples`.\n\n### Set up the localizer using embedded Json resources files\n\nIf you are going to embed your Json files in your Assemblies, you just need the\n**SoloX.BlazorJsonLocalization** package to enable the localization support.\n\n#### Set up the dependency injection\n\nA few lines of code are actually needed to setup the BlazorJsonLocalizer.\nYou just need to use the name space `SoloX.BlazorJsonLocalization` to get access to\nthe right extension methods and to add the services in your `ServiceCollection` :\n\n* For Blazor WebAssembly:\n\nUpdate your `Main` method in the `Program.cs` file:\n\n```csharp\n// Here we are going to store the Json files in the project 'Resources' folder.\nbuilder.Services.AddJsonLocalization(\n    builder =\u003e builder.UseEmbeddedJson(\n        options =\u003e options.ResourcesPath = \"Resources\"));\n```\n\nBy default the current culture is going to be taken from the browser settings. But it can\nbe easily set by code with this simple code:\n\n```csharp\nvar cultureInfo = CultureInfo.GetCultureInfo(name);\nCultureInfo.DefaultThreadCurrentUICulture = cultureInfo;\n```\n\nYou can find an example in the project repository in `src/examples/SoloX.BlazorJsonLocalization.Example.Wasm`.\n\n* For Blazor Server Side:\n\nFirst add the `using Microsoft.AspNetCore.Localization` and `using SoloX.BlazorJsonLocalization` directives then update your\n`ConfigureServices` method in the `Startup.cs` file:\n\n```csharp\n// Here we are going to store the Json files in the project 'Resources' folder.\nservices.AddJsonLocalization(\n    builder =\u003e builder.UseEmbeddedJson(\n        options =\u003e options.ResourcesPath = \"Resources\"),\n        ServiceLifetime.Singleton);\n\n// AspNet core standard localization setup to get culture from the\n// Browser\nvar supportedCultures = new List\u003cCultureInfo\u003e\n{\n    new CultureInfo(\"en\"),\n    new CultureInfo(\"fr\")\n};\nservices.Configure\u003cRequestLocalizationOptions\u003e(options =\u003e\n{\n    options.DefaultRequestCulture = new RequestCulture(\"en\");\n    options.SupportedUICultures = supportedCultures;\n});\n```\n\nNote that it is also possible to provide custom `JsonSerializerOptions` in the `JsonSerializerOptions` options property.\n\n```csharp\n// Here we are going to store the Json files in the project 'Resources' folder\n// and we provide custom JsonSerializerOptions.\nservices.AddJsonLocalization(\n    builder =\u003e builder.UseEmbeddedJson(\n        options =\u003e\n        {\n            options.ResourcesPath = \"Resources\";\n            options.JsonSerializerOptions = yourCustomOptions;\n        }),\n        ServiceLifetime.Singleton);\n```\n\n\nAnd update your `Configure` method in the Startup.cs file:\n\n```csharp\n// AspNet core standard localization setup to get culture from the\n// Browser\napp.UseRequestLocalization();\n```\n\nWith this configuration, you will be able to get the culture from the browser. If you want to\ndefine the culture by code you can go to the Microsoft documentation:\n[Provide UI to choose the culture](https://docs.microsoft.com/fr-fr/aspnet/core/blazor/globalization-localization?view=aspnetcore-5.0#provide-ui-to-choose-the-culture).\nYou will find a nice solution for this purpose.\nIn addition you can find an example in the BlazorJsonLocalizer project repository in\n`src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide`.\n\n#### Enable localization support in your component\n\nLet's say that we are going to use the localization in the `Index` page. The first thing to do\nis to create your Json resource files that are actually going to contain the translated text.\nYou will add the Json files in the project \"Resources\" folder (since we have defined it in the\noptions `ResourcesPath` property).\nThe folders hierarchy is also important to avoid name collision so if your component is in a\nsub-folder your Json files must also be in the same sub-folder.\n\n\u003e For example if your `Index` page is in the `Pages` sub-folder, your Index Json files must\n\u003e be in the same sub-folder: `Resources/Pages` with `Resources` the resources path defined\n\u003e in the options.\n\n##### Write your localization Json files\n\nThe file must be named with the component name (In our case `Index`) and suffixed with `CultureInfo` name or the\nISO2 language code:\n\n| File name     | Description              |\n|---------------|--------------------------|\n| Index.fr.json | French translated text.  |\n| Index.de.json | German translated text.  |\n| Index.en.json | English translated text. |\n| Index.json    | Since there is no language code, this file is going to be used as fall back when the language is unknown. |\n\n\u003e Note that if you want to get the localization resources for your\n\u003e component `MyComponent` and for the French `CultureInfo` (fr-FR) the\n\u003e factory will first try to load `MyComponent.fr-FR.json`. If the file\n\u003e is not found, it will try to load `MyComponent.fr.json` and finally\n\u003e if the file is still not found, it will fall back to the file `MyComponent.json`\n\nThe content of the file is using a conventional Json syntax for example\nthe English Json file will look like this:\n\n```json\n{\n  \"Hello\": \"Hello world!\",\n  \"Welcome\": \"Welcome to your new app.\"\n}\n```\n\nand the French file:\n\n```json\n{\n  \"Hello\": \"Bonjour tout le monde!\",\n  \"Welcome\": \"Bienvenue dans votre nouvelle application.\"\n}\n```\n\n\u003e **Warning: the Json file should use UTF8 encoding in order to easily handle accents or specific character set.**\n\nThe Json file need to be declared as *Embedded resources* in order to be shipped in\nthe Assembly. You can do it this way in your csproj file specifying every json file manually:\n\n```xml\n  \u003cItemGroup\u003e\n    \u003cEmbeddedResource Include=\"Resources\\Pages\\Index.fr.json\" /\u003e\n    \u003cEmbeddedResource Include=\"Resources\\Pages\\Index.json\" /\u003e\n  \u003c/ItemGroup\u003e\n```\n\nOr using the wildcards version:\n\n```xml\n  \u003cItemGroup\u003e\n    \u003cEmbeddedResource Include=\"Resources\\**\\*.json\" /\u003e\n  \u003c/ItemGroup\u003e\n```\n\n##### Multi-line Json value\n\nMulti-line Json value is supported. Let's say you have a message with multiple lines to associate on a Key.\nWe are going to use some HTML text for example:\n\n```html\n\u003cp\u003e\n    Some text.\n\u003cp\u003e\n```\n\nWe have two solutions to write you Json file, first you can use escaped new line separator `\\n` (or the windows `\\r\\n`).\n\nHere is the resulting Json:\n\n```json\n{\n  \"HtmlKey\" : \"\u003cp\u003e\\r\\n    Some text.\\r\\n\u003cp\u003e\"\n}\n```\n\nBut you have a second option using an array. In that case the Json could be like this:\n\n```json\n{\n  \"HtmlKey\" : [\n    \"\u003cp\u003e\",\n    \"    Some text.\",\n    \"\u003cp\u003e\"]\n}\n```\n\n\n##### Use the localization in your code\n\nYou will need to inject the `IStringLocalizer\u003cIndex\u003e` in the `Index` class:\n\n```csharp\n[Inject]\nprivate IStringLocalizer\u003cIndex\u003e L { get; set; }\n```\n\nor using the razor syntax in the `Index.razor` file:\n\n```razor\n@inject IStringLocalizer\u003cIndex\u003e L\n```\n\nwith the `using` declared in your `_Imorts.razor`:\n\n```razor\n@using Microsoft.Extensions.Localization\n```\n\nOnce the localizer is available you can just use it like this in the `Index.razor` file:\n\n```razor\n@page \"/\"\n\n\u003ch1\u003e@L[\"Hello\"]\u003c/h1\u003e\n\n@L[\"Welcome\"]\n```\n\n##### Structured Json support\n\nAs we have seen before, we can store key / value peer in the Json file but you also can use structured Json. For instance\nyou can associate to a given key a sub-json structure like this:\n\n```json\n{\n  \"Notification\": {\n    \"Message\": \"Some notification!\",\n    \"Description\": \"My notification description!\"\n  }\n}\n```\n\nTo access a complex object, you can directly use a key path (separated with ':'). In this case it is possible to use the\nIStringLocalizer with the key \"Notification:Message\" to get the corresponding value: \"Some notification!\".\n\n```csharp\n// Import extension methods (Get, GetSubLocalizer)\nusing SoloX.BlazorJsonLocalization;\n\n[Inject]\nIStringLocalizer\u003cIndex\u003e Localizer { get; set; }\n\n// Access with the key path:\nvar txt = Localizer[\"Notification:Message\"];\n\n// Or preferably using the Key.Path method.\nvar txt = Localizer[Key.Path(\"Notification\", \"Message\")];\n```\n\nThat said, we can use an other way to access structured object: the GetSubLocalizer extension method:\n\n```csharp\n\n// Access using a sub-localizer\nvar subLocalizer = Localizer.GetSubLocalizer(\"Notification\");\nvar txt = subLocalizer[\"Message\"];\n```\n\nThe sub-localizer can be be used as if it would contain only the structured object:\n```json\n{\n  \"Message\": \"Some notification!\",\n  \"Description\": \"My notification description!\"\n}\n```\n\n### Set up the localizer using Json static assets on the HTTP host side\n\nBasically you need to do almost the same as above except for the following points.\n\n#### Json resource files as static assets\n\nYour resource files are not embedded any more and they are located in the `wwwroot` folder\nof your project with the same naming rules.\n\n#### Dependency injection in Blazor WebAssembly\n\nOnly the **SoloX.BlazorJsonLocalization** package is needed.\n\n\u003e The **SoloX.BlazorJsonLocalization.WebAssembly** extension package is now Obsolete.\n\nThe registration of your services will look like this in the `Program.cs` file:\n\n```csharp\n// Here we are going to store the Json files in the project 'wwwroot/Resources' folder.\nbuilder.Services.AddJsonLocalization(\n    builder =\u003e builder.UseHttpClientJson(\n        options =\u003e\n        {\n            options.ApplicationAssembly = typeof(Program).Assembly;\n            options.ResourcesPath = \"Resources\";\n        }));\n```\n\nMake sure the HttpClient is registered as a service or you can also use a `IHttpClientFactory` in that case you\ncan use the `HttpClientBuilder` property in the options:\n\n```csharp\n// Here we are going to build the HttpClient from the factory.\nbuilder.Services.AddJsonLocalization(\n    builder =\u003e builder.UseHttpClientJson(\n        options =\u003e\n        {\n            options.HttpClientBuilder = serviceProvider =\u003e\n            {\n                var httpClientFactory = serviceProvider.GetRequiredService\u003cIHttpClientFactory\u003e();\n                return httpClientFactory.CreateClient(\"Host\");\n            };\n        }));\n```\n\n\u003e Note that naming your static asset file, you can change the expected file name by using\n\u003e the `NamingPolicy` delegate. So instead of naming your file `MyComponent.fr.json` you can customize it\n\u003e like this `MyComponent.fr.json?v=1.0.0.1` just by setting the `NamingPolicy` delegate to something like:\n\u003e ```csharp\n\u003e // Here we are going to add a version querystring to help with cache busting\n\u003e builder.Services.AddJsonLocalization(\n\u003e     builder =\u003e builder.UseHttpClientJson(\n\u003e         options =\u003e\n\u003e         {\n\u003e             options.ApplicationAssembly = typeof(Program).Assembly;\n\u003e             options.ResourcesPath = \"Resources\";\n\u003e             options.NamingPolicy =  \n\u003e                 (basePath, cultureName) =\u003e string.IsNullOrEmpty(cultureName)\n\u003e                     ? new Uri($\"{basePath}.json?v=1.0.0.1\", UriKind.Relative)\n\u003e                     : new Uri($\"{basePath}.{cultureName}.json?v=1.0.0.1\", UriKind.Relative);\n\u003e         }));\n\u003e ```\n\n#### Dependency injection in Blazor Server Side\n\nIn addition of the **SoloX.BlazorJsonLocalization** package you will need the\n**SoloX.BlazorJsonLocalization.ServerSide** extension package.\n\nThe registration of your services will look like this in your `ConfigureServices` method in the\n`Startup.cs` file:\n\n```csharp\n// Here we are going to store the Json files in the project 'wwwroot/Resources' folder.\nservices.AddServerSideJsonLocalization(\n    builder =\u003e builder.UseHttpHostedJson(\n        options =\u003e\n        {\n            options.ApplicationAssembly = typeof(Program).Assembly;\n            options.ResourcesPath = \"Resources\";\n        }));\n```\n\nNote that the localizer engine will load Json resources directly from the files.\nBut it is also possible to use a HttpClient instead in the case where you would like to serve the\nJson from a HTTP API Controller like this:\n\n```csharp\n// Here we are going to store the Json files in the project 'wwwroot/Resources' folder.\nservices.AddServerSideJsonLocalization(\n    builder =\u003e builder.UseHttpClientJson(\n        options =\u003e\n        {\n           ...\n        }));\n```\n\n#### Make sure your Json resources are actually loaded\n\nSince the Json resources are static assets, they need to be loaded through HTTP to be used in your\ncomponents. Thanks to a cache system, this will occur only once for each of your components but it\nmay be useful to override the `OnInitializedAsync` method with a `L.LoadAsync()` like this to make\nsure your refresh your localized text once the localization data are available:\n\n```csharp\n[Inject]\nprivate IStringLocalizer\u003cIndex\u003e L { get; set; }\n\nprotected override async Task OnInitializedAsync()\n{\n    await L.LoadAsync();\n    await base.OnInitializedAsync();\n}\n```\n\n\u003e Note that as long as the translation resources are not loaded the IStringLocalizer will always return ``...``\n\u003e unless you use the ``EnableDisplayKeysWhileLoadingAsync`` method in the ``JsonLocalizationOptionsBuilder``.\n\n\n### Inheritance and fall back\n\nLet's say that we have a localizer `Global` with some basic and reusable string, we have\nseveral options to use it.\n\nThe Global class:\n```csharp\npublic class Global\n{\n}\n```\n\nWith its Json resource file:\n```json\n{\n  \"GlobalKey\": \"This is global message...\"\n}\n```\n\n#### Injecting the Global localizer\n\nThe first option is to inject the localizer in your component\nand to use it directly alongside of the component specific localizer.\n\n```csharp\n[Inject]\nprivate IStringLocalizer\u003cGlobal\u003e Localizer { get; set; }\n```\n\n#### Using inheritance\n\nA second option is to use inheritance. Your component specific localizer can inherit `Global` in\norder to access the Global localization strings directly using you component localizer.\n\nHere is an example with a `Specific` localizer:\n\n```csharp\npublic class Specific : Global\n{\n}\n\n[Inject]\nprivate IStringLocalizer\u003cSpecific\u003e Localizer { get; set; }\n\n// Use of the GlobalKey will return the message from the Global localizer.\nvar txt = Localizer[\"GlobalKey\"]\n```\n\n#### Using a fall back\n\nYou can setup a fall back localizer in the localization options to use the fall back\nlocalizer any time where a message key is not found in a specific Localizer.\n\nHere is an example that set up a fall back to the Fallback Json files defined in a given assembly.\n\n```csharp\nbuilder.Services.AddJsonLocalization(\n    optionBuilder =\u003e\n    {\n        optionBuilder\n            // Add a localization fallback.\n            .AddFallback(\"Fallback\", assemblyWhereFallbackJsonFilesAreDefined);\n    });\n```\n\n### Scope Localizer to a specific Assembly\n\nYou may need to set up a localizer differently depending on the assembly. For example you may\nbe using embedded Json resources in an assembly that contains some components and Http hosted\nJson resources in an other assembly.\n\nIn this case, you can set up the localization options for each assembly using the `AssemblyNames`\nproperty in the localizer options object.\n\n```csharp\nbuilder.Services.AddJsonLocalization(\n    builder =\u003e\n    {\n        builder\n            .UseEmbeddedJson(options =\u003e\n            {\n                options.AssemblyNames = new[] { AssemblyWithEmbeddedJson.GetName().Name };\n                //...\n            })\n            .UseHttpClientJson(options =\u003e\n            {\n                options.AssemblyNames = new[] { AssemblyWithHttpClientJson.GetName().Name };\n                //...\n            });\n    });\n```\n\n#### Using Logs\n\nIn order to get logs while loading messages, you can setup a logger options to enable or disable logging. Default is false.\n\nHere is an example that set up use of the logger.\n\n```csharp\nbuilder.Services.AddJsonLocalization(\n    optionBuilder =\u003e\n    {\n        optionBuilder\n            // Enable logger.\n            .EnableLogger(true);\n    });\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxaviersolau%2Fblazorjsonlocalization","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxaviersolau%2Fblazorjsonlocalization","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxaviersolau%2Fblazorjsonlocalization/lists"}