diff options
| author | Armand Philippot <git@armandphilippot.com> | 2022-01-29 18:21:37 +0100 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2022-01-29 19:02:57 +0100 |
| commit | e4d5b8151802517b2943756fc0d09ffa95e2c4e2 (patch) | |
| tree | 9e99137a7b64ea7993a8311a7162336a551be8b2 /src/pages | |
| parent | 47b854de26dea24e7838fd0804df103dee99635f (diff) | |
chore: replace lingui functions with react-intl
Diffstat (limited to 'src/pages')
| -rw-r--r-- | src/pages/404.tsx | 62 | ||||
| -rw-r--r-- | src/pages/article/[slug].tsx | 6 | ||||
| -rw-r--r-- | src/pages/blog/index.tsx | 78 | ||||
| -rw-r--r-- | src/pages/contact.tsx | 95 | ||||
| -rw-r--r-- | src/pages/cv.tsx | 55 | ||||
| -rw-r--r-- | src/pages/index.tsx | 69 | ||||
| -rw-r--r-- | src/pages/mentions-legales.tsx | 35 | ||||
| -rw-r--r-- | src/pages/projets.tsx | 30 | ||||
| -rw-r--r-- | src/pages/recherche/index.tsx | 68 | ||||
| -rw-r--r-- | src/pages/sujet/[slug].tsx | 20 | ||||
| -rw-r--r-- | src/pages/thematique/[slug].tsx | 20 |
11 files changed, 424 insertions, 114 deletions
diff --git a/src/pages/404.tsx b/src/pages/404.tsx index 64c74ba..079dead 100644 --- a/src/pages/404.tsx +++ b/src/pages/404.tsx @@ -1,44 +1,70 @@ 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 { 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 { 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); @@ -51,4 +77,4 @@ export const getStaticProps: GetStaticProps = async ( }; }; -export default error404; +export default Error404; diff --git a/src/pages/article/[slug].tsx b/src/pages/article/[slug].tsx index ce9c22b..8668a66 100644 --- a/src/pages/article/[slug].tsx +++ b/src/pages/article/[slug].tsx @@ -18,6 +18,7 @@ import { useRouter } from 'next/router'; import Prism from 'prismjs'; import { ParsedUrlQuery } from 'querystring'; import { useEffect } from 'react'; +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}`, diff --git a/src/pages/blog/index.tsx b/src/pages/blog/index.tsx index 8e42e02..9a86d9f 100644 --- a/src/pages/blog/index.tsx +++ b/src/pages/blog/index.tsx @@ -6,22 +6,22 @@ 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 { 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 { BlogPageProps, PostsList as PostsListData } from '@ts/types/blog'; -import { 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 { useEffect, useRef, useState } from 'react'; +import { useIntl } from 'react-intl'; import { Blog as BlogSchema, Graph, WebPage } from 'schema-dts'; 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,7 +208,11 @@ 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); diff --git a/src/pages/contact.tsx b/src/pages/contact.tsx index 464854d..489135d 100644 --- a/src/pages/contact.tsx +++ b/src/pages/contact.tsx @@ -4,20 +4,20 @@ 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 { 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 { useIntl } from 'react-intl'; import { ContactPage as ContactPageSchema, Graph, WebPage } from 'schema-dts'; 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,7 +229,11 @@ 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); diff --git a/src/pages/cv.tsx b/src/pages/cv.tsx index a851c38..c3686de 100644 --- a/src/pages/cv.tsx +++ b/src/pages/cv.tsx @@ -2,10 +2,8 @@ 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'; @@ -13,9 +11,11 @@ import { loadTranslation } from '@utils/helpers/i18n'; import { GetStaticProps, GetStaticPropsContext } from 'next'; import Head from 'next/head'; import { useRouter } from 'next/router'; +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} /> diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 264c45a..41a4603 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -2,29 +2,38 @@ 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 { config } from '@config/website'; import HomePageContent from '@content/pages/homepage.mdx'; -import { t } from '@lingui/macro'; 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 { useIntl } from 'react-intl'; import { Graph, WebPage } from 'schema-dts'; 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) }} diff --git a/src/pages/mentions-legales.tsx b/src/pages/mentions-legales.tsx index e13a7e2..0ec92a2 100644 --- a/src/pages/mentions-legales.tsx +++ b/src/pages/mentions-legales.tsx @@ -2,13 +2,11 @@ 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 { config } from '@config/website'; import LegalNoticeContent, { intro, meta, } from '@content/pages/legal-notice.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'; @@ -16,9 +14,11 @@ import { loadTranslation } from '@utils/helpers/i18n'; 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 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" diff --git a/src/pages/projets.tsx b/src/pages/projets.tsx index 263973d..da4523c 100644 --- a/src/pages/projets.tsx +++ b/src/pages/projets.tsx @@ -1,7 +1,6 @@ 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'; @@ -11,9 +10,11 @@ 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) }} diff --git a/src/pages/recherche/index.tsx b/src/pages/recherche/index.tsx index c3c71f3..857b114 100644 --- a/src/pages/recherche/index.tsx +++ b/src/pages/recherche/index.tsx @@ -7,19 +7,20 @@ 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 { 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'; 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,7 +183,11 @@ 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); diff --git a/src/pages/sujet/[slug].tsx b/src/pages/sujet/[slug].tsx index 65ea2fd..87a86a2 100644 --- a/src/pages/sujet/[slug].tsx +++ b/src/pages/sujet/[slug].tsx @@ -4,7 +4,6 @@ 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'; @@ -16,9 +15,11 @@ import Head from 'next/head'; import { useRouter } from 'next/router'; import { ParsedUrlQuery } from 'querystring'; import { useRef } from 'react'; +import { useIntl } from 'react-intl'; import { Article as Article, Graph, WebPage } from 'schema-dts'; 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> </> diff --git a/src/pages/thematique/[slug].tsx b/src/pages/thematique/[slug].tsx index d263ee9..61019fd 100644 --- a/src/pages/thematique/[slug].tsx +++ b/src/pages/thematique/[slug].tsx @@ -4,7 +4,6 @@ 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 { getAllThematicsSlug, getThematicBySlug, @@ -19,9 +18,11 @@ import Head from 'next/head'; 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> </> |
