.
+
+Add the `CultureSelector` component to the `MainLayout` component. Place the following markup inside the closing `` tag in the `Components/Layout/MainLayout.razor` file:
+
+```razor
+
+
+
+```
+
+Use the `CultureExample1` component shown in the [Demonstration component](#demonstration-component) section to study how the preceding example works.
+
+In the server project, place the following `CultureServer` component to study how globalization works for SSR components.
+
+`Components/Pages/CultureServer.razor`:
+
+```razor
+@page "/culture-server"
+@rendermode InteractiveServer
+@using System.Globalization
+
+Culture Server
+
+Culture Server
+
+
+ CurrentCulture: @CultureInfo.CurrentCulture
+
+
+Rendered values
+
+
+ - Date: @dt
+ - Number: @number.ToString("N2")
+
+
+<input> elements that don't set a type
+
+
+ The following <input> elements use
+ CultureInfo.CurrentCulture.
+
+
+
+
+<input> elements that set a type
+
+
+ The following <input> elements use
+ CultureInfo.InvariantCulture.
+
+
+
+
+@code {
+ private DateTime dt = DateTime.Now;
+ private double number = 1999.69;
+}
+```
+
+Add both the `CultureClient` and `CultureServer` components to the sidebar navigation in `Components/Layout/NavMenu.razor`:
+
+```razor
+
+
+ Culture (Server)
+
+
+
+
+
+ Culture (Client)
+
+
+```
+
+### Interactive Auto components
+
+The guidance in this section also works for components that adopt the Interactive Auto render mode:
+
+```razor
+@rendermode InteractiveAuto
+```
+
+:::moniker-end
+
## Localization
If the app doesn't already support dynamic culture selection, add the [`Microsoft.Extensions.Localization`](https://www.nuget.org/packages/Microsoft.Extensions.Localization) package to the app.
From 1fd3269e6fa45bc0982be15c3cb3989df7a3ebfa Mon Sep 17 00:00:00 2001
From: Luke Latham <1622880+guardrex@users.noreply.github.com>
Date: Fri, 23 Feb 2024 08:37:42 -0500
Subject: [PATCH 2/6] Update aspnetcore/blazor/globalization-localization.md
Co-authored-by: Hisham Bin Ateya
---
aspnetcore/blazor/globalization-localization.md | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/aspnetcore/blazor/globalization-localization.md b/aspnetcore/blazor/globalization-localization.md
index 419227591d74..a24d3adea1c6 100644
--- a/aspnetcore/blazor/globalization-localization.md
+++ b/aspnetcore/blazor/globalization-localization.md
@@ -819,18 +819,15 @@ builder.Services.AddLocalization();
var host = builder.Build();
-CultureInfo culture;
+const string defaultCulture = "en-US";
+
var js = host.Services.GetRequiredService();
var result = await js.InvokeAsync("blazorCulture.get");
+var culture = CultureInfo.GetCulture(result ?? defaultCulture);
-if (result != null)
+if (result == null)
{
- culture = new CultureInfo(result);
-}
-else
-{
- culture = new CultureInfo("en-US");
- await js.InvokeVoidAsync("blazorCulture.set", "en-US");
+ await js.InvokeVoidAsync("blazorCulture.set", defaultCulture);
}
CultureInfo.DefaultThreadCurrentCulture = culture;
From e43784215939d3ca1ed3016a556d1f493d44e6bc Mon Sep 17 00:00:00 2001
From: guardrex <1622880+guardrex@users.noreply.github.com>
Date: Fri, 23 Feb 2024 08:38:45 -0500
Subject: [PATCH 3/6] Updates
---
aspnetcore/blazor/globalization-localization.md | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/aspnetcore/blazor/globalization-localization.md b/aspnetcore/blazor/globalization-localization.md
index a24d3adea1c6..1ae79ccc0eea 100644
--- a/aspnetcore/blazor/globalization-localization.md
+++ b/aspnetcore/blazor/globalization-localization.md
@@ -433,18 +433,15 @@ builder.Services.AddLocalization();
var host = builder.Build();
-CultureInfo culture;
+const string defaultCulture = "en-US";
+
var js = host.Services.GetRequiredService();
var result = await js.InvokeAsync("blazorCulture.get");
+var culture = CultureInfo.GetCulture(result ?? defaultCulture);
-if (result != null)
-{
- culture = new CultureInfo(result);
-}
-else
+if (result == null)
{
- culture = new CultureInfo("en-US");
- await js.InvokeVoidAsync("blazorCulture.set", "en-US");
+ await js.InvokeVoidAsync("blazorCulture.set", defaultCulture);
}
CultureInfo.DefaultThreadCurrentCulture = culture;
From b2d51db7254ce4d2f7b2125ee6ddf3dfbcbcf352 Mon Sep 17 00:00:00 2001
From: guardrex <1622880+guardrex@users.noreply.github.com>
Date: Thu, 29 Feb 2024 09:46:13 -0500
Subject: [PATCH 4/6] Updates
---
.../blazor/globalization-localization.md | 38 +++++++++----------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/aspnetcore/blazor/globalization-localization.md b/aspnetcore/blazor/globalization-localization.md
index 1ae79ccc0eea..4d6e1ba67b39 100644
--- a/aspnetcore/blazor/globalization-localization.md
+++ b/aspnetcore/blazor/globalization-localization.md
@@ -185,9 +185,9 @@ Optionally, add a menu item to the navigation in the `NavMenu` component (`NavMe
Add the [`Microsoft.Extensions.Localization`](https://www.nuget.org/packages/Microsoft.Extensions.Localization) package to the app.
-The [`Accept-Language` header](https://developer.mozilla.org/docs/Web/HTTP/Headers/Accept-Language) is set by the browser and controlled by the user's language preferences in browser settings. In browser settings, a user sets one or more preferred languages in order of preference. The order of preference is used by the browser to set quality values (`q`, 0-1) for each language in the header. The following example specifies United States English, English, and Chilean Spanish with a preference for United States English or English:
+The [`Accept-Language` header](https://developer.mozilla.org/docs/Web/HTTP/Headers/Accept-Language) is set by the browser and controlled by the user's language preferences in browser settings. In browser settings, a user sets one or more preferred languages in order of preference. The order of preference is used by the browser to set quality values (`q`, 0-1) for each language in the header. The following example specifies United States English, English, and Costa Rican Spanish with a preference for United States English or English:
-**Accept-Language**: en-US,en;q=0.9,es-CL;q=0.8
+**Accept-Language**: en-US,en;q=0.9,es-CR;q=0.8
The app's culture is set by matching the first requested language that matches a supported culture of the app.
@@ -220,17 +220,17 @@ Add the following line to the `Program` file where services are registered:
builder.Services.AddLocalization();
```
-In ***server-side development***, you can specify the app's supported cultures immediately after Routing Middleware is added to the processing pipeline. The following example configures supported cultures for United States English and Chilean Spanish:
+In ***server-side development***, you can specify the app's supported cultures immediately after Routing Middleware is added to the processing pipeline. The following example configures supported cultures for United States English and Costa Rican Spanish:
```csharp
app.UseRequestLocalization(new RequestLocalizationOptions()
- .AddSupportedCultures(new[] { "en-US", "es-CL" })
- .AddSupportedUICultures(new[] { "en-US", "es-CL" }));
+ .AddSupportedCultures(new[] { "en-US", "es-CR" })
+ .AddSupportedUICultures(new[] { "en-US", "es-CR" }));
```
For information on ordering the Localization Middleware in the middleware pipeline of the `Program` file, see .
-Use the `CultureExample1` component shown in the [Demonstration component](#demonstration-component) section to study how globalization works. Issue a request with United States English (`en-US`). Switch to Chilean Spanish (`es-CL`) in the browser's language settings. Request the webpage again.
+Use the `CultureExample1` component shown in the [Demonstration component](#demonstration-component) section to study how globalization works. Issue a request with United States English (`en-US`). Switch to Costa Rican Spanish (`es-CR`) in the browser's language settings. Request the webpage again.
> [!NOTE]
> Some browsers force you to use the default language setting for both requests and the browser's own UI settings. This can make changing the language back to one that you understand difficult because all of the setting UI screens might end up in a language that you can't read. A browser such as [Opera](https://www.opera.com/download) is a good choice for testing because it permits you to set a default language for webpage requests but leave the browser's settings UI in your language.
@@ -240,7 +240,7 @@ When the culture is United States English (`en-US`), the rendered component uses
* **Date**: 6/7/2021 6:45:22 AM
* **Number**: 1,999.69
-When the culture is Chilean Spanish (`es-CL`), the rendered component uses day/month date formatting (`7/6`), 24-hour time, and period separators in numbers with a comma for the decimal value (`1.999,69`):
+When the culture is Costa Rican Spanish (`es-CR`), the rendered component uses day/month date formatting (`7/6`), 24-hour time, and period separators in numbers with a comma for the decimal value (`1.999,69`):
* **Date**: 7/6/2021 6:49:38
* **Number**: 1.999,69
@@ -323,7 +323,7 @@ CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");
> [!IMPORTANT]
> Always set and to the same culture in order to use and .
-Use the `CultureExample1` component shown in the [Demonstration component](#demonstration-component) section to study how globalization works. Issue a request with United States English (`en-US`). Switch to Chilean Spanish (`es-CL`) in the browser's language settings. Request the webpage again. When the requested language is Chilean Spanish, the app's culture remains United States English (`en-US`).
+Use the `CultureExample1` component shown in the [Demonstration component](#demonstration-component) section to study how globalization works. Issue a request with United States English (`en-US`). Switch to Costa Rican Spanish (`es-CR`) in the browser's language settings. Request the webpage again. When the requested language is Costa Rican Spanish, the app's culture remains United States English (`en-US`).
## Statically set the server-side culture
@@ -371,7 +371,7 @@ For information on ordering the Localization Middleware in the middleware pipeli
:::moniker-end
-Use the `CultureExample1` component shown in the [Demonstration component](#demonstration-component) section to study how globalization works. Issue a request with United States English (`en-US`). Switch to Chilean Spanish (`es-CL`) in the browser's language settings. Request the webpage again. When the requested language is Chilean Spanish, the app's culture remains United States English (`en-US`).
+Use the `CultureExample1` component shown in the [Demonstration component](#demonstration-component) section to study how globalization works. Issue a request with United States English (`en-US`). Switch to Costa Rican Spanish (`es-CR`) in the browser's language settings. Request the webpage again. When the requested language is Costa Rican Spanish, the app's culture remains United States English (`en-US`).
## Dynamically set the client-side culture by user preference
@@ -482,7 +482,7 @@ The following `CultureSelector` component shows how to perform the following act
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
- new CultureInfo("es-CL"),
+ new CultureInfo("es-CR"),
};
private CultureInfo Culture
@@ -559,7 +559,7 @@ After the call to `app.UseRouting` in the request processing pipeline, place the
:::moniker-end
```csharp
-var supportedCultures = new[] { "en-US", "es-CL" };
+var supportedCultures = new[] { "en-US", "es-CR" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
@@ -701,7 +701,7 @@ The following `CultureSelector` component shows how to call the `Set` method of
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
- new CultureInfo("es-CL"),
+ new CultureInfo("es-CR"),
};
protected override void OnInitialized()
@@ -870,13 +870,13 @@ The component adopts the following approaches to work for either SSR or CSR comp
new()
{
{ "en-US", "English (United States)" },
- { "es-CL", "Spanish (Chile)" }
+ { "es-CR", "Spanish (Costa Rica)" }
};
private CultureInfo[] supportedCultures = new[]
{
new CultureInfo("en-US"),
- new CultureInfo("es-CL"),
+ new CultureInfo("es-CR"),
};
private CultureInfo Culture
@@ -996,7 +996,7 @@ Set the app's default and supported cultures with .
-* Specify the app's default and supported cultures in the `Program` file. The following example configures supported cultures for United States English and Chilean Spanish.
+* Specify the app's default and supported cultures in the `Program` file. The following example configures supported cultures for United States English and Costa Rican Spanish.
```csharp
builder.Services.AddLocalization();
@@ -1237,7 +1237,7 @@ builder.Services.AddLocalization();
Immediately after Routing Middleware is added to the processing pipeline:
```csharp
-var supportedCultures = new[] { "en-US", "es-CL" };
+var supportedCultures = new[] { "en-US", "es-CR" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
@@ -1253,7 +1253,7 @@ For information on ordering the Localization Middleware in the middleware pipeli
:::moniker range="< aspnetcore-6.0"
* Add localization services to the app with .
-* Specify the app's default and supported cultures in `Startup.Configure` (`Startup.cs`). The following example configures supported cultures for United States English and Chilean Spanish.
+* Specify the app's default and supported cultures in `Startup.Configure` (`Startup.cs`). The following example configures supported cultures for United States English and Costa Rican Spanish.
In `Startup.ConfigureServices` (`Startup.cs`):
@@ -1264,7 +1264,7 @@ services.AddLocalization();
In `Startup.Configure` immediately after Routing Middleware is added to the processing pipeline:
```csharp
-var supportedCultures = new[] { "en-US", "es-CL" };
+var supportedCultures = new[] { "en-US", "es-CR" };
var localizationOptions = new RequestLocalizationOptions()
.SetDefaultCulture(supportedCultures[0])
.AddSupportedCultures(supportedCultures)
From 53fbc9bb1acce13b86087eb8f7baad1ef56a3950 Mon Sep 17 00:00:00 2001
From: guardrex <1622880+guardrex@users.noreply.github.com>
Date: Tue, 5 Mar 2024 15:34:41 -0500
Subject: [PATCH 5/6] Updates
---
.../blazor/globalization-localization.md | 41 +++++--------------
1 file changed, 11 insertions(+), 30 deletions(-)
diff --git a/aspnetcore/blazor/globalization-localization.md b/aspnetcore/blazor/globalization-localization.md
index 4d6e1ba67b39..2fd2c58f8f97 100644
--- a/aspnetcore/blazor/globalization-localization.md
+++ b/aspnetcore/blazor/globalization-localization.md
@@ -841,8 +841,7 @@ Add the following `CultureSelector` component to the `.Client` project.
The component adopts the following approaches to work for either SSR or CSR components:
* The display name of each available culture in the dropdown list is provided by a dictionary because client-side globalization data include localized text of culture display names that server-side globalization data provides. For example, server-side localization displays `English (United States)` when `en-US` is the culture and `Ingles ()` when a different culture is used. Because localization of the culture display names isn't available with Blazor WebAssembly globalization, the display name for United States English on the client for any loaded culture is just `en-US`. Using a custom dictionary permits the component to at least display full English culture names.
-* When the user selects a different culture from the dropdown list and the component is rendered on the client, JS interop sets the culture in local browser storage.
-* When user changes the culture and the component is rendered on the server, JS interop sets the culture in local browser storage and a controller action updates the localization cookie with the culture. The controller is added to the app later in the [Server project updates](#server-project-updates) section.
+* When user changes the culture, JS interop sets the culture in local browser storage and a controller action updates the localization cookie with the culture. The controller is added to the app later in the [Server project updates](#server-project-updates) section.
`Pages/CultureSelector.razor`:
@@ -886,34 +885,16 @@ The component adopts the following approaches to work for either SSR or CSR comp
{
if (CultureInfo.CurrentCulture != value)
{
- if (RuntimeInformation.IsOSPlatform(
- OSPlatform.Create("WEBASSEMBLY")))
- {
- // Running on WebAssembly in the browser
- var js = (IJSInProcessRuntime)JS;
- js.InvokeVoid("blazorCulture.set", value.Name);
-
- Navigation.NavigateTo(Navigation.Uri, forceLoad: true);
- }
- else
- {
- // Running on the server
- if (CultureInfo.CurrentCulture != value)
- {
- var js = (IJSRuntime)JS;
- js.InvokeVoidAsync("blazorCulture.set", value.Name);
-
- var uri = new Uri(Navigation.Uri).GetComponents(
- UriComponents.PathAndQuery, UriFormat.Unescaped);
- var cultureEscaped = Uri.EscapeDataString(value.Name);
- var uriEscaped = Uri.EscapeDataString(uri);
-
- Navigation.NavigateTo(
- $"Culture/Set?culture={cultureEscaped}" +
- $"&redirectUri={uriEscaped}",
- forceLoad: true);
- }
- }
+ JS.InvokeVoidAsync("blazorCulture.set", value.Name);
+
+ var uri = new Uri(Navigation.Uri)
+ .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
+ var cultureEscaped = Uri.EscapeDataString(value.Name);
+ var uriEscaped = Uri.EscapeDataString(uri);
+
+ Navigation.NavigateTo(
+ $"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
+ forceLoad: true);
}
}
}
From c98c0ad7941d850291b574b1ac0188bd2d857e41 Mon Sep 17 00:00:00 2001
From: guardrex <1622880+guardrex@users.noreply.github.com>
Date: Thu, 7 Mar 2024 12:01:35 -0500
Subject: [PATCH 6/6] Updates
---
.../blazor/globalization-localization.md | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/aspnetcore/blazor/globalization-localization.md b/aspnetcore/blazor/globalization-localization.md
index 2fd2c58f8f97..947662af7a10 100644
--- a/aspnetcore/blazor/globalization-localization.md
+++ b/aspnetcore/blazor/globalization-localization.md
@@ -778,7 +778,7 @@ If the app adopts ***per-page/component*** interactivity, make the following cha
## Dynamically set the culture in a Blazor Web App by user preference
-*This section applies to Blazor Web Apps that adopt Auto (Server and WebAssembly) interactivity with per-component interactivity location.*
+*This section applies to Blazor Web Apps that adopt Auto (Server and WebAssembly) interactivity.*
Examples of locations where an app might store a user's preference include in [browser local storage](https://developer.mozilla.org/docs/Web/API/Window/localStorage) (common for client-side scenarios), in a localization cookie or database (common for server-side scenarios), both local storage and a localization cookie (Blazor Web Apps with server and WebAssembly components), or in an external service attached to an external database and accessed by a [web API](xref:blazor/call-web-api). The following example demonstrates how to use browser local storage for client-side rendered (CSR) components and a localization cookie for server-side rendered (SSR) components.
@@ -885,16 +885,16 @@ The component adopts the following approaches to work for either SSR or CSR comp
{
if (CultureInfo.CurrentCulture != value)
{
- JS.InvokeVoidAsync("blazorCulture.set", value.Name);
+ JS.InvokeVoidAsync("blazorCulture.set", value.Name);
- var uri = new Uri(Navigation.Uri)
- .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
- var cultureEscaped = Uri.EscapeDataString(value.Name);
- var uriEscaped = Uri.EscapeDataString(uri);
+ var uri = new Uri(Navigation.Uri)
+ .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped);
+ var cultureEscaped = Uri.EscapeDataString(value.Name);
+ var uriEscaped = Uri.EscapeDataString(uri);
- Navigation.NavigateTo(
- $"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
- forceLoad: true);
+ Navigation.NavigateTo(
+ $"Culture/Set?culture={cultureEscaped}&redirectUri={uriEscaped}",
+ forceLoad: true);
}
}
}
@@ -1150,7 +1150,6 @@ Add both the `CultureClient` and `CultureServer` components to the sidebar navig
Culture (Server)
-
Culture (Client)