diff --git a/website/src/components/LanguageSelector/LanguageSelector.tsx b/website/src/components/LanguageSelector/LanguageSelector.tsx index 4ed9ede91e..06a4096b60 100644 --- a/website/src/components/LanguageSelector/LanguageSelector.tsx +++ b/website/src/components/LanguageSelector/LanguageSelector.tsx @@ -3,6 +3,7 @@ import { useRouter } from "next/router"; import { useTranslation } from "next-i18next"; import { useCallback, useEffect, useMemo } from "react"; import { useCookies } from "react-cookie"; +import { getLocaleDisplayName } from "src/lib/languages"; const LanguageSelector = () => { const router = useRouter(); @@ -20,15 +21,11 @@ const LanguageSelector = () => { } }, [cookies, setCookie, router]); - const firstLetterUppercase = (str) => { - return str.charAt(0).toLocaleUpperCase() + str.slice(1); - }; - // Memo the set of locales and their display names. const localesAndNames = useMemo(() => { return router.locales.map((locale) => ({ locale, - name: firstLetterUppercase(new Intl.DisplayNames([locale], { type: "language" }).of(locale)), + name: getLocaleDisplayName(locale), })); }, [router.locales]); diff --git a/website/src/components/Messages/LabelFlagGroup.tsx b/website/src/components/Messages/LabelFlagGroup.tsx index 7e135d249a..7598627eec 100644 --- a/website/src/components/Messages/LabelFlagGroup.tsx +++ b/website/src/components/Messages/LabelFlagGroup.tsx @@ -2,6 +2,7 @@ import { Button, Flex, Tooltip } from "@chakra-ui/react"; import { useTranslation } from "next-i18next"; import { useCookies } from "react-cookie"; import { getTypeSafei18nKey } from "src/lib/i18n"; +import { getLocaleDisplayName } from "src/lib/languages"; interface LabelFlagGroupProps { values: number[]; @@ -21,7 +22,7 @@ export const LabelFlagGroup = ({ const { t } = useTranslation("labelling"); const [cookies] = useCookies(["NEXT_LOCALE"]); const currentLanguage = cookies["NEXT_LOCALE"]; - const expectedLanguageName = new Intl.DisplayNames(currentLanguage, { type: "language" }).of(expectedLanguage); + const expectedLanguageName = getLocaleDisplayName(expectedLanguage, currentLanguage); return ( {labelNames.map((name, idx) => ( diff --git a/website/src/components/Survey/TrackedTextarea.tsx b/website/src/components/Survey/TrackedTextarea.tsx index bc86a864c3..1b06d6e8a3 100644 --- a/website/src/components/Survey/TrackedTextarea.tsx +++ b/website/src/components/Survey/TrackedTextarea.tsx @@ -5,6 +5,7 @@ import { useTranslation } from "next-i18next"; import React from "react"; import { useCookies } from "react-cookie"; import { LanguageAbbreviations } from "src/lib/iso6393"; +import { getLocaleDisplayName } from "src/lib/languages"; import { colors } from "src/styles/Theme/colors"; interface TrackedTextboxProps { @@ -80,8 +81,8 @@ export const TrackedTextarea = (props: TrackedTextboxProps) => { > {detectedLang} diff --git a/website/src/lib/languages.ts b/website/src/lib/languages.ts new file mode 100644 index 0000000000..3283be7328 --- /dev/null +++ b/website/src/lib/languages.ts @@ -0,0 +1,13 @@ +/** + * Returns the locale's name. + */ +export const getLocaleDisplayName = (locale, displayLocale = undefined) => { + // Different browsers seem to handle "eu" differently from the Node server. + // Special case this to avoid a hydration failure. + if (locale === "eu") { + return "Eurakasa"; + } + const displayName = new Intl.DisplayNames([displayLocale || locale], { type: "language" }).of(locale); + // Return the Titlecased version of the language name. + return displayName.charAt(0).toLocaleUpperCase() + displayName.slice(1); +}; diff --git a/website/src/pages/messages/index.tsx b/website/src/pages/messages/index.tsx index 6c1d6f7ed4..92784bb100 100644 --- a/website/src/pages/messages/index.tsx +++ b/website/src/pages/messages/index.tsx @@ -7,6 +7,7 @@ import { MessageConversation } from "src/components/Messages/MessageConversation import { get } from "src/lib/api"; import useSWRImmutable from "swr/immutable"; export { getDefaultStaticProps as getStaticProps } from "src/lib/default_static_props"; +import { getLocaleDisplayName } from "src/lib/languages"; const MessagesDashboard = () => { const { t } = useTranslation(["message"]); @@ -28,7 +29,7 @@ const MessagesDashboard = () => { {t("recent_messages", { - language: new Intl.DisplayNames([currentLanguage], { type: "language" }).of(currentLanguage), + language: getLocaleDisplayName(currentLanguage), })}