diff options
Diffstat (limited to 'src/pages')
| -rw-r--r-- | src/pages/404.tsx | 66 | ||||
| -rw-r--r-- | src/pages/_app.tsx | 26 | ||||
| -rw-r--r-- | src/pages/article/[slug].tsx | 17 | ||||
| -rw-r--r-- | src/pages/blog/index.tsx | 106 | ||||
| -rw-r--r-- | src/pages/contact.tsx | 109 | ||||
| -rw-r--r-- | src/pages/cv.tsx | 75 | ||||
| -rw-r--r-- | src/pages/index.tsx | 90 | ||||
| -rw-r--r-- | src/pages/mentions-legales.tsx | 57 | ||||
| -rw-r--r-- | src/pages/projet/[slug].tsx | 4 | ||||
| -rw-r--r-- | src/pages/projets.tsx | 34 | ||||
| -rw-r--r-- | src/pages/recherche/index.tsx | 80 | ||||
| -rw-r--r-- | src/pages/sujet/[slug].tsx | 42 | ||||
| -rw-r--r-- | src/pages/thematique/[slug].tsx | 46 |
13 files changed, 529 insertions, 223 deletions
diff --git a/src/pages/404.tsx b/src/pages/404.tsx index 5ba7b95..079dead 100644 --- a/src/pages/404.tsx +++ b/src/pages/404.tsx @@ -1,46 +1,72 @@ import { getLayout } from '@components/Layouts/Layout'; import PostHeader from '@components/PostHeader/PostHeader'; -import { seo } from '@config/seo'; -import { t, Trans } from '@lingui/macro'; +import { config } from '@config/website'; +import styles from '@styles/pages/Page.module.scss'; import { NextPageWithLayout } from '@ts/types/app'; -import { defaultLocale, loadTranslation } from '@utils/helpers/i18n'; +import { getIntlInstance, 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'; +import { FormattedMessage, useIntl } from 'react-intl'; + +const Error404: NextPageWithLayout = () => { + const intl = useIntl(); + + const pageTitle = intl.formatMessage( + { + defaultMessage: 'Error 404: Page not found - {websiteName}', + description: '404Page: SEO - Page title', + }, + { websiteName: config.name } + ); + const pageDescription = intl.formatMessage({ + defaultMessage: 'Page not found.', + description: '404Page: SEO - Meta description', + }); -const error404: NextPageWithLayout = () => { return ( <> <Head> - <title>{seo.error404.title}</title> - <meta name="description" content={seo.error404.description} /> + <title>{pageTitle}</title> + <meta name="description" content={pageDescription} /> </Head> <div className={`${styles.article} ${styles['article--no-comments']}`}> - <PostHeader title={t`Page not found`} /> + <PostHeader + title={intl.formatMessage({ + defaultMessage: 'Page not found', + description: '404Page: page title', + })} + /> <div className={styles.body}> - <Trans> - Sorry, it seems that the page you are looking for does not exist. - </Trans>{' '} - <Trans> - If you think this path should work, feel free to{' '} - <Link href="/contact/">contact me</Link> with the necessary - information so that I can fix the problem. - </Trans> + <FormattedMessage + defaultMessage="Sorry, it seems that the page your are looking for does not exist. If you think this path should work, feel free to <link>contact me</link> with the necessary information so that I can fix the problem." + description="404Page: page body" + values={{ + link: (chunks: string) => ( + <Link href="/contact/"> + <a>{chunks}</a> + </Link> + ), + }} + /> </div> </div> </> ); }; -error404.getLayout = getLayout; +Error404.getLayout = getLayout; export const getStaticProps: GetStaticProps = async ( context: GetStaticPropsContext ) => { - const breadcrumbTitle = t`Error`; + const intl = await getIntlInstance(); + const breadcrumbTitle = intl.formatMessage({ + defaultMessage: 'Error 404', + description: '404Page: breadcrumb item', + }); const { locale } = context; - const translation = await loadTranslation(locale || defaultLocale); + const translation = await loadTranslation(locale); return { props: { @@ -51,4 +77,4 @@ export const getStaticProps: GetStaticProps = async ( }; }; -export default error404; +export default Error404; 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 ( - <I18nProvider i18n={i18n}> + <IntlProvider + locale={appLocale} + defaultLocale={defaultLocale} + messages={pageProps.translation} + > <ThemeProvider defaultTheme="system" enableColorScheme={true} @@ -25,7 +23,7 @@ const MyApp = ({ Component, pageProps }: AppPropsWithLayout) => { > {getLayout(<Component {...pageProps} />)} </ThemeProvider> - </I18nProvider> + </IntlProvider> ); }; diff --git a/src/pages/article/[slug].tsx b/src/pages/article/[slug].tsx index d38ff63..8668a66 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,7 @@ 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 { useIntl } from 'react-intl'; import { Blog, BlogPosting, Graph, WebPage } from 'schema-dts'; const SingleArticle: NextPageWithLayout<ArticleProps> = ({ post }) => { @@ -45,6 +46,7 @@ const SingleArticle: NextPageWithLayout<ArticleProps> = ({ post }) => { wordsCount: info.wordsCount, }; + const intl = useIntl(); const router = useRouter(); const locale = router.locale ? router.locale : config.locales.defaultLocale; const articleUrl = `${config.url}${router.asPath}`; @@ -55,8 +57,8 @@ const SingleArticle: NextPageWithLayout<ArticleProps> = ({ post }) => { }); useEffect(() => { - translateCopyButton(locale); - }, [locale]); + translateCopyButton(locale, intl); + }, [intl, locale]); const webpageSchema: WebPage = { '@id': `${articleUrl}`, @@ -163,7 +165,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 +173,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..9a86d9f 100644 --- a/src/pages/blog/index.tsx +++ b/src/pages/blog/index.tsx @@ -1,27 +1,27 @@ -import { GetStaticProps, GetStaticPropsContext } from 'next'; -import Head from 'next/head'; -import { t } from '@lingui/macro'; -import { getLayout } from '@components/Layouts/Layout'; -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 { getPublishedPosts } from '@services/graphql/queries'; +import { getLayout } from '@components/Layouts/Layout'; +import PaginationCursor from '@components/PaginationCursor/PaginationCursor'; import PostHeader from '@components/PostHeader/PostHeader'; -import { ThematicsList, TopicsList } from '@components/Widgets'; +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 { getPublishedPosts } from '@services/graphql/queries'; import styles from '@styles/pages/Page.module.scss'; +import { NextPageWithLayout } from '@ts/types/app'; +import { BlogPageProps, PostsList as PostsListData } from '@ts/types/blog'; +import { getIntlInstance, 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 { useIntl } from 'react-intl'; 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<BlogPageProps> = ({ fallback }) => { + const intl = useIntl(); const lastPostRef = useRef<HTMLSpanElement>(null); const router = useRouter(); @@ -76,21 +76,39 @@ const Blog: NextPageWithLayout<BlogPageProps> = ({ fallback }) => { }; const getPostsList = () => { - if (error) return t`Failed to load.`; + if (error) + return intl.formatMessage({ + defaultMessage: 'Failed to load.', + description: 'BlogPage: failed to load text', + }); if (!data) return <Spinner />; return <PostsList ref={lastPostRef} data={data} showYears={true} />; }; - const title = t`Blog`; + const pageTitle = intl.formatMessage( + { + defaultMessage: 'Blog: development, open source - {websiteName}', + description: 'BlogPage: SEO - Page title', + }, + { websiteName: config.name } + ); + const pageDescription = intl.formatMessage( + { + defaultMessage: + "Discover {websiteName}'s writings. He talks about web development, Linux and open source mostly.", + description: 'BlogPage: SEO - Meta description', + }, + { websiteName: config.name } + ); const pageUrl = `${config.url}${router.asPath}`; const webpageSchema: WebPage = { '@id': `${pageUrl}`, '@type': 'WebPage', breadcrumb: { '@id': `${config.url}/#breadcrumb` }, - name: seo.blog.title, - description: seo.blog.description, + name: pageTitle, + description: pageDescription, inLanguage: config.locales.defaultLocale, reviewedBy: { '@id': `${config.url}/#branding` }, url: `${config.url}`, @@ -115,15 +133,20 @@ const Blog: NextPageWithLayout<BlogPageProps> = ({ fallback }) => { '@graph': [webpageSchema, blogSchema], }; + const title = intl.formatMessage({ + defaultMessage: 'Blog', + description: 'BlogPage: page title', + }); + return ( <> <Head> - <title>{seo.blog.title}</title> - <meta name="description" content={seo.blog.description} /> + <title>{pageTitle}</title> + <meta name="description" content={pageDescription} /> <meta property="og:url" content={`${pageUrl}`} /> <meta property="og:type" content="website" /> <meta property="og:title" content={title} /> - <meta property="og:description" content={seo.blog.description} /> + <meta property="og:description" content={pageDescription} /> <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }} @@ -146,13 +169,34 @@ const Blog: NextPageWithLayout<BlogPageProps> = ({ fallback }) => { isDisabled={isLoadingMore} clickHandler={loadMorePosts} position="center" - >{t`Load more?`}</Button> + > + {intl.formatMessage({ + defaultMessage: 'Load more?', + description: 'BlogPage: load more text', + })} + </Button> </> )} </div> - <Sidebar position="right" title={t`Filter by`}> - <ThematicsList title={t`Thematics`} /> - <TopicsList title={t`Topics`} /> + <Sidebar + position="right" + title={intl.formatMessage({ + defaultMessage: 'Filter by:', + description: 'BlogPage: sidebar title', + })} + > + <ThematicsList + title={intl.formatMessage({ + defaultMessage: 'Thematics', + description: 'BlogPage: thematics list widget title', + })} + /> + <TopicsList + title={intl.formatMessage({ + defaultMessage: 'Topics', + description: 'BlogPage: topics list widget title', + })} + /> </Sidebar> </article> </> @@ -164,10 +208,14 @@ Blog.getLayout = getLayout; export const getStaticProps: GetStaticProps = async ( context: GetStaticPropsContext ) => { - const breadcrumbTitle = t`Blog`; + const intl = await getIntlInstance(); + const breadcrumbTitle = intl.formatMessage({ + defaultMessage: 'Blog', + description: 'BlogPage: breadcrumb item', + }); 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..489135d 100644 --- a/src/pages/contact.tsx +++ b/src/pages/contact.tsx @@ -1,23 +1,23 @@ import { ButtonSubmit } from '@components/Buttons'; import { Form, FormItem, Input, TextArea } from '@components/Form'; import { getLayout } from '@components/Layouts/Layout'; -import { seo } from '@config/seo'; -import { t } from '@lingui/macro'; +import PostHeader from '@components/PostHeader/PostHeader'; +import Sidebar from '@components/Sidebar/Sidebar'; +import { SocialMedia } from '@components/Widgets'; +import { config } from '@config/website'; 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 { getIntlInstance, 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 { useIntl } from 'react-intl'; import { ContactPage as ContactPageSchema, Graph, WebPage } from 'schema-dts'; -import { config } from '@config/website'; -import { useRouter } from 'next/router'; const ContactPage: NextPageWithLayout = () => { + const intl = useIntl(); const [name, setName] = useState(''); const [email, setEmail] = useState(''); const [subject, setSubject] = useState(''); @@ -46,26 +46,54 @@ const ContactPage: NextPageWithLayout = () => { if (mail.sent) { setStatus( - t`Thanks. Your message was successfully sent. I will answer it as soon as possible.` + intl.formatMessage({ + defaultMessage: + 'Thanks. Your message was successfully sent. I will answer it as soon as possible.', + description: 'ContactPage: success message', + }) ); resetForm(); } else { - const errorPrefix = t`An error occurred:`; + const errorPrefix = intl.formatMessage({ + defaultMessage: 'An error occurred:', + description: 'ContactPage: error message', + }); const error = `${errorPrefix} ${mail.message}`; setStatus(error); } }; - const title = t`Contact`; - const intro = t`Please fill the form to contact me.`; + const pageTitle = intl.formatMessage( + { + defaultMessage: 'Contact form - {websiteName}', + description: 'ContactPage: SEO - Page title', + }, + { websiteName: config.name } + ); + const pageDescription = intl.formatMessage( + { + defaultMessage: + "Contact {websiteName} through its website. All you need to do it's to fill the contact form.", + description: 'ContactPage: SEO - Meta description', + }, + { websiteName: config.name } + ); const pageUrl = `${config.url}${router.asPath}`; + const title = intl.formatMessage({ + defaultMessage: 'Contact', + description: 'ContactPage: page title', + }); + const intro = intl.formatMessage({ + defaultMessage: 'Please fill the form to contact me.', + description: 'ContactPage: page introduction', + }); const webpageSchema: WebPage = { '@id': `${pageUrl}`, '@type': 'WebPage', breadcrumb: { '@id': `${config.url}/#breadcrumb` }, - name: seo.contact.title, - description: seo.contact.description, + name: pageTitle, + description: pageDescription, reviewedBy: { '@id': `${config.url}/#branding` }, url: `${pageUrl}`, isPartOf: { @@ -94,8 +122,8 @@ const ContactPage: NextPageWithLayout = () => { return ( <> <Head> - <title>{seo.contact.title}</title> - <meta name="description" content={seo.contact.description} /> + <title>{pageTitle}</title> + <meta name="description" content={pageDescription} /> <meta property="og:url" content={`${pageUrl}`} /> <meta property="og:type" content="article" /> <meta property="og:title" content={title} /> @@ -111,7 +139,12 @@ const ContactPage: NextPageWithLayout = () => { > <PostHeader title={title} intro={intro} /> <div className={styles.body}> - <p>{t`All fields marked with * are required.`}</p> + <p> + {intl.formatMessage({ + defaultMessage: 'All fields marked with * are required.', + description: 'ContactPage: required fields text', + })} + </p> {status && <p>{status}</p>} <Form submitHandler={submitHandler}> <FormItem> @@ -120,7 +153,10 @@ const ContactPage: NextPageWithLayout = () => { name="name" value={name} setValue={setName} - label={t`Name`} + label={intl.formatMessage({ + defaultMessage: 'Name', + description: 'ContactPage: name field label', + })} required={true} /> </FormItem> @@ -130,7 +166,10 @@ const ContactPage: NextPageWithLayout = () => { name="email" value={email} setValue={setEmail} - label={t`Email`} + label={intl.formatMessage({ + defaultMessage: 'Email', + description: 'ContactPage: email field label', + })} required={true} /> </FormItem> @@ -140,7 +179,10 @@ const ContactPage: NextPageWithLayout = () => { name="subject" value={subject} setValue={setSubject} - label={t`Subject`} + label={intl.formatMessage({ + defaultMessage: 'Subject', + description: 'ContactPage: subject field label', + })} /> </FormItem> <FormItem> @@ -149,18 +191,29 @@ const ContactPage: NextPageWithLayout = () => { name="message" value={message} setValue={setMessage} - label={t`Message`} + label={intl.formatMessage({ + defaultMessage: 'Message', + description: 'ContactPage: message field label', + })} required={true} /> </FormItem> <FormItem> - <ButtonSubmit>{t`Send`}</ButtonSubmit> + <ButtonSubmit> + {intl.formatMessage({ + defaultMessage: 'Send', + description: 'ContactPage: send button text', + })} + </ButtonSubmit> </FormItem> </Form> </div> <Sidebar position="right"> <SocialMedia - title={t`Find me elsewhere`} + title={intl.formatMessage({ + defaultMessage: 'Find me elsewhere', + description: 'ContactPage: social media widget title', + })} github={true} gitlab={true} linkedin={true} @@ -176,9 +229,13 @@ ContactPage.getLayout = getLayout; export const getStaticProps: GetStaticProps = async ( context: GetStaticPropsContext ) => { - const breadcrumbTitle = t`Contact`; + const intl = await getIntlInstance(); + const breadcrumbTitle = intl.formatMessage({ + defaultMessage: 'Contact', + description: 'ContactPage: breadcrumb item', + }); 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..c3686de 100644 --- a/src/pages/cv.tsx +++ b/src/pages/cv.tsx @@ -1,21 +1,21 @@ import { getLayout } from '@components/Layouts/Layout'; -import { seo } from '@config/seo'; -import { NextPageWithLayout } from '@ts/types/app'; -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 { CVPreview, SocialMedia, ToC } from '@components/Widgets'; import { config } from '@config/website'; +import CVContent, { intro, meta, pdf, image } from '@content/pages/cv.mdx'; +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 { useRouter } from 'next/router'; -import { defaultLocale, loadTranslation } from '@utils/helpers/i18n'; +import { useIntl } from 'react-intl'; +import { AboutPage, Graph, WebPage } from 'schema-dts'; const CV: NextPageWithLayout = () => { + const intl = useIntl(); const router = useRouter(); const dates = { publication: meta.publishedOn, @@ -26,13 +26,28 @@ const CV: NextPageWithLayout = () => { dates, }; const pageUrl = `${config.url}${router.asPath}`; + const pageTitle = intl.formatMessage( + { + defaultMessage: 'CV Front-end developer - {websiteName}', + description: 'CVPage: SEO - Page title', + }, + { websiteName: config.name } + ); + const pageDescription = intl.formatMessage( + { + defaultMessage: + 'Discover the curriculum of {websiteName}, front-end developer located in France: skills, experiences and training.', + description: 'CVPage: SEO - Meta description', + }, + { websiteName: config.name } + ); const webpageSchema: WebPage = { '@id': `${pageUrl}`, '@type': 'WebPage', breadcrumb: { '@id': `${config.url}/#breadcrumb` }, - name: seo.cv.title, - description: seo.cv.description, + name: pageTitle, + description: pageDescription, reviewedBy: { '@id': `${config.url}/#branding` }, url: `${pageUrl}`, isPartOf: { @@ -46,7 +61,7 @@ const CV: NextPageWithLayout = () => { const cvSchema: AboutPage = { '@id': `${config.url}/#cv`, '@type': 'AboutPage', - name: `${config.name} CV`, + name: pageTitle, description: intro, author: { '@id': `${config.url}/#branding` }, creator: { '@id': `${config.url}/#branding` }, @@ -66,17 +81,25 @@ const CV: NextPageWithLayout = () => { '@graph': [webpageSchema, cvSchema], }; + const title = intl.formatMessage( + { + defaultMessage: "{name}'s CV", + description: 'CVPage: page title', + }, + { name: config.name } + ); + return ( <> <Head> - <title>{seo.cv.title}</title> - <meta name="description" content={seo.cv.description} /> + <title>{pageTitle}</title> + <meta name="description" content={pageDescription} /> <meta property="og:url" content={`${pageUrl}`} /> <meta property="og:type" content="article" /> - <meta property="og:title" content={`${config.name} CV`} /> + <meta property="og:title" content={title} /> <meta property="og:description" content={intro} /> <meta property="og:image" content={image} /> - <meta property="og:image:alt" content={`${config.name} CV`} /> + <meta property="og:image:alt" content={title} /> <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }} @@ -94,9 +117,19 @@ const CV: NextPageWithLayout = () => { <CVContent /> </div> <Sidebar position="right"> - <CVPreview title={t`Other formats`} imgSrc={image} pdf={pdf} /> + <CVPreview + title={intl.formatMessage({ + defaultMessage: 'Others formats', + description: 'CVPage: cv preview widget title', + })} + imgSrc={image} + pdf={pdf} + /> <SocialMedia - title={t`Open-source projects`} + title={intl.formatMessage({ + defaultMessage: 'Open-source projects', + description: 'CVPage: social media widget title', + })} github={true} gitlab={true} /> @@ -113,7 +146,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..41a4603 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,30 +1,39 @@ -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 { 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 { useIntl } from 'react-intl'; import { Graph, WebPage } from 'schema-dts'; -import { config } from '@config/website'; const Home: NextPageWithLayout = () => { + const intl = useIntl(); + const CodingLinks = () => { return ( <ul className={styles['links-list']}> <li> <ButtonLink target="/thematique/developpement-web"> - {t`Web development`} + {intl.formatMessage({ + defaultMessage: 'Web development', + description: 'HomePage: link to web development thematic', + })} </ButtonLink> </li> <li> - <ButtonLink target="/projets">{t`Projects`}</ButtonLink> + <ButtonLink target="/projets"> + {intl.formatMessage({ + defaultMessage: 'Projects', + description: 'HomePage: link to projects', + })} + </ButtonLink> </li> </ul> ); @@ -57,10 +66,20 @@ const Home: NextPageWithLayout = () => { return ( <ul className={styles['links-list']}> <li> - <ButtonLink target="/thematique/libre">{t`Free`}</ButtonLink> + <ButtonLink target="/thematique/libre"> + {intl.formatMessage({ + defaultMessage: 'Free', + description: 'HomePage: link to free thematic', + })} + </ButtonLink> </li> <li> - <ButtonLink target="/thematique/linux">{t`Linux`}</ButtonLink> + <ButtonLink target="/thematique/linux"> + {intl.formatMessage({ + defaultMessage: 'Linux', + description: 'HomePage: link to Linux thematic', + })} + </ButtonLink> </li> </ul> ); @@ -72,13 +91,19 @@ const Home: NextPageWithLayout = () => { <li> <ButtonLink target="/contact"> <ContactIcon /> - {t`Contact me`} + {intl.formatMessage({ + defaultMessage: 'Contact me', + description: 'HomePage: contact button text', + })} </ButtonLink> </li> <li> <ButtonLink target="/feed"> <FeedIcon className={styles['icon--feed']} /> - {t`Subscribe`} + {intl.formatMessage({ + defaultMessage: 'Subscribe', + description: 'HomePage: RSS feed subscription text', + })} </ButtonLink> </li> </ul> @@ -92,12 +117,28 @@ const Home: NextPageWithLayout = () => { MoreLinks: MoreLinks, }; + const pageTitle = intl.formatMessage( + { + defaultMessage: '{websiteName} | Front-end developer: WordPress/React', + description: 'HomePage: SEO - Page title', + }, + { websiteName: config.name } + ); + const pageDescription = intl.formatMessage( + { + defaultMessage: + '{websiteName} is a front-end developer located in France. He codes and he writes mostly about web development and open-source.', + description: 'HomePage: SEO - Meta description', + }, + { websiteName: config.name } + ); + const webpageSchema: WebPage = { '@id': `${config.url}/#home`, '@type': 'WebPage', breadcrumb: { '@id': `${config.url}/#breadcrumb` }, - name: seo.legalNotice.title, - description: seo.legalNotice.description, + name: pageTitle, + description: pageDescription, author: { '@id': `${config.url}/#branding` }, creator: { '@id': `${config.url}/#branding` }, editor: { '@id': `${config.url}/#branding` }, @@ -115,12 +156,12 @@ const Home: NextPageWithLayout = () => { return ( <> <Head> - <title>{seo.homepage.title}</title> - <meta name="description" content={seo.homepage.description} /> + <title>{pageTitle}</title> + <meta name="description" content={pageDescription} /> <meta property="og:type" content="website" /> <meta property="og:url" content={`${config.url}`} /> - <meta property="og:title" content={seo.homepage.title} /> - <meta property="og:description" content={seo.homepage.description} /> + <meta property="og:title" content={pageTitle} /> + <meta property="og:description" content={pageDescription} /> <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }} @@ -141,11 +182,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..0ec92a2 100644 --- a/src/pages/mentions-legales.tsx +++ b/src/pages/mentions-legales.tsx @@ -1,24 +1,24 @@ import { getLayout } from '@components/Layouts/Layout'; -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 PostHeader from '@components/PostHeader/PostHeader'; +import Sidebar from '@components/Sidebar/Sidebar'; +import { ToC } from '@components/Widgets'; +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 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 { useIntl } from 'react-intl'; +import { Article, Graph, WebPage } from 'schema-dts'; const LegalNotice: NextPageWithLayout = () => { + const intl = useIntl(); const router = useRouter(); const dates = { publication: meta.publishedOn, @@ -28,8 +28,25 @@ const LegalNotice: NextPageWithLayout = () => { const pageMeta: ArticleMeta = { dates, }; + const pageTitle = intl.formatMessage( + { + defaultMessage: 'Legal notice - {websiteName}', + description: 'LegalNoticePage: SEO - Page title', + }, + { websiteName: config.name } + ); + const pageDescription = intl.formatMessage( + { + defaultMessage: "Discover the legal notice of {websiteName}'s website.", + description: 'LegalNoticePage: SEO - Meta description', + }, + { websiteName: config.name } + ); const pageUrl = `${config.url}${router.asPath}`; - + const title = intl.formatMessage({ + defaultMessage: 'Legal notice', + description: 'LegalNoticePage: page title', + }); const publicationDate = new Date(dates.publication); const updateDate = new Date(dates.update); @@ -37,8 +54,8 @@ const LegalNotice: NextPageWithLayout = () => { '@id': `${pageUrl}`, '@type': 'WebPage', breadcrumb: { '@id': `${config.url}/#breadcrumb` }, - name: seo.legalNotice.title, - description: seo.legalNotice.description, + name: pageTitle, + description: pageDescription, inLanguage: config.locales.defaultLocale, license: 'https://creativecommons.org/licenses/by-sa/4.0/deed.fr', reviewedBy: { '@id': `${config.url}/#branding` }, @@ -51,7 +68,7 @@ const LegalNotice: NextPageWithLayout = () => { const articleSchema: Article = { '@id': `${config.url}/#legal-notice`, '@type': 'Article', - name: t`Legal notice`, + name: title, description: intro, author: { '@id': `${config.url}/#branding` }, copyrightYear: publicationDate.getFullYear(), @@ -73,11 +90,11 @@ const LegalNotice: NextPageWithLayout = () => { return ( <> <Head> - <title>{seo.legalNotice.title}</title> - <meta name="description" content={seo.legalNotice.description} /> + <title>{pageTitle}</title> + <meta name="description" content={pageDescription} /> <meta property="og:url" content={`${pageUrl}`} /> <meta property="og:type" content="article" /> - <meta property="og:title" content={t`Legal notice`} /> + <meta property="og:title" content={pageTitle} /> <meta property="og:description" content={intro} /> <script type="application/ld+json" @@ -107,7 +124,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..da4523c 100644 --- a/src/pages/projets.tsx +++ b/src/pages/projets.tsx @@ -1,19 +1,20 @@ import { getLayout } from '@components/Layouts/Layout'; import PostHeader from '@components/PostHeader/PostHeader'; import ProjectsList from '@components/ProjectsList/ProjectsList'; -import { seo } from '@config/seo'; 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'; import { useRouter } from 'next/router'; +import { useIntl } from 'react-intl'; import { Article, Graph, WebPage } from 'schema-dts'; const Projects = ({ projects }: { projects: Project[] }) => { + const intl = useIntl(); const dates = { publication: meta.publishedOn, update: meta.updatedOn, @@ -22,13 +23,28 @@ const Projects = ({ projects }: { projects: Project[] }) => { const updateDate = new Date(dates.update); const router = useRouter(); const pageUrl = `${config.url}${router.asPath}`; + const pageTitle = intl.formatMessage( + { + defaultMessage: 'Projects: open-source makings - {websiteName}', + description: 'ProjectsPage: SEO - Page title', + }, + { websiteName: config.name } + ); + const pageDescription = intl.formatMessage( + { + defaultMessage: + 'Discover {websiteName} projects. Mostly related to web development and open source.', + description: 'ProjectsPage: SEO - Meta description', + }, + { websiteName: config.name } + ); const webpageSchema: WebPage = { '@id': `${pageUrl}`, '@type': 'WebPage', breadcrumb: { '@id': `${config.url}/#breadcrumb` }, - name: seo.legalNotice.title, - description: seo.legalNotice.description, + name: pageTitle, + description: pageDescription, inLanguage: config.locales.defaultLocale, license: 'https://creativecommons.org/licenses/by-sa/4.0/deed.fr', reviewedBy: { '@id': `${config.url}/#branding` }, @@ -42,7 +58,7 @@ const Projects = ({ projects }: { projects: Project[] }) => { '@id': `${config.url}/#projects`, '@type': 'Article', name: meta.title, - description: seo.projects.description, + description: pageDescription, author: { '@id': `${config.url}/#branding` }, copyrightYear: publicationDate.getFullYear(), creator: { '@id': `${config.url}/#branding` }, @@ -63,12 +79,12 @@ const Projects = ({ projects }: { projects: Project[] }) => { return ( <> <Head> - <title>{seo.projects.title}</title> - <meta name="description" content={seo.projects.description} /> + <title>{pageTitle}</title> + <meta name="description" content={pageDescription} /> <meta property="og:url" content={`${pageUrl}`} /> <meta property="og:type" content="article" /> <meta property="og:title" content={meta.title} /> - <meta property="og:description" content={seo.projects.description} /> + <meta property="og:description" content={pageDescription} /> <script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }} @@ -92,7 +108,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..857b114 100644 --- a/src/pages/recherche/index.tsx +++ b/src/pages/recherche/index.tsx @@ -1,25 +1,26 @@ 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 { getIntlInstance, 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 { useIntl } from 'react-intl'; 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 intl = useIntl(); const [query, setQuery] = useState(''); const router = useRouter(); const lastPostRef = useRef<HTMLSpanElement>(null); @@ -76,15 +77,33 @@ const Search: NextPageWithLayout = () => { const hasNextPage = data && data[data.length - 1].pageInfo.hasNextPage; const title = query - ? t`Search results for: ${query}` - : t({ - comment: 'Search page title', - message: 'Search', + ? intl.formatMessage( + { + defaultMessage: 'Search results for {query}', + description: 'SearchPage: search results text', + }, + { query } + ) + : intl.formatMessage({ + defaultMessage: 'Search', + description: 'SearchPage: page title', }); const description = query - ? t`Discover search results for: ${query}` - : t`Search for a post on ${config.name}.`; + ? intl.formatMessage( + { + defaultMessage: 'Discover search results for {query}', + description: 'SearchPage: meta description with query', + }, + { query } + ) + : intl.formatMessage( + { + defaultMessage: 'Search for a post on {websiteName}', + description: 'SearchPage: meta description without query', + }, + { websiteName: config.name } + ); const head = { title: `${title} | ${config.name}`, @@ -99,7 +118,11 @@ const Search: NextPageWithLayout = () => { }; const getPostsList = () => { - if (error) return t`Failed to load.`; + if (error) + return intl.formatMessage({ + defaultMessage: 'Failed to load.', + description: 'SearchPage: failed to load text', + }); if (!data) return <Spinner />; return <PostsList ref={lastPostRef} data={data} showYears={false} />; @@ -127,13 +150,28 @@ const Search: NextPageWithLayout = () => { isDisabled={isLoadingMore} clickHandler={loadMorePosts} position="center" - >{t`Load more?`}</Button> + > + {intl.formatMessage({ + defaultMessage: 'Load more?', + description: 'SearchPage: load more text', + })} + </Button> </> )} </div> <Sidebar position="right"> - <ThematicsList title={t`Thematics`} /> - <TopicsList title={t`Topics`} /> + <ThematicsList + title={intl.formatMessage({ + defaultMessage: 'Thematics', + description: 'SearchPage: thematics list widget title', + })} + /> + <TopicsList + title={intl.formatMessage({ + defaultMessage: 'Topics', + description: 'SearchPage: topics list widget title', + })} + /> </Sidebar> </article> </> @@ -145,9 +183,13 @@ Search.getLayout = getLayout; export const getStaticProps: GetStaticProps = async ( context: GetStaticPropsContext ) => { - const breadcrumbTitle = t`Search`; + const intl = await getIntlInstance(); + const breadcrumbTitle = intl.formatMessage({ + defaultMessage: 'Search', + description: 'SearchPage: breadcrumb item', + }); 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..87a86a2 100644 --- a/src/pages/sujet/[slug].tsx +++ b/src/pages/sujet/[slug].tsx @@ -1,24 +1,25 @@ import { getLayout } from '@components/Layouts/Layout'; +import PostHeader from '@components/PostHeader/PostHeader'; import PostPreview from '@components/PostPreview/PostPreview'; -import { t } from '@lingui/macro'; +import Sidebar from '@components/Sidebar/Sidebar'; +import { RelatedThematics, ToC, TopicsList } from '@components/Widgets'; +import { config } from '@config/website'; +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 { useIntl } from 'react-intl'; import { Article as Article, Graph, WebPage } from 'schema-dts'; -import { config } from '@config/website'; -import { useRouter } from 'next/router'; const Topic: NextPageWithLayout<TopicProps> = ({ topic }) => { + const intl = useIntl(); const relatedThematics = useRef<ThematicPreview[]>([]); const router = useRouter(); @@ -128,14 +129,27 @@ const Topic: NextPageWithLayout<TopicProps> = ({ topic }) => { <div dangerouslySetInnerHTML={{ __html: topic.content }}></div> {topic.posts.length > 0 && ( <section className={styles.section}> - <h2>{t`All posts in ${topic.title}`}</h2> + <h2> + {intl.formatMessage( + { + defaultMessage: 'All posts in {name}', + description: 'TopicPage: posts list title', + }, + { name: topic.title } + )} + </h2> <ol className={styles.list}>{getPostsList()}</ol> </section> )} </div> <Sidebar position="right"> <RelatedThematics thematics={relatedThematics.current} /> - <TopicsList title={t`Other topics`} /> + <TopicsList + title={intl.formatMessage({ + defaultMessage: 'Others topics', + description: 'TopicPage: topics list widget title', + })} + /> </Sidebar> </article> </> @@ -152,7 +166,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..61019fd 100644 --- a/src/pages/thematique/[slug].tsx +++ b/src/pages/thematique/[slug].tsx @@ -1,27 +1,28 @@ import { getLayout } from '@components/Layouts/Layout'; +import PostHeader from '@components/PostHeader/PostHeader'; import PostPreview from '@components/PostPreview/PostPreview'; -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 Sidebar from '@components/Sidebar/Sidebar'; +import { RelatedTopics, ThematicsList, ToC } from '@components/Widgets'; +import { config } from '@config/website'; 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 { useIntl } from 'react-intl'; +import { Article, Graph, WebPage } from 'schema-dts'; const Thematic: NextPageWithLayout<ThematicProps> = ({ thematic }) => { + const intl = useIntl(); const relatedTopics = useRef<TopicPreview[]>([]); const router = useRouter(); @@ -118,14 +119,27 @@ const Thematic: NextPageWithLayout<ThematicProps> = ({ thematic }) => { <div dangerouslySetInnerHTML={{ __html: thematic.content }}></div> {thematic.posts.length > 0 && ( <section className={styles.section}> - <h2>{t`All posts in ${thematic.title}`}</h2> + <h2> + {intl.formatMessage( + { + defaultMessage: 'All posts in {name}', + description: 'ThematicPage: posts list title', + }, + { name: thematic.title } + )} + </h2> <ol className={styles.list}>{getPostsList()}</ol> </section> )} </div> <Sidebar position="right"> <RelatedTopics topics={relatedTopics.current} /> - <ThematicsList title={t`Other thematics`} /> + <ThematicsList + title={intl.formatMessage({ + defaultMessage: 'Others thematics', + description: 'ThematicPage: thematics list widget title', + })} + /> </Sidebar> </article> </> @@ -142,7 +156,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; |
