@inject ILocalizationProvider LocalizationProvider
@inject NavigationManager Navigation
@inject IJSRuntime JS
@code {
private string selected = "zh";
private readonly Dictionary options = new(StringComparer.OrdinalIgnoreCase)
{
{ "zh", "ÖÐÎÄ" },
{ "en", "English" }
};
protected override async Task OnInitializedAsync()
{
var current = LocalizationProvider.CurrentCulture;
var mapping = new Dictionary(StringComparer.OrdinalIgnoreCase)
{
{ "zh", "zh-Hans" },
{ "en", "en-US" }
};
var found = mapping.FirstOrDefault(kv => string.Equals(kv.Value, current, StringComparison.OrdinalIgnoreCase)).Key;
if (!string.IsNullOrEmpty(found)) selected = found;
LocalizationProvider.LanguageChanged += (s, c) =>
{
var found2 = mapping.FirstOrDefault(kv => string.Equals(kv.Value, c, StringComparison.OrdinalIgnoreCase)).Key;
if (!string.IsNullOrEmpty(found2)) selected = found2;
StateHasChanged();
};
}
private async Task OnChange(ChangeEventArgs e)
{
if (e?.Value is string val)
{
selected = val;
await LocalizationProvider.SetCultureAsync(selected);
try
{
// Use NavigationManager to inspect and modify the current client-side path
var relative = Navigation.ToBaseRelativePath(Navigation.Uri).Trim('/');
var segments = string.IsNullOrEmpty(relative) ? Array.Empty() : relative.Split('/', StringSplitOptions.RemoveEmptyEntries);
var mapping = new Dictionary(StringComparer.OrdinalIgnoreCase)
{
{ "zh", "zh-Hans" },
{ "en", "en-US" }
};
string newUrl;
if (segments.Length > 0 && mapping.ContainsKey(segments[0]))
{
// replace existing locale prefix
var remaining = segments.Length > 1 ? "/" + string.Join('/', segments.Skip(1)) : "/";
newUrl = "/" + selected + remaining;
}
else
{
// keep current path, but trigger remount by navigating to same URI
newUrl = Navigation.Uri;
}
// trigger client-side navigation (no hard reload) so components remount and re-evaluate localizer
Navigation.NavigateTo(newUrl, forceLoad: false);
return;
}
catch
{
// fallback: just request UI refresh
StateHasChanged();
}
}
}
}