diff --git a/apps/web-client-base-net/src/WebClientBase.Client/Components/LanguageSwitcher.razor b/apps/web-client-base-net/src/WebClientBase.Client/Components/LanguageSwitcher.razor
new file mode 100644
index 00000000..f6e30ad4
--- /dev/null
+++ b/apps/web-client-base-net/src/WebClientBase.Client/Components/LanguageSwitcher.razor
@@ -0,0 +1,58 @@
+@using System.Globalization
+@inject NavigationManager Navigation
+
+
+
+
+
+ @(CultureInfo.CurrentCulture.Name.StartsWith("vi") ? "VI" : "EN")
+
+
+
+
+
+
+
+ 🇻🇳
+ Tiếng Việt
+
+
+
+
+ 🇺🇸
+ English
+
+
+
+
+
+@code {
+ private void SwitchLanguage(string targetCulture)
+ {
+ var uri = new Uri(Navigation.Uri);
+ var path = uri.PathAndQuery;
+
+ // Simple logic to replace or prepend culture segment
+ // Check if path starts with a supported culture
+ var segments = path.Split('/', StringSplitOptions.RemoveEmptyEntries);
+
+ string newPath;
+ if (segments.Length > 0 && (segments[0].Equals("vi-VN", StringComparison.OrdinalIgnoreCase) ||
+ segments[0].Equals("en-US", StringComparison.OrdinalIgnoreCase) ||
+ segments[0].Equals("vi", StringComparison.OrdinalIgnoreCase) ||
+ segments[0].Equals("en", StringComparison.OrdinalIgnoreCase)))
+ {
+ // Replace first segment
+ segments[0] = targetCulture;
+ newPath = "/" + string.Join('/', segments);
+ }
+ else
+ {
+ // Prepend
+ if (path == "/") path = "";
+ newPath = $"/{targetCulture}{path}";
+ }
+
+ Navigation.NavigateTo(newPath, forceLoad: true);
+ }
+}
diff --git a/apps/web-client-base-net/src/WebClientBase.Client/Layout/MainLayout.razor b/apps/web-client-base-net/src/WebClientBase.Client/Layout/MainLayout.razor
index 0e141bd0..0658f10c 100644
--- a/apps/web-client-base-net/src/WebClientBase.Client/Layout/MainLayout.razor
+++ b/apps/web-client-base-net/src/WebClientBase.Client/Layout/MainLayout.razor
@@ -1,4 +1,5 @@
@inherits LayoutComponentBase
+@inject IStringLocalizer L
@@ -8,12 +9,12 @@
-
+
@@ -92,7 +94,7 @@
document.documentElement.setAttribute('data-theme', theme);
}
-
+