Skip to content

Commit 9828a9e

Browse files
committed
fix: locale switcher correctly works w/ localized Makeswift paths
1 parent 1821b03 commit 9828a9e

File tree

2 files changed

+75
-8
lines changed

2 files changed

+75
-8
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
'use server';
2+
3+
import { getSiteVersion } from '@makeswift/runtime/next/server';
4+
import { client as makeswiftClient } from '~/lib/makeswift/client';
5+
import { defaultLocale } from '~/i18n/locales';
6+
7+
const getPageInfo = async ({
8+
pathname,
9+
locale,
10+
}: {
11+
pathname: string;
12+
locale: string | undefined;
13+
}) =>
14+
makeswiftClient
15+
.getPages({
16+
locale: locale === defaultLocale ? undefined : locale,
17+
pathPrefix: pathname,
18+
siteVersion: await getSiteVersion(),
19+
})
20+
.filter((page) => page.path === pathname)
21+
.toArray()
22+
.then((pages) => (pages.length === 0 ? null : pages[0]));
23+
24+
const getPathname = (variants: Array<{ locale: string; path: string }>, locale: string) =>
25+
variants.find((v) => v.locale === locale)?.path;
26+
27+
export async function getLocalizedPathname({
28+
pathname,
29+
activeLocale,
30+
targetLocale,
31+
}: {
32+
pathname: string;
33+
activeLocale: string | undefined;
34+
targetLocale: string;
35+
}) {
36+
// fallback to page info for default locale if there is no page info for active locale
37+
const fallbackPageInfo =
38+
activeLocale === defaultLocale
39+
? Promise.resolve(null)
40+
: getPageInfo({ pathname, locale: undefined });
41+
42+
const localizedPageInfo = await getPageInfo({ pathname, locale: activeLocale });
43+
const pageInfo = localizedPageInfo ?? (await fallbackPageInfo);
44+
45+
if (pageInfo == null) {
46+
return pathname;
47+
}
48+
49+
return (
50+
getPathname(pageInfo.localizedVariants, targetLocale) ??
51+
getPathname(pageInfo.localizedVariants, defaultLocale) ??
52+
pathname
53+
);
54+
}

core/vibes/soul/primitives/navigation/index.tsx

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import { Link } from '~/components/link';
3030
import { usePathname, useRouter } from '~/i18n/routing';
3131
import { useSearch } from '~/lib/search';
3232

33+
import { getLocalizedPathname } from './_actions/localized-pathname';
34+
3335
interface Link {
3436
label: string;
3537
href: string;
@@ -862,21 +864,32 @@ function SearchResults({
862864
);
863865
}
864866

865-
const useSwitchLocale = () => {
867+
const useSwitchLocale = ({ activeLocale }: { activeLocale: Locale | undefined }) => {
866868
const pathname = usePathname();
867869
const router = useRouter();
868870
const params = useParams();
869871
const searchParams = useSearchParams();
870872

871873
return useCallback(
872-
(locale: string) =>
874+
async (locale: string) => {
875+
const localizedPathname = await getLocalizedPathname({
876+
pathname,
877+
activeLocale: activeLocale?.id,
878+
targetLocale: locale,
879+
});
880+
873881
router.push(
874-
// @ts-expect-error -- TypeScript will validate that only known `params`
875-
// are used in combination with a given `pathname`. Since the two will
876-
// always match for the current route, we can skip runtime checks.
877-
{ pathname, params, query: Object.fromEntries(searchParams.entries()) },
882+
{
883+
pathname: localizedPathname,
884+
// @ts-expect-error -- TypeScript will validate that only known `params`
885+
// are used in combination with a given `pathname`. Since the two will
886+
// always match for the current route, we can skip runtime checks.
887+
params,
888+
query: Object.fromEntries(searchParams.entries()),
889+
},
878890
{ locale },
879-
),
891+
);
892+
},
880893
[pathname, params, router, searchParams],
881894
);
882895
};
@@ -892,7 +905,7 @@ function LocaleSwitcher({
892905
}) {
893906
const activeLocale = locales.find((locale) => locale.id === activeLocaleId);
894907
const [isPending, startTransition] = useTransition();
895-
const switchLocale = useSwitchLocale();
908+
const switchLocale = useSwitchLocale({ activeLocale });
896909

897910
return (
898911
<div className={className}>

0 commit comments

Comments
 (0)