From 6743aa460997206e70934d84628941d458c4ee99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Omar=20L=C3=B3pez?= Date: Tue, 22 Aug 2023 05:34:55 -0700 Subject: [PATCH] fix: client locale inference (#10850) --- apps/web/components/I18nLanguageHandler.tsx | 34 +++++++++--- apps/web/components/PageWrapper.tsx | 4 +- apps/web/lib/app-providers.tsx | 9 ++-- apps/web/lib/core/i18n/i18n.utils.ts | 53 ------------------- apps/web/next.config.js | 4 ++ apps/web/server/lib/ssg.ts | 7 +-- apps/web/server/lib/ssr.ts | 28 +++++----- packages/config/next-i18next.config.js | 40 +++++++------- packages/lib/constants.ts | 1 + packages/lib/i18n.ts | 13 +++-- packages/trpc/server/createContext.ts | 4 +- .../routers/publicViewer/i18n.schema.ts | 9 +++- packages/ui/components/credits/Credits.tsx | 8 +-- .../ui/components/credits/credits.test.tsx | 8 +-- playwright.config.ts | 6 ++- turbo.json | 1 + 16 files changed, 102 insertions(+), 127 deletions(-) delete mode 100644 apps/web/lib/core/i18n/i18n.utils.ts diff --git a/apps/web/components/I18nLanguageHandler.tsx b/apps/web/components/I18nLanguageHandler.tsx index 81a7fb8859..5c7fe018ee 100644 --- a/apps/web/components/I18nLanguageHandler.tsx +++ b/apps/web/components/I18nLanguageHandler.tsx @@ -1,15 +1,14 @@ +import parser from "accept-language-parser"; import { useSession } from "next-auth/react"; import { useTranslation } from "next-i18next"; import { useEffect } from "react"; +import { CALCOM_VERSION } from "@calcom/lib/constants"; import { trpc } from "@calcom/trpc/react"; -// eslint-disable-next-line turbo/no-undeclared-env-vars -const vercelCommitHash = process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA || "NA"; - -export function useViewerI18n(locale: string) { +function useViewerI18n(locale: string) { return trpc.viewer.public.i18n.useQuery( - { locale, CalComVersion: vercelCommitHash }, + { locale, CalComVersion: CALCOM_VERSION }, { /** * i18n should never be clubbed with other queries, so that it's caching can be managed independently. @@ -21,13 +20,32 @@ export function useViewerI18n(locale: string) { ); } +function useClientLocale(locales: string[]) { + const session = useSession(); + // If the user is logged in, use their locale + if (session.data?.user.locale) return session.data.user.locale; + // If the user is not logged in, use the browser locale + if (typeof window !== "undefined") { + // This is the only way I found to ensure the prefetched locale is used on first render + // FIXME: Find a better way to pick the best matching locale from the browser + return parser.pick(locales, window.navigator.language, { loose: true }) || window.navigator.language; + } + // If the browser is not available, use English + return "en"; +} + +export function useClientViewerI18n(locales: string[]) { + const clientLocale = useClientLocale(locales); + return useViewerI18n(clientLocale); +} + /** * Auto-switches locale client-side to the logged in user's preference */ -const I18nLanguageHandler = () => { - const session = useSession(); +const I18nLanguageHandler = (props: { locales: string[] }) => { + const { locales } = props; const { i18n } = useTranslation("common"); - const locale = useViewerI18n(session.data?.user.locale || "en").data?.locale || i18n.language; + const locale = useClientViewerI18n(locales).data?.locale || i18n.language; useEffect(() => { // bail early when i18n = {} diff --git a/apps/web/components/PageWrapper.tsx b/apps/web/components/PageWrapper.tsx index c076ebd2da..2ac8afca7c 100644 --- a/apps/web/components/PageWrapper.tsx +++ b/apps/web/components/PageWrapper.tsx @@ -6,7 +6,7 @@ import Script from "next/script"; import "@calcom/embed-core/src/embed-iframe"; import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired"; -import { WEBAPP_URL, IS_CALCOM } from "@calcom/lib/constants"; +import { IS_CALCOM, WEBAPP_URL } from "@calcom/lib/constants"; import { buildCanonical } from "@calcom/lib/next-seo.config"; import type { AppProps } from "@lib/app-providers"; @@ -72,7 +72,7 @@ function PageWrapper(props: AppProps) { } {...seoConfig.defaultNextSeo} /> - +