Reputation: 63
I am not able to find any reference/ solution to set the culture in the Blazor app through cookies in a pre-rendered application.
Please help me to find one.
Upvotes: 0
Views: 569
Reputation: 1
Add to _Host.cshtml
@{
var rqf = HttpContext.Request.Headers.AcceptLanguage;
var language = Request.GetTypedHeaders()
.AcceptLanguage
?.OrderByDescending(x => x.Quality ?? 1)
.Select(x => x.Value.ToString())
.First() ?? null;
if (language!=null)
{
var culture = new CultureInfo(languages);
CultureInfo.DefaultThreadCurrentCulture = culture;
CultureInfo.DefaultThreadCurrentUICulture = culture;
}
}
<component type="typeof(ProImprover.Client.App)" render-mode="WebAssemblyPrerendered" />
Upvotes: 0
Reputation: 31
I had the same problem and figured out a solution. It's not the nicest one but it works:
First, I configured localization in Progam.cs in the server project (assuming .NET 6):
builder.Services.AddLocalization();
...
...
string[] cultures = {"de","en","nl" };
app.UseRequestLocalization(new RequestLocalizationOptions()
.SetDefaultCulture(cultures.First())
.AddSupportedCultures(cultures)
.AddSupportedUICultures(cultures));
In _Host.cshtml (also on the server) you can intercept the initial request to customize the current culture. For instance, check for query string value or preferred language cookie.
@page "/"
@namespace blazor.Client
@using System.Globalization
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
Layout = "_Layout";
//use the default culture from server initials request
var requestCulture = CultureInfo.CurrentCulture.Name;
//get culture from query string
if (Request.Query.ContainsKey("culture"))
{
var lang = Request.Query["culture"].ToString();
requestCulture = lang;
//todo: place language cookie
}
//get culture from cookie
if (Request.Cookies.TryGetValue(CookieRequestCultureProvider.DefaultCookieName, out var value))
{
var fromCookie = CookieRequestCultureProvider.ParseCookieValue(value).Cultures.First().Value;
requestCulture = fromCookie;
}
and then you pass the current culture to the App component (also in _Host.cshtml)
<component
type="typeof(App)"
param-SelectedCulture="requestCulture"
render-mode="WebAssemblyPrerendered" />
The custom culture is passed to the App component via 'param-SelectedCulture' as a string value.
In App.razor you can assign this value to CurrentInfo.DefaultThread like so:
@using System.Globalization
<AppState>
<Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
</AppState>
@code {
[Parameter] public string SelectedCulture { get; set; } = default!;
protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
var selectedCulture = new CultureInfo(SelectedCulture);
CultureInfo.DefaultThreadCurrentCulture = selectedCulture;
CultureInfo.DefaultThreadCurrentUICulture = selectedCulture;
}
}
}
In your client app you can set a language cookie after the user selects a different language. After setting the cookie, reload the page:
NavigationManager.NavigateTo("/",true)
Upvotes: 2