From 47b854de26dea24e7838fd0804df103dee99635f Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Fri, 28 Jan 2022 18:19:24 +0100 Subject: chore(i18n): replace i18n provider and helpers --- src/config/website.ts | 1 + src/pages/404.tsx | 6 +-- src/pages/_app.tsx | 26 ++++++------ src/pages/article/[slug].tsx | 11 +++-- src/pages/blog/index.tsx | 32 +++++++------- src/pages/contact.tsx | 16 +++---- src/pages/cv.tsx | 22 +++++----- src/pages/index.tsx | 23 +++++------ src/pages/mentions-legales.tsx | 24 +++++------ src/pages/projet/[slug].tsx | 4 +- src/pages/projets.tsx | 4 +- src/pages/recherche/index.tsx | 14 +++---- src/pages/sujet/[slug].tsx | 22 +++++----- src/pages/thematique/[slug].tsx | 26 ++++++------ src/utils/helpers/i18n.ts | 92 ++++++++--------------------------------- 15 files changed, 131 insertions(+), 192 deletions(-) (limited to 'src') diff --git a/src/config/website.ts b/src/config/website.ts index 1b0e2d3..a359d9a 100644 --- a/src/config/website.ts +++ b/src/config/website.ts @@ -10,6 +10,7 @@ export const config = { locales: { defaultLocale: 'fr', defaultCountry: 'FR', + supported: ['en', 'fr'], }, postsPerPage: 10, twitterId: '@ArmandPhilippot', diff --git a/src/pages/404.tsx b/src/pages/404.tsx index 5ba7b95..64c74ba 100644 --- a/src/pages/404.tsx +++ b/src/pages/404.tsx @@ -2,12 +2,12 @@ import { getLayout } from '@components/Layouts/Layout'; import PostHeader from '@components/PostHeader/PostHeader'; import { seo } from '@config/seo'; import { t, Trans } from '@lingui/macro'; +import styles from '@styles/pages/Page.module.scss'; import { NextPageWithLayout } from '@ts/types/app'; -import { defaultLocale, loadTranslation } from '@utils/helpers/i18n'; +import { loadTranslation } from '@utils/helpers/i18n'; import { GetStaticProps, GetStaticPropsContext } from 'next'; import Head from 'next/head'; import Link from 'next/link'; -import styles from '@styles/pages/Page.module.scss'; const error404: NextPageWithLayout = () => { return ( @@ -40,7 +40,7 @@ export const getStaticProps: GetStaticProps = async ( ) => { const breadcrumbTitle = t`Error`; const { locale } = context; - const translation = await loadTranslation(locale || defaultLocale); + const translation = await loadTranslation(locale); return { props: { diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index db021f9..ec97ff7 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,23 +1,21 @@ -import { useEffect } from 'react'; -import { i18n } from '@lingui/core'; -import { I18nProvider } from '@lingui/react'; +import { config } from '@config/website'; import { AppPropsWithLayout } from '@ts/types/app'; -import { activateLocale, defaultLocale, initLingui } from '@utils/helpers/i18n'; -import '../styles/globals.scss'; import { ThemeProvider } from 'next-themes'; - -initLingui(defaultLocale); +import { useRouter } from 'next/router'; +import { IntlProvider } from 'react-intl'; +import '../styles/globals.scss'; const MyApp = ({ Component, pageProps }: AppPropsWithLayout) => { - const locale: string = pageProps.locale || defaultLocale; - - useEffect(() => { - activateLocale(locale, pageProps.translation); - }); + const { locale, defaultLocale } = useRouter(); + const appLocale: string = locale || config.locales.defaultLocale; const getLayout = Component.getLayout ?? ((page) => page); return ( - + { > {getLayout()} - + ); }; diff --git a/src/pages/article/[slug].tsx b/src/pages/article/[slug].tsx index d38ff63..ce9c22b 100644 --- a/src/pages/article/[slug].tsx +++ b/src/pages/article/[slug].tsx @@ -3,11 +3,14 @@ import CommentsList from '@components/CommentsList/CommentsList'; import { getLayout } from '@components/Layouts/Layout'; import PostFooter from '@components/PostFooter/PostFooter'; import PostHeader from '@components/PostHeader/PostHeader'; +import Sidebar from '@components/Sidebar/Sidebar'; +import { Sharing, ToC } from '@components/Widgets'; import { config } from '@config/website'; import { getAllPostsSlug, getPostBySlug } from '@services/graphql/queries'; +import styles from '@styles/pages/Page.module.scss'; import { NextPageWithLayout } from '@ts/types/app'; import { ArticleMeta, ArticleProps } from '@ts/types/articles'; -import { defaultLocale, loadTranslation } from '@utils/helpers/i18n'; +import { loadTranslation } from '@utils/helpers/i18n'; import { addPrismClasses, translateCopyButton } from '@utils/helpers/prism'; import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from 'next'; import Head from 'next/head'; @@ -15,9 +18,6 @@ import { useRouter } from 'next/router'; import Prism from 'prismjs'; import { ParsedUrlQuery } from 'querystring'; import { useEffect } from 'react'; -import styles from '@styles/pages/Page.module.scss'; -import { Sharing, ToC } from '@components/Widgets'; -import Sidebar from '@components/Sidebar/Sidebar'; import { Blog, BlogPosting, Graph, WebPage } from 'schema-dts'; const SingleArticle: NextPageWithLayout = ({ post }) => { @@ -163,7 +163,7 @@ export const getStaticProps: GetStaticProps = async ( context: GetStaticPropsContext ) => { const { locale } = context; - const translation = await loadTranslation(locale || defaultLocale); + const translation = await loadTranslation(locale); const { slug } = context.params as PostParams; const post = await getPostBySlug(slug); const breadcrumbTitle = post.title; @@ -171,7 +171,6 @@ export const getStaticProps: GetStaticProps = async ( return { props: { breadcrumbTitle, - locale, post, translation, }, diff --git a/src/pages/blog/index.tsx b/src/pages/blog/index.tsx index 0650cfb..8e42e02 100644 --- a/src/pages/blog/index.tsx +++ b/src/pages/blog/index.tsx @@ -1,25 +1,25 @@ -import { GetStaticProps, GetStaticPropsContext } from 'next'; -import Head from 'next/head'; -import { t } from '@lingui/macro'; +import { Button } from '@components/Buttons'; import { getLayout } from '@components/Layouts/Layout'; +import PaginationCursor from '@components/PaginationCursor/PaginationCursor'; +import PostHeader from '@components/PostHeader/PostHeader'; +import PostsList from '@components/PostsList/PostsList'; +import Sidebar from '@components/Sidebar/Sidebar'; +import Spinner from '@components/Spinner/Spinner'; +import { ThematicsList, TopicsList } from '@components/Widgets'; import { seo } from '@config/seo'; import { config } from '@config/website'; -import { NextPageWithLayout } from '@ts/types/app'; -import { BlogPageProps, PostsList as PostsListData } from '@ts/types/blog'; -import { defaultLocale, loadTranslation } from '@utils/helpers/i18n'; -import PostsList from '@components/PostsList/PostsList'; -import useSWRInfinite from 'swr/infinite'; -import { Button } from '@components/Buttons'; +import { t } from '@lingui/macro'; import { getPublishedPosts } from '@services/graphql/queries'; -import PostHeader from '@components/PostHeader/PostHeader'; -import { ThematicsList, TopicsList } from '@components/Widgets'; -import Sidebar from '@components/Sidebar/Sidebar'; import styles from '@styles/pages/Page.module.scss'; +import { NextPageWithLayout } from '@ts/types/app'; +import { BlogPageProps, PostsList as PostsListData } from '@ts/types/blog'; +import { loadTranslation } from '@utils/helpers/i18n'; +import { GetStaticProps, GetStaticPropsContext } from 'next'; +import Head from 'next/head'; +import { useRouter } from 'next/router'; import { useEffect, useRef, useState } from 'react'; -import Spinner from '@components/Spinner/Spinner'; import { Blog as BlogSchema, Graph, WebPage } from 'schema-dts'; -import { useRouter } from 'next/router'; -import PaginationCursor from '@components/PaginationCursor/PaginationCursor'; +import useSWRInfinite from 'swr/infinite'; const Blog: NextPageWithLayout = ({ fallback }) => { const lastPostRef = useRef(null); @@ -167,7 +167,7 @@ export const getStaticProps: GetStaticProps = async ( const breadcrumbTitle = t`Blog`; const data = await getPublishedPosts({ first: config.postsPerPage }); const { locale } = context; - const translation = await loadTranslation(locale || defaultLocale); + const translation = await loadTranslation(locale); return { props: { diff --git a/src/pages/contact.tsx b/src/pages/contact.tsx index cb88b7d..464854d 100644 --- a/src/pages/contact.tsx +++ b/src/pages/contact.tsx @@ -1,21 +1,21 @@ import { ButtonSubmit } from '@components/Buttons'; import { Form, FormItem, Input, TextArea } from '@components/Form'; import { getLayout } from '@components/Layouts/Layout'; +import PostHeader from '@components/PostHeader/PostHeader'; +import Sidebar from '@components/Sidebar/Sidebar'; +import { SocialMedia } from '@components/Widgets'; import { seo } from '@config/seo'; +import { config } from '@config/website'; import { t } from '@lingui/macro'; import { sendMail } from '@services/graphql/mutations'; +import styles from '@styles/pages/Page.module.scss'; import { NextPageWithLayout } from '@ts/types/app'; -import { defaultLocale, loadTranslation } from '@utils/helpers/i18n'; +import { loadTranslation } from '@utils/helpers/i18n'; import { GetStaticProps, GetStaticPropsContext } from 'next'; import Head from 'next/head'; +import { useRouter } from 'next/router'; import { FormEvent, useState } from 'react'; -import PostHeader from '@components/PostHeader/PostHeader'; -import styles from '@styles/pages/Page.module.scss'; -import { SocialMedia } from '@components/Widgets'; -import Sidebar from '@components/Sidebar/Sidebar'; import { ContactPage as ContactPageSchema, Graph, WebPage } from 'schema-dts'; -import { config } from '@config/website'; -import { useRouter } from 'next/router'; const ContactPage: NextPageWithLayout = () => { const [name, setName] = useState(''); @@ -178,7 +178,7 @@ export const getStaticProps: GetStaticProps = async ( ) => { const breadcrumbTitle = t`Contact`; const { locale } = context; - const translation = await loadTranslation(locale || defaultLocale); + const translation = await loadTranslation(locale); return { props: { diff --git a/src/pages/cv.tsx b/src/pages/cv.tsx index 85bddd6..a851c38 100644 --- a/src/pages/cv.tsx +++ b/src/pages/cv.tsx @@ -1,19 +1,19 @@ import { getLayout } from '@components/Layouts/Layout'; +import PostHeader from '@components/PostHeader/PostHeader'; +import Sidebar from '@components/Sidebar/Sidebar'; +import { CVPreview, SocialMedia, ToC } from '@components/Widgets'; import { seo } from '@config/seo'; +import { config } from '@config/website'; +import CVContent, { intro, meta, pdf, image } from '@content/pages/cv.mdx'; +import { t } from '@lingui/macro'; +import styles from '@styles/pages/Page.module.scss'; import { NextPageWithLayout } from '@ts/types/app'; +import { ArticleMeta } from '@ts/types/articles'; +import { loadTranslation } from '@utils/helpers/i18n'; import { GetStaticProps, GetStaticPropsContext } from 'next'; import Head from 'next/head'; -import CVContent, { intro, meta, pdf, image } from '@content/pages/cv.mdx'; -import PostHeader from '@components/PostHeader/PostHeader'; -import { ArticleMeta } from '@ts/types/articles'; -import styles from '@styles/pages/Page.module.scss'; -import { CVPreview, SocialMedia, ToC } from '@components/Widgets'; -import { t } from '@lingui/macro'; -import Sidebar from '@components/Sidebar/Sidebar'; -import { AboutPage, Graph, WebPage } from 'schema-dts'; -import { config } from '@config/website'; import { useRouter } from 'next/router'; -import { defaultLocale, loadTranslation } from '@utils/helpers/i18n'; +import { AboutPage, Graph, WebPage } from 'schema-dts'; const CV: NextPageWithLayout = () => { const router = useRouter(); @@ -113,7 +113,7 @@ export const getStaticProps: GetStaticProps = async ( ) => { const breadcrumbTitle = meta.title; const { locale } = context; - const translation = await loadTranslation(locale || defaultLocale); + const translation = await loadTranslation(locale); return { props: { diff --git a/src/pages/index.tsx b/src/pages/index.tsx index ae5fe4b..264c45a 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,18 +1,18 @@ -import type { ReactElement } from 'react'; -import { GetStaticProps, GetStaticPropsContext } from 'next'; -import Head from 'next/head'; +import FeedIcon from '@assets/images/icon-feed.svg'; +import { ButtonLink } from '@components/Buttons'; +import { ContactIcon } from '@components/Icons'; import Layout from '@components/Layouts/Layout'; import { seo } from '@config/seo'; -import { NextPageWithLayout } from '@ts/types/app'; -import { defaultLocale, loadTranslation } from '@utils/helpers/i18n'; +import { config } from '@config/website'; import HomePageContent from '@content/pages/homepage.mdx'; -import { ButtonLink } from '@components/Buttons'; -import styles from '@styles/pages/Home.module.scss'; import { t } from '@lingui/macro'; -import FeedIcon from '@assets/images/icon-feed.svg'; -import { ContactIcon } from '@components/Icons'; +import styles from '@styles/pages/Home.module.scss'; +import { NextPageWithLayout } from '@ts/types/app'; +import { loadTranslation } from '@utils/helpers/i18n'; +import { GetStaticProps, GetStaticPropsContext } from 'next'; +import Head from 'next/head'; +import type { ReactElement } from 'react'; import { Graph, WebPage } from 'schema-dts'; -import { config } from '@config/website'; const Home: NextPageWithLayout = () => { const CodingLinks = () => { @@ -141,11 +141,10 @@ export const getStaticProps: GetStaticProps = async ( context: GetStaticPropsContext ) => { const { locale } = context; - const translation = await loadTranslation(locale || defaultLocale); + const translation = await loadTranslation(locale); return { props: { - locale, translation, }, }; diff --git a/src/pages/mentions-legales.tsx b/src/pages/mentions-legales.tsx index c9d2ccd..e13a7e2 100644 --- a/src/pages/mentions-legales.tsx +++ b/src/pages/mentions-legales.tsx @@ -1,22 +1,22 @@ import { getLayout } from '@components/Layouts/Layout'; +import PostHeader from '@components/PostHeader/PostHeader'; +import Sidebar from '@components/Sidebar/Sidebar'; +import { ToC } from '@components/Widgets'; import { seo } from '@config/seo'; -import { NextPageWithLayout } from '@ts/types/app'; -import { defaultLocale, loadTranslation } from '@utils/helpers/i18n'; -import { GetStaticProps, GetStaticPropsContext } from 'next'; -import Head from 'next/head'; +import { config } from '@config/website'; import LegalNoticeContent, { intro, meta, } from '@content/pages/legal-notice.mdx'; -import PostHeader from '@components/PostHeader/PostHeader'; -import { ArticleMeta } from '@ts/types/articles'; +import { t } from '@lingui/macro'; import styles from '@styles/pages/Page.module.scss'; -import { ToC } from '@components/Widgets'; -import Sidebar from '@components/Sidebar/Sidebar'; -import { Article, Graph, WebPage } from 'schema-dts'; -import { config } from '@config/website'; +import { NextPageWithLayout } from '@ts/types/app'; +import { ArticleMeta } from '@ts/types/articles'; +import { loadTranslation } from '@utils/helpers/i18n'; +import { GetStaticProps, GetStaticPropsContext } from 'next'; +import Head from 'next/head'; import { useRouter } from 'next/router'; -import { t } from '@lingui/macro'; +import { Article, Graph, WebPage } from 'schema-dts'; const LegalNotice: NextPageWithLayout = () => { const router = useRouter(); @@ -107,7 +107,7 @@ export const getStaticProps: GetStaticProps = async ( ) => { const breadcrumbTitle = meta.title; const { locale } = context; - const translation = await loadTranslation(locale || defaultLocale); + const translation = await loadTranslation(locale); return { props: { diff --git a/src/pages/projet/[slug].tsx b/src/pages/projet/[slug].tsx index 847f84c..14ddf9c 100644 --- a/src/pages/projet/[slug].tsx +++ b/src/pages/projet/[slug].tsx @@ -11,7 +11,7 @@ import { Project as ProjectData, ProjectProps, } from '@ts/types/app'; -import { defaultLocale, loadTranslation } from '@utils/helpers/i18n'; +import { loadTranslation } from '@utils/helpers/i18n'; import { getAllProjectsFilename, getProjectData, @@ -133,7 +133,7 @@ export const getStaticProps: GetStaticProps = async ( ) => { const breadcrumbTitle = ''; const { locale } = context; - const translation = await loadTranslation(locale || defaultLocale); + const translation = await loadTranslation(locale); const { slug } = context.params as ProjectParams; const project = await getProjectData(slug); diff --git a/src/pages/projets.tsx b/src/pages/projets.tsx index 4359721..263973d 100644 --- a/src/pages/projets.tsx +++ b/src/pages/projets.tsx @@ -6,7 +6,7 @@ import { config } from '@config/website'; import PageContent, { meta } from '@content/pages/projects.mdx'; import styles from '@styles/pages/Projects.module.scss'; import { Project } from '@ts/types/app'; -import { defaultLocale, loadTranslation } from '@utils/helpers/i18n'; +import { loadTranslation } from '@utils/helpers/i18n'; import { getSortedProjects } from '@utils/helpers/projects'; import { GetStaticProps, GetStaticPropsContext } from 'next'; import Head from 'next/head'; @@ -92,7 +92,7 @@ export const getStaticProps: GetStaticProps = async ( const breadcrumbTitle = meta.title; const { locale } = context; const projects: Project[] = await getSortedProjects(); - const translation = await loadTranslation(locale || defaultLocale); + const translation = await loadTranslation(locale); return { props: { diff --git a/src/pages/recherche/index.tsx b/src/pages/recherche/index.tsx index 7f410e8..c3c71f3 100644 --- a/src/pages/recherche/index.tsx +++ b/src/pages/recherche/index.tsx @@ -1,23 +1,23 @@ import { Button } from '@components/Buttons'; import { getLayout } from '@components/Layouts/Layout'; +import PaginationCursor from '@components/PaginationCursor/PaginationCursor'; import PostHeader from '@components/PostHeader/PostHeader'; import PostsList from '@components/PostsList/PostsList'; +import Sidebar from '@components/Sidebar/Sidebar'; +import Spinner from '@components/Spinner/Spinner'; +import { ThematicsList, TopicsList } from '@components/Widgets'; import { config } from '@config/website'; import { t } from '@lingui/macro'; import { getPublishedPosts } from '@services/graphql/queries'; +import styles from '@styles/pages/Page.module.scss'; import { NextPageWithLayout } from '@ts/types/app'; import { PostsList as PostsListData } from '@ts/types/blog'; +import { loadTranslation } from '@utils/helpers/i18n'; import { GetStaticProps, GetStaticPropsContext } from 'next'; import Head from 'next/head'; import { useRouter } from 'next/router'; import { useEffect, useRef, useState } from 'react'; import useSWRInfinite from 'swr/infinite'; -import Sidebar from '@components/Sidebar/Sidebar'; -import { ThematicsList, TopicsList } from '@components/Widgets'; -import styles from '@styles/pages/Page.module.scss'; -import Spinner from '@components/Spinner/Spinner'; -import PaginationCursor from '@components/PaginationCursor/PaginationCursor'; -import { defaultLocale, loadTranslation } from '@utils/helpers/i18n'; const Search: NextPageWithLayout = () => { const [query, setQuery] = useState(''); @@ -147,7 +147,7 @@ export const getStaticProps: GetStaticProps = async ( ) => { const breadcrumbTitle = t`Search`; const { locale } = context; - const translation = await loadTranslation(locale || defaultLocale); + const translation = await loadTranslation(locale); return { props: { diff --git a/src/pages/sujet/[slug].tsx b/src/pages/sujet/[slug].tsx index 9947758..65ea2fd 100644 --- a/src/pages/sujet/[slug].tsx +++ b/src/pages/sujet/[slug].tsx @@ -1,22 +1,22 @@ import { getLayout } from '@components/Layouts/Layout'; +import PostHeader from '@components/PostHeader/PostHeader'; import PostPreview from '@components/PostPreview/PostPreview'; +import Sidebar from '@components/Sidebar/Sidebar'; +import { RelatedThematics, ToC, TopicsList } from '@components/Widgets'; +import { config } from '@config/website'; import { t } from '@lingui/macro'; +import { getAllTopicsSlug, getTopicBySlug } from '@services/graphql/queries'; +import styles from '@styles/pages/Page.module.scss'; import { NextPageWithLayout } from '@ts/types/app'; +import { ArticleMeta } from '@ts/types/articles'; import { TopicProps, ThematicPreview } from '@ts/types/taxonomies'; -import { defaultLocale, loadTranslation } from '@utils/helpers/i18n'; +import { loadTranslation } from '@utils/helpers/i18n'; import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from 'next'; +import Head from 'next/head'; +import { useRouter } from 'next/router'; import { ParsedUrlQuery } from 'querystring'; -import styles from '@styles/pages/Page.module.scss'; -import { getAllTopicsSlug, getTopicBySlug } from '@services/graphql/queries'; -import PostHeader from '@components/PostHeader/PostHeader'; -import { ArticleMeta } from '@ts/types/articles'; -import { RelatedThematics, ToC, TopicsList } from '@components/Widgets'; import { useRef } from 'react'; -import Head from 'next/head'; -import Sidebar from '@components/Sidebar/Sidebar'; import { Article as Article, Graph, WebPage } from 'schema-dts'; -import { config } from '@config/website'; -import { useRouter } from 'next/router'; const Topic: NextPageWithLayout = ({ topic }) => { const relatedThematics = useRef([]); @@ -152,7 +152,7 @@ export const getStaticProps: GetStaticProps = async ( context: GetStaticPropsContext ) => { const { locale } = context; - const translation = await loadTranslation(locale || defaultLocale); + const translation = await loadTranslation(locale); const { slug } = context.params as PostParams; const topic = await getTopicBySlug(slug); const breadcrumbTitle = topic.title; diff --git a/src/pages/thematique/[slug].tsx b/src/pages/thematique/[slug].tsx index 9955089..d263ee9 100644 --- a/src/pages/thematique/[slug].tsx +++ b/src/pages/thematique/[slug].tsx @@ -1,25 +1,25 @@ import { getLayout } from '@components/Layouts/Layout'; +import PostHeader from '@components/PostHeader/PostHeader'; import PostPreview from '@components/PostPreview/PostPreview'; +import Sidebar from '@components/Sidebar/Sidebar'; +import { RelatedTopics, ThematicsList, ToC } from '@components/Widgets'; +import { config } from '@config/website'; import { t } from '@lingui/macro'; -import { NextPageWithLayout } from '@ts/types/app'; -import { TopicPreview, ThematicProps } from '@ts/types/taxonomies'; -import { defaultLocale, loadTranslation } from '@utils/helpers/i18n'; -import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from 'next'; -import { ParsedUrlQuery } from 'querystring'; -import styles from '@styles/pages/Page.module.scss'; import { getAllThematicsSlug, getThematicBySlug, } from '@services/graphql/queries'; -import PostHeader from '@components/PostHeader/PostHeader'; -import { RelatedTopics, ThematicsList, ToC } from '@components/Widgets'; -import { useRef } from 'react'; +import styles from '@styles/pages/Page.module.scss'; +import { NextPageWithLayout } from '@ts/types/app'; import { ArticleMeta } from '@ts/types/articles'; +import { TopicPreview, ThematicProps } from '@ts/types/taxonomies'; +import { loadTranslation } from '@utils/helpers/i18n'; +import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from 'next'; import Head from 'next/head'; -import Sidebar from '@components/Sidebar/Sidebar'; -import { Article, Graph, WebPage } from 'schema-dts'; -import { config } from '@config/website'; import { useRouter } from 'next/router'; +import { ParsedUrlQuery } from 'querystring'; +import { useRef } from 'react'; +import { Article, Graph, WebPage } from 'schema-dts'; const Thematic: NextPageWithLayout = ({ thematic }) => { const relatedTopics = useRef([]); @@ -142,7 +142,7 @@ export const getStaticProps: GetStaticProps = async ( context: GetStaticPropsContext ) => { const { locale } = context; - const translation = await loadTranslation(locale || defaultLocale); + const translation = await loadTranslation(locale); const { slug } = context.params as PostParams; const thematic = await getThematicBySlug(slug); const breadcrumbTitle = thematic.title; diff --git a/src/utils/helpers/i18n.ts b/src/utils/helpers/i18n.ts index 4439906..dd010c4 100644 --- a/src/utils/helpers/i18n.ts +++ b/src/utils/helpers/i18n.ts @@ -1,86 +1,28 @@ -import { messages as messagesEn } from '@i18n/en/messages.js'; -import { messages as messagesFr } from '@i18n/fr/messages.js'; -import { i18n, Messages } from '@lingui/core'; -import { en, fr } from 'make-plural/plurals'; +import { config } from '@config/website'; +import { readFile } from 'fs/promises'; +import path from 'path'; -type Catalog = { - messages: Messages; -}; - -export const locales = { - en: 'English', - fr: 'Français', -}; - -export const defaultLocale = 'fr'; +type Messages = { [key: string]: string }; /** - * Load the translation with the correct method depending on environment. - * - * @param {string} locale - The current locale. - * @returns {Promise} The translated messages. + * Load the translation for the provided locale. + * @param currentLocale - The current locale. + * @returns {Promise} The translated strings. */ -export async function loadTranslation(locale: string): Promise { - let catalog: Catalog; - - try { - if (process.env.NODE_ENV === 'production') { - catalog = await import(`src/i18n/${locale}/messages`); - } else { - catalog = await import(`@lingui/loader!src/i18n/${locale}/messages.po`); - } +export async function loadTranslation( + currentLocale: string | undefined +): Promise { + const locale: string = currentLocale || config.locales.defaultLocale; - return catalog.messages; - } catch (error) { - console.error('Error while loading translation.'); - throw error; - } -} - -/** - * Init lingui. - * - * @param {string} locale - The locale to activate. - * @param {Messages} [messages] - The compiled translation. - */ -export function initLingui(locale: string, messages?: Messages) { - try { - i18n.loadLocaleData({ - en: { plurals: en }, - fr: { plurals: fr }, - }); - - if (messages) { - i18n.load(locale, messages); - } else { - i18n.load({ - en: messagesEn, - fr: messagesFr, - }); - } - - i18n.activate(locale, Object.keys(locales)); - } catch (error) { - console.error('Error while Lingui init.'); - throw error; - } -} - -/** - * Activate the given locale. - * - * @param {string} locale - The locale to activate. - * @param {Messages} messages - The compiled translation. - */ -export function activateLocale(currentLocale: string, messages: Messages) { - const locale: string = Object.keys(locales).includes(currentLocale) - ? currentLocale - : defaultLocale; + const languagePath = path.join(process.cwd(), `lang/${locale}.json`); try { - initLingui(locale, messages); + const contents = await readFile(languagePath, 'utf8'); + return JSON.parse(contents); } catch (error) { - console.error(`Error while activating ${currentLocale}`); + console.error( + 'Error: Could not load compiled language files. Please run `yarn run i18n:compile` first."' + ); throw error; } } -- cgit v1.2.3 From e4d5b8151802517b2943756fc0d09ffa95e2c4e2 Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Sat, 29 Jan 2022 18:21:37 +0100 Subject: chore: replace lingui functions with react-intl --- src/components/Branding/Branding.tsx | 24 +- src/components/Breadcrumb/Breadcrumb.tsx | 46 +- .../Buttons/ButtonToolbar/ButtonToolbar.tsx | 27 +- src/components/Comment/Comment.tsx | 39 +- src/components/CommentForm/CommentForm.tsx | 45 +- src/components/CommentsList/CommentsList.tsx | 20 +- src/components/Footer/Footer.tsx | 10 +- src/components/FooterNav/FooterNav.tsx | 18 +- src/components/Icons/Copyright/Copyright.tsx | 3 +- src/components/Icons/Moon/Moon.tsx | 11 +- src/components/Icons/Sun/Sun.tsx | 11 +- src/components/Layouts/Layout.tsx | 14 +- src/components/MDX/CodeBlock/CodeBlock.tsx | 6 +- src/components/MainNav/MainNav.tsx | 66 ++- .../PaginationCursor/PaginationCursor.tsx | 21 +- src/components/PostFooter/PostFooter.tsx | 11 +- src/components/PostMeta/PostMeta.tsx | 118 ++++- src/components/PostPreview/PostPreview.tsx | 31 +- src/components/PostsList/PostsList.tsx | 25 +- src/components/ProjectPreview/ProjectPreview.tsx | 22 +- src/components/ProjectSummary/ProjectSummary.tsx | 68 ++- src/components/SearchForm/SearchForm.tsx | 17 +- .../Settings/ReduceMotion/ReduceMotion.tsx | 18 +- src/components/Settings/Settings.tsx | 10 +- .../Settings/ThemeToggle/ThemeToggle.tsx | 8 +- src/components/Spinner/Spinner.tsx | 11 +- .../ExpandableWidget/ExpandableWidget.tsx | 13 +- src/components/Widgets/CVPreview/CVPreview.tsx | 16 +- src/components/Widgets/RecentPosts/RecentPosts.tsx | 16 +- .../Widgets/RelatedThematics/RelatedThematics.tsx | 12 +- .../Widgets/RelatedTopics/RelatedTopics.tsx | 12 +- src/components/Widgets/Sharing/Sharing.tsx | 42 +- .../Widgets/ThematicsList/ThematicsList.tsx | 13 +- src/components/Widgets/ToC/ToC.tsx | 8 +- src/components/Widgets/TopicsList/TopicsList.tsx | 13 +- src/config/nav.ts | 14 - src/config/seo.ts | 33 -- src/config/sharing.ts | 4 +- src/config/website.ts | 4 +- src/i18n/en.json | 586 +++++++++++++++++++++ src/i18n/fr.json | 586 +++++++++++++++++++++ src/pages/404.tsx | 62 ++- src/pages/article/[slug].tsx | 6 +- src/pages/blog/index.tsx | 78 ++- src/pages/contact.tsx | 95 +++- src/pages/cv.tsx | 55 +- src/pages/index.tsx | 69 ++- src/pages/mentions-legales.tsx | 35 +- src/pages/projets.tsx | 30 +- src/pages/recherche/index.tsx | 68 ++- src/pages/sujet/[slug].tsx | 20 +- src/pages/thematique/[slug].tsx | 20 +- src/utils/helpers/i18n.ts | 23 +- src/utils/helpers/prism.ts | 22 +- 54 files changed, 2314 insertions(+), 341 deletions(-) delete mode 100644 src/config/nav.ts delete mode 100644 src/config/seo.ts create mode 100644 src/i18n/en.json create mode 100644 src/i18n/fr.json (limited to 'src') diff --git a/src/components/Branding/Branding.tsx b/src/components/Branding/Branding.tsx index 01948e9..efb3a49 100644 --- a/src/components/Branding/Branding.tsx +++ b/src/components/Branding/Branding.tsx @@ -1,17 +1,18 @@ -import Image from 'next/image'; -import Link from 'next/link'; -import { ReactElement } from 'react'; -import { t } from '@lingui/macro'; import photo from '@assets/images/armand-philippot.jpg'; import { config } from '@config/website'; -import styles from './Branding.module.scss'; import Head from 'next/head'; +import Image from 'next/image'; +import Link from 'next/link'; +import { ReactElement } from 'react'; +import { useIntl } from 'react-intl'; import { Person, WithContext } from 'schema-dts'; +import styles from './Branding.module.scss'; import Logo from './Logo/Logo'; type BrandingReturn = ({ isHome }: { isHome: boolean }) => ReactElement; const Branding: BrandingReturn = ({ isHome = false }) => { + const intl = useIntl(); const TitleTag = isHome ? 'h1' : 'p'; const schemaJsonLd: WithContext = { @@ -38,10 +39,15 @@ const Branding: BrandingReturn = ({ isHome = false }) => {
{t({
diff --git a/src/components/Breadcrumb/Breadcrumb.tsx b/src/components/Breadcrumb/Breadcrumb.tsx index 7c8eb5c..30179be 100644 --- a/src/components/Breadcrumb/Breadcrumb.tsx +++ b/src/components/Breadcrumb/Breadcrumb.tsx @@ -1,12 +1,13 @@ import { config } from '@config/website'; -import { t } from '@lingui/macro'; import Head from 'next/head'; import Link from 'next/link'; import { useRouter } from 'next/router'; +import { useIntl } from 'react-intl'; import { BreadcrumbList, WithContext } from 'schema-dts'; import styles from './Breadcrumb.module.scss'; const Breadcrumb = ({ pageTitle }: { pageTitle: string }) => { + const intl = useIntl(); const router = useRouter(); const isHome = router.pathname === '/'; @@ -20,14 +21,24 @@ const Breadcrumb = ({ pageTitle }: { pageTitle: string }) => { <>
  • - {t`Home`} + + {intl.formatMessage({ + defaultMessage: 'Home', + description: 'Breadcrumb: Home item', + })} +
  • {(isArticle || isThematic || isSubject) && ( <>
  • - {t`Blog`} + + {intl.formatMessage({ + defaultMessage: 'Blog', + description: 'Breadcrumb: Blog item', + })} +
  • @@ -36,7 +47,12 @@ const Breadcrumb = ({ pageTitle }: { pageTitle: string }) => { <>
  • - {t`Projects`} + + {intl.formatMessage({ + defaultMessage: 'Projects', + description: 'Breadcrumb: Projects item', + })} +
  • @@ -51,7 +67,10 @@ const Breadcrumb = ({ pageTitle }: { pageTitle: string }) => { const homepage: BreadcrumbList['itemListElement'] = { '@type': 'ListItem', position: 1, - name: t`Home`, + name: intl.formatMessage({ + defaultMessage: 'Home', + description: 'Breadcrumb: Home item', + }), item: config.url, }; @@ -61,7 +80,10 @@ const Breadcrumb = ({ pageTitle }: { pageTitle: string }) => { const blog: BreadcrumbList['itemListElement'] = { '@type': 'ListItem', position: 2, - name: t`Blog`, + name: intl.formatMessage({ + defaultMessage: 'Blog', + description: 'Breadcrumb: Blog item', + }), item: `${config.url}/blog`, }; @@ -72,7 +94,10 @@ const Breadcrumb = ({ pageTitle }: { pageTitle: string }) => { const blog: BreadcrumbList['itemListElement'] = { '@type': 'ListItem', position: 2, - name: t`Projects`, + name: intl.formatMessage({ + defaultMessage: 'Projects', + description: 'Breadcrumb: Projects item', + }), item: `${config.url}/projets`, }; @@ -108,7 +133,12 @@ const Breadcrumb = ({ pageTitle }: { pageTitle: string }) => { {!isHome && ( )} diff --git a/src/components/Buttons/ButtonToolbar/ButtonToolbar.tsx b/src/components/Buttons/ButtonToolbar/ButtonToolbar.tsx index 246ad80..e9f6079 100644 --- a/src/components/Buttons/ButtonToolbar/ButtonToolbar.tsx +++ b/src/components/Buttons/ButtonToolbar/ButtonToolbar.tsx @@ -1,6 +1,6 @@ import { CloseIcon, CogIcon, SearchIcon } from '@components/Icons'; -import { t } from '@lingui/macro'; import { ForwardedRef, forwardRef, SetStateAction } from 'react'; +import { useIntl } from 'react-intl'; import styles from '../Buttons.module.scss'; type ButtonType = 'search' | 'settings'; @@ -17,6 +17,7 @@ const ButtonToolbar = ( }, ref: ForwardedRef ) => { + const intl = useIntl(); const ButtonIcon = () => (type === 'search' ? : ); const btnClasses = isActivated ? `${styles.toolbar} ${styles['toolbar--activated']}` @@ -38,9 +39,29 @@ const ButtonToolbar = ( {isActivated ? ( - {t`Close ${type}`} + + {intl.formatMessage( + { + defaultMessage: 'Close {type}', + description: 'ButtonToolbar: Close button', + }, + { + type, + } + )} + ) : ( - {t`Open ${type}`} + + {intl.formatMessage( + { + defaultMessage: 'Open {type}', + description: 'ButtonToolbar: Open button', + }, + { + type, + } + )} + )} ); diff --git a/src/components/Comment/Comment.tsx b/src/components/Comment/Comment.tsx index 6eb0184..e95a378 100644 --- a/src/components/Comment/Comment.tsx +++ b/src/components/Comment/Comment.tsx @@ -1,7 +1,6 @@ import { Button } from '@components/Buttons'; import CommentForm from '@components/CommentForm/CommentForm'; import { config } from '@config/website'; -import { t } from '@lingui/macro'; import { Comment as CommentData } from '@ts/types/comments'; import { getFormattedDate } from '@utils/helpers/format'; import Head from 'next/head'; @@ -9,6 +8,7 @@ import Image from 'next/image'; import Link from 'next/link'; import { useRouter } from 'next/router'; import { useEffect, useRef, useState } from 'react'; +import { useIntl } from 'react-intl'; import { Comment as CommentSchema, WithContext } from 'schema-dts'; import styles from './Comment.module.scss'; @@ -21,6 +21,7 @@ const Comment = ({ comment: CommentData; isNested?: boolean; }) => { + const intl = useIntl(); const router = useRouter(); const locale = router.locale ? router.locale : config.locales.defaultLocale; const [isReply, setIsReply] = useState(false); @@ -48,7 +49,16 @@ const Comment = ({ minute: 'numeric', }) .replace(':', 'h'); - return t`${date} at ${time}`; + return intl.formatMessage( + { + defaultMessage: '{date} at {time}', + description: 'Comment: publication date', + }, + { + date, + time, + } + ); }; const getApprovedComment = () => { @@ -68,7 +78,12 @@ const Comment = ({ {getCommentAuthor()}
    -
    {t`Published on:`}
    +
    + {intl.formatMessage({ + defaultMessage: 'Published on:', + description: 'Comment: publication date label', + })} +