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}
/>
-
+