fix(i18n): working locale switcher + RTL category sidebar
- add src/i18n/navigation.ts (next-intl createNavigation) and rewire
LanguageSwitcher to router.replace(pathname, { locale }) — the manual
next/navigation path-munging didn't switch locale reliably
- VideoTemplatesCategorySidebar: text-left → text-start, ml-auto → ms-auto
so labels/badges align correctly under dir="rtl"
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2,39 +2,24 @@
|
||||
|
||||
import { useTransition } from "react";
|
||||
import { useLocale, useTranslations } from "next-intl";
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
import { Globe } from "lucide-react";
|
||||
|
||||
import { routing, type Locale } from "@/i18n/routing";
|
||||
import { usePathname, useRouter } from "@/i18n/navigation";
|
||||
import { type Locale } from "@/i18n/routing";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
export function LanguageSwitcher({ className }: { className?: string }) {
|
||||
const locale = useLocale() as Locale;
|
||||
const t = useTranslations("langSwitcher");
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const pathname = usePathname(); // locale-agnostic (no /en prefix)
|
||||
const [isPending, startTransition] = useTransition();
|
||||
|
||||
const toggleLocale = () => {
|
||||
const nextLocale: Locale = locale === "fa" ? "en" : "fa";
|
||||
|
||||
// Strip existing locale prefix from path, then prepend new one if needed
|
||||
let newPath = pathname;
|
||||
for (const loc of routing.locales) {
|
||||
if (newPath.startsWith(`/${loc}/`)) {
|
||||
newPath = newPath.slice(loc.length + 1); // remove /en
|
||||
break;
|
||||
} else if (newPath === `/${loc}`) {
|
||||
newPath = "/";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const prefix = nextLocale === routing.defaultLocale ? "" : `/${nextLocale}`;
|
||||
const finalPath = prefix + (newPath.startsWith("/") ? newPath : `/${newPath}`);
|
||||
|
||||
startTransition(() => {
|
||||
router.push(finalPath);
|
||||
// next-intl adds/removes the locale prefix per the routing config.
|
||||
router.replace(pathname, { locale: nextLocale });
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -92,9 +92,9 @@ export function VideoTemplatesCategorySidebar({
|
||||
)}
|
||||
aria-hidden
|
||||
/>
|
||||
<span className="min-w-0 flex-1 truncate text-left">{t(category.labelKey)}</span>
|
||||
<span className="min-w-0 flex-1 truncate text-start">{t(category.labelKey)}</span>
|
||||
{category.count !== undefined ? (
|
||||
<span className="ml-auto rounded bg-gray-100 px-1.5 py-0.5 text-[11px] text-gray-500">
|
||||
<span className="ms-auto rounded bg-gray-100 px-1.5 py-0.5 text-[11px] text-gray-500">
|
||||
{category.count}
|
||||
</span>
|
||||
) : null}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import { createNavigation } from "next-intl/navigation";
|
||||
|
||||
import { routing } from "./routing";
|
||||
|
||||
// Locale-aware navigation wrappers. `usePathname` returns the path WITHOUT the locale
|
||||
// prefix, and `useRouter().replace(path, { locale })` switches locale correctly for the
|
||||
// `as-needed` prefix strategy — which manual string-munging of next/navigation does not.
|
||||
export const { Link, redirect, usePathname, useRouter, getPathname } =
|
||||
createNavigation(routing);
|
||||
Reference in New Issue
Block a user