Skip to content
This repository has been archived by the owner on Jan 23, 2024. It is now read-only.

Commit

Permalink
fix: build locale based on validated codes and regions (calcom#11912)
Browse files Browse the repository at this point in the history
* fix: build locale based on validated codes and regions

* keep html lang stable

* fix type error
  • Loading branch information
grzpab authored Oct 16, 2023
1 parent bc81f65 commit f2ecd98
Show file tree
Hide file tree
Showing 5 changed files with 324 additions and 21 deletions.
31 changes: 23 additions & 8 deletions apps/web/lib/app-providers.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { TooltipProvider } from "@radix-ui/react-tooltip";
import { dir } from "i18next";
import type { Session } from "next-auth";
import { SessionProvider, useSession } from "next-auth/react";
import { EventCollectionProvider } from "next-collect/client";
Expand Down Expand Up @@ -77,19 +78,33 @@ const CustomI18nextProvider = (props: AppPropsWithoutNonce) => {
const locale = session?.data?.user.locale ?? props.pageProps.newLocale;

useEffect(() => {
window.document.documentElement.lang = locale;

let direction = window.document.dir || "ltr";

try {
const intlLocale = new Intl.Locale(locale);
// @ts-expect-error INFO: Typescript does not know about the Intl.Locale textInfo attribute
direction = intlLocale.textInfo?.direction;
// @ts-expect-error TS2790: The operand of a 'delete' operator must be optional.
delete window.document.documentElement["lang"];

window.document.documentElement.lang = locale;

// Next.js writes the locale to the same attribute
// https://github.com/vercel/next.js/blob/1609da2d9552fed48ab45969bdc5631230c6d356/packages/next/src/shared/lib/router/router.ts#L1786
// which can result in a race condition
// this property descriptor ensures this never happens
Object.defineProperty(window.document.documentElement, "lang", {
configurable: true,
// value: locale,
set: function (this) {
// empty setter on purpose
},
get: function () {
return locale;
},
});
} catch (error) {
console.error(error);

window.document.documentElement.lang = locale;
}

window.document.dir = direction;
window.document.dir = dir(locale);
}, [locale]);

const clientViewerI18n = useViewerI18n(locale);
Expand Down
11 changes: 3 additions & 8 deletions apps/web/pages/_document.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { IncomingMessage } from "http";
import { dir } from "i18next";
import type { NextPageContext } from "next";
import type { DocumentContext, DocumentProps } from "next/document";
import Document, { Head, Html, Main, NextScript } from "next/document";
Expand Down Expand Up @@ -50,21 +51,15 @@ class MyDocument extends Document<Props> {
render() {
const { isEmbed, embedColorScheme } = this.props;
const newLocale = this.props.newLocale || "en";
const newDir = dir(newLocale);

const nonceParsed = z.string().safeParse(this.props.nonce);
const nonce = nonceParsed.success ? nonceParsed.data : "";

const intlLocale = new Intl.Locale(newLocale);
// @ts-expect-error INFO: Typescript does not know about the Intl.Locale textInfo attribute
const direction = intlLocale.textInfo?.direction;
if (!direction) {
throw new Error("NodeJS major breaking change detected, use getTextInfo() instead.");
}

return (
<Html
lang={newLocale}
dir={direction}
dir={newDir}
style={embedColorScheme ? { colorScheme: embedColorScheme as string } : undefined}>
<Head nonce={nonce}>
<script
Expand Down
Loading

0 comments on commit f2ecd98

Please sign in to comment.