Skip to content

Commit 66a39fa

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

3 files changed

Lines changed: 82 additions & 9 deletions

File tree

.changeset/twenty-ants-sip.md

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

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

Lines changed: 22 additions & 9 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,22 +864,33 @@ 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-
),
880-
[pathname, params, router, searchParams],
891+
);
892+
},
893+
[pathname, activeLocale?.id, params, router, searchParams],
881894
);
882895
};
883896

@@ -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)