From 03252b4883d1fbe0dbc1684a128536223c00b2f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89mile=20R=C3=A9?= Date: Tue, 21 Jul 2026 16:34:19 +0200 Subject: [PATCH] Close the menu cleanly when changing locale MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dismiss the user menu on language pick, and update the URL together with an optimistic identity write so the mismatch callout does not flash mid-switch. Signed-off-by: Émile Ré --- .../src/components/TopBar/TopBarUserMenu.tsx | 8 ++++++-- .../compliance-portal/src/lib/i18n/useChangeLocale.ts | 11 +++++++++-- .../compliance-portal/src/lib/i18n/useUpdateLocale.ts | 5 +++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/apps/compliance-portal/src/components/TopBar/TopBarUserMenu.tsx b/apps/compliance-portal/src/components/TopBar/TopBarUserMenu.tsx index cd4fe3428..c3daae9b0 100644 --- a/apps/compliance-portal/src/components/TopBar/TopBarUserMenu.tsx +++ b/apps/compliance-portal/src/components/TopBar/TopBarUserMenu.tsx @@ -58,7 +58,6 @@ const topBarUserMenuFragment = graphql` fragment TopBarUserMenu_identity on Identity { fullName email - locale } `; @@ -136,7 +135,12 @@ export function TopBarUserMenu({ identityKey }: TopBarUserMenuProps) { }} > {URL_LOCALES.map(code => ( - + {URL_LOCALE_LABELS[code]} ))} diff --git a/apps/compliance-portal/src/lib/i18n/useChangeLocale.ts b/apps/compliance-portal/src/lib/i18n/useChangeLocale.ts index a8d275dd9..156243091 100644 --- a/apps/compliance-portal/src/lib/i18n/useChangeLocale.ts +++ b/apps/compliance-portal/src/lib/i18n/useChangeLocale.ts @@ -44,11 +44,18 @@ export function useChangeLocale() { locale: UrlLocale, options: ChangeLocaleOptions = {}, ) => { + // Persist and navigate without sequencing them: awaiting the mutation + // before navigation left a frame where Identity.locale already matched + // the new choice but the URL still had the old prefix, flashing the + // mismatch callout. updateLocale writes the store optimistically, and + // flushSync applies the URL change in the same paint. if (options.persist) { - await updateLocale(locale); + void updateLocale(locale); } if (locale !== currentLocale) { - void navigate(replaceLocaleInPathname(pathname, locale) + search); + void navigate(replaceLocaleInPathname(pathname, locale) + search, { + flushSync: true, + }); } }, [currentLocale, navigate, pathname, search, updateLocale]); diff --git a/apps/compliance-portal/src/lib/i18n/useUpdateLocale.ts b/apps/compliance-portal/src/lib/i18n/useUpdateLocale.ts index 6856bbe06..560884cd8 100644 --- a/apps/compliance-portal/src/lib/i18n/useUpdateLocale.ts +++ b/apps/compliance-portal/src/lib/i18n/useUpdateLocale.ts @@ -53,6 +53,11 @@ export function useUpdateLocale() { await commit( { variables: { input: { locale } }, + // Keep the Relay store in sync with the URL during locale switches so + // the mismatch callout never paints a one-frame desync. + optimisticUpdater: (store) => { + store.getRoot().getLinkedRecord("viewer")?.setValue(locale, "locale"); + }, }, feedback, );