From b981a7d2da18033ee98bb4bd330755373bc75ae7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Comeau?= Date: Fri, 23 Jun 2023 10:57:59 -0300 Subject: [PATCH] refactor: next-i18next serverSideTranslations wrapper --- src/lib/utils/next-i18next-utils.ts | 56 +++++++++++++++++++++++++++++ src/pages/email.tsx | 4 +-- src/pages/expectations.tsx | 10 +++--- src/pages/landing.tsx | 7 ++-- src/pages/status.tsx | 7 ++-- 5 files changed, 67 insertions(+), 17 deletions(-) create mode 100644 src/lib/utils/next-i18next-utils.ts diff --git a/src/lib/utils/next-i18next-utils.ts b/src/lib/utils/next-i18next-utils.ts new file mode 100644 index 000000000..77116c9d9 --- /dev/null +++ b/src/lib/utils/next-i18next-utils.ts @@ -0,0 +1,56 @@ +import { FlatNamespace } from 'i18next' +import { serverSideTranslations } from 'next-i18next/serverSideTranslations' + +import nextI18nextConfig from '../../../next-i18next.config' + +/** + * The default namespaces for translations. + */ +export const defaultNamespaces: Array = ['common'] + +/** + * Retrieves namespaces based on the provided requirements. + * Note: The namespace from {@link defaultNamespaces} will always be added. + * @param namespacesRequired The namespaces required. + * @returns The retrieved namespaces. + */ +export const getNamespaces = ( + namespacesRequired: + | Readonly + | ReadonlyArray + | undefined = undefined +) => { + // default with namespaces to always needed + const namespaces: Array = defaultNamespaces + + if (!namespacesRequired) { + return namespaces + } + + if (typeof namespacesRequired === 'string') { + return [...new Set([...namespaces, namespacesRequired])] + } + + namespacesRequired + return [...new Set([...namespaces, ...namespacesRequired])] +} + +/** + * A wrapper function for server-side translations using next-i18next. + * @param locale - The locale to use for translations. If not provided, the default locale specified in `nextI18nextConfig` will be used. + * @param namespacesRequired - The namespaces required for translations. It can be a single `FlatNamespace` or an array of `FlatNamespace`. If not provided, {@link defaultNamespaces} will be used. + * @returns {Promise} - A Promise that resolves to an object containing the translations for the specified locale and namespaces. + */ +export const pageWithServerSideTranslations = async ( + locale?: string, + namespacesRequired: + | FlatNamespace + | Array + | undefined = undefined +) => { + return serverSideTranslations( + locale ?? nextI18nextConfig.i18n.defaultLocale, + getNamespaces(namespacesRequired), + nextI18nextConfig + ) +} diff --git a/src/pages/email.tsx b/src/pages/email.tsx index 305e5365b..afa00c30d 100644 --- a/src/pages/email.tsx +++ b/src/pages/email.tsx @@ -10,7 +10,6 @@ import { import { useFormik, validateYupSchema, yupToFormErrors } from 'formik' import { GetServerSideProps } from 'next' import { Trans, useTranslation } from 'next-i18next' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' import { NextSeo } from 'next-seo' import { useRouter } from 'next/router' import * as Yup from 'yup' @@ -32,6 +31,7 @@ import Layout from '../components/Layout' import Modal from '../components/Modal' import { EmailEsrfApiRequestBody } from '../lib/types' import useEmailEsrf from '../lib/useEmailEsrf' +import { pageWithServerSideTranslations } from '../lib/utils/next-i18next-utils' import { getDCTermsTitle } from '../lib/utils/seo-utils' const initialValues: EmailEsrfApiRequestBody = { @@ -330,7 +330,7 @@ const Email: FC = () => { export const getServerSideProps: GetServerSideProps = async ({ locale }) => ({ props: { - ...(await serverSideTranslations(locale ?? 'default', ['common', 'email'])), + ...(await pageWithServerSideTranslations(locale, 'email')), }, }) diff --git a/src/pages/expectations.tsx b/src/pages/expectations.tsx index 6a03935b6..a08df6c04 100644 --- a/src/pages/expectations.tsx +++ b/src/pages/expectations.tsx @@ -3,7 +3,6 @@ import { FC, MouseEventHandler, useCallback } from 'react' import { setCookie } from 'cookies-next' import { GetServerSideProps } from 'next' import { Trans, useTranslation } from 'next-i18next' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' import { NextSeo } from 'next-seo' import Router from 'next/router' @@ -11,6 +10,7 @@ import ActionButton from '../components/ActionButton' import AlertSection from '../components/AlertSection' import ExternalLink from '../components/ExternalLink' import Layout from '../components/Layout' +import { pageWithServerSideTranslations } from '../lib/utils/next-i18next-utils' import { getDCTermsTitle } from '../lib/utils/seo-utils' const Expectations: FC = () => { @@ -113,10 +113,10 @@ const Expectations: FC = () => { export const getServerSideProps: GetServerSideProps = async ({ locale }) => ({ props: { - ...(await serverSideTranslations(locale ?? 'default', [ - 'common', - 'expectations', - ])), + ...(await pageWithServerSideTranslations( + locale ?? 'default', + 'expectations' + )), }, }) diff --git a/src/pages/landing.tsx b/src/pages/landing.tsx index c74b31a9e..4855eb5a6 100644 --- a/src/pages/landing.tsx +++ b/src/pages/landing.tsx @@ -2,7 +2,6 @@ import { FC } from 'react' import { GetServerSideProps } from 'next' import { Trans, useTranslation } from 'next-i18next' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' import { NextSeo } from 'next-seo' import Link from 'next/link' @@ -10,6 +9,7 @@ import Collapse from '../components/Collapse' import ExampleImage from '../components/ExampleImage' import Layout from '../components/Layout' import LinkButton from '../components/LinkButton' +import { pageWithServerSideTranslations } from '../lib/utils/next-i18next-utils' import { getDCTermsTitle } from '../lib/utils/seo-utils' const Landing: FC = () => { @@ -126,10 +126,7 @@ const Landing: FC = () => { export const getServerSideProps: GetServerSideProps = async ({ locale }) => ({ props: { - ...(await serverSideTranslations(locale ?? 'default', [ - 'common', - 'landing', - ])), + ...(await pageWithServerSideTranslations(locale, 'landing')), }, }) diff --git a/src/pages/status.tsx b/src/pages/status.tsx index edec26dfe..e081b7e0a 100644 --- a/src/pages/status.tsx +++ b/src/pages/status.tsx @@ -11,7 +11,6 @@ import { import { useFormik, validateYupSchema, yupToFormErrors } from 'formik' import { GetServerSideProps } from 'next' import { Trans, useTranslation } from 'next-i18next' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' import { NextSeo } from 'next-seo' import Link from 'next/link' import { useRouter } from 'next/router' @@ -34,6 +33,7 @@ import Layout from '../components/Layout' import Modal from '../components/Modal' import { CheckStatusApiRequestQuery } from '../lib/types' import { useCheckStatus } from '../lib/useCheckStatus' +import { pageWithServerSideTranslations } from '../lib/utils/next-i18next-utils' import { getDCTermsTitle } from '../lib/utils/seo-utils' const initialValues: CheckStatusApiRequestQuery = { @@ -311,10 +311,7 @@ const Status: FC = () => { export const getServerSideProps: GetServerSideProps = async ({ locale }) => ({ props: { - ...(await serverSideTranslations(locale ?? 'default', [ - 'common', - 'status', - ])), + ...(await pageWithServerSideTranslations(locale, 'status')), }, })