Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React i18next #8406

Merged
merged 29 commits into from
Nov 28, 2022
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a07ee2d
refactor all the components
pettinarip Sep 22, 2022
10a9be7
initial commit to implement gatsby-plugin-react-i18next
pettinarip Oct 28, 2022
20ba84c
fixes
pettinarip Oct 28, 2022
9ed0d41
remove analyzer
pettinarip Oct 29, 2022
bf6db9e
fix redirects on non mdx pages
pettinarip Oct 29, 2022
f4d00ee
add redirects of defaultLang pages
pettinarip Oct 31, 2022
db8d10f
add comments
pettinarip Oct 31, 2022
ba73184
enable generateDefaultLanguagePage
pettinarip Oct 31, 2022
5fb1643
add translations to languages page
pettinarip Oct 31, 2022
4737998
fix redirects
pettinarip Oct 31, 2022
d7cbb98
fix custom 404 pages
pettinarip Nov 1, 2022
69126da
use gatsby-plugin-layout to wrap the page with a component and simpli…
pettinarip Nov 1, 2022
d3cf052
Merge branch 'dev' into react-i18next
pettinarip Nov 2, 2022
6f2e080
dangerously insert html translation string in specific parts of the code
pettinarip Nov 3, 2022
2e7dc1f
fix translation function
pettinarip Nov 4, 2022
7976a5e
Merge branch 'dev' into react-i18next
pettinarip Nov 4, 2022
5ee0309
cleanup
pettinarip Nov 4, 2022
5684ccf
Merge branch 'dev' into react-i18next
pettinarip Nov 7, 2022
472b6f3
Merge branch 'dev' into react-i18next
pettinarip Nov 14, 2022
ee4e9ce
replace with function
pettinarip Nov 14, 2022
3691652
Merge branch 'dev' into react-i18next
pettinarip Nov 19, 2022
60a9701
Merge branch 'dev' into react-i18next
pettinarip Nov 21, 2022
7d62c99
update translation functions
pettinarip Nov 21, 2022
0b20b35
fix tutorials filter
pettinarip Nov 21, 2022
91ebe76
always fetch the default lang in order to fallback to it when the tra…
pettinarip Nov 23, 2022
b362468
Merge branch 'dev' into react-i18next
pettinarip Nov 23, 2022
45124c8
use htmr to parse html inside json files
pettinarip Nov 14, 2022
1becc65
update Translation comments
pettinarip Nov 23, 2022
e90d693
Merge pull request #8592 from ethereum/i18n-parse-html-json
corwintines Nov 24, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ yarn-error.log
src/data/contributors.json
# These files are generated by `yarn merge-translations` command
src/intl/*.json
i18n/locales
# Auto generated code when gatsby build the site
src/gatsby-types.d.ts

Expand Down
51 changes: 0 additions & 51 deletions gatsby-browser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
* See: https://www.gatsbyjs.org/docs/browser-apis/
*/

import React from "react"
import browserLang from "browser-lang"
import { withPrefix, GatsbyBrowser } from "gatsby"

import Prism from "prism-react-renderer/prism"
;(typeof global !== "undefined" ? global : window).Prism = Prism

Expand All @@ -16,53 +12,6 @@ import "@formatjs/intl-locale/polyfill"
import "@formatjs/intl-numberformat/polyfill"
import "@formatjs/intl-numberformat/locale-data/en"

import Layout from "./src/components/Layout"
import {
supportedLanguages,
defaultLanguage,
isLang,
} from "./src/utils/languages"
import { IS_DEV } from "./src/utils/env"
import { Context } from "./src/types"

// Default languages included:
// https://github.com/FormidableLabs/prism-react-renderer/blob/master/src/vendor/prism/includeLangs.js
require("prismjs/components/prism-solidity")

// Prevents <Layout/> from unmounting on page transitions
// https://www.gatsbyjs.com/docs/layout-components/#how-to-prevent-layout-components-from-unmounting
// @ts-ignore: returning `null` is not accepted by the `GatsbyBrowser` type def.
export const wrapPageElement: GatsbyBrowser<
any,
Context
>["wrapPageElement"] = ({ element, props }) => {
const { location, pageContext } = props
const { pathname, search } = location
const { originalPath } = pageContext

const [, pathLocale] = pathname.split("/")

// client side redirect on paths that don't have a locale in them. Most useful
// on dev env where we don't have server redirects
if (IS_DEV && !isLang(pathLocale)) {
let detected =
window.localStorage.getItem("eth-org-language") ||
browserLang({
languages: supportedLanguages,
fallback: defaultLanguage,
})

if (!isLang(detected)) {
detected = defaultLanguage
}

const queryParams = search || ""
const newUrl = withPrefix(`/${detected}${originalPath}${queryParams}`)
window.localStorage.setItem("eth-org-language", detected)
window.location.replace(newUrl)

return null
}

return <Layout {...props}>{element}</Layout>
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gatsby-browser & gatsby-ssr content was replaced by the usage of gatsby-plugin-layout.

68 changes: 50 additions & 18 deletions gatsby-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,6 @@ const config: GatsbyConfig = {
editContentUrl: `https://github.com/ethereum/ethereum-org-website/tree/dev/`,
},
plugins: [
// i18n support
{
resolve: `gatsby-theme-i18n`,
options: {
defaultLang: defaultLanguage,
prefixDefault: true,
locales: supportedLanguages.length
? supportedLanguages.join(" ")
: null,
configPath: path.resolve(`./i18n/config.json`),
},
},
{
resolve: `gatsby-theme-i18n-react-intl`,
options: {
defaultLocale: `./src/intl/en.json`,
},
},
// Web app manifest
{
resolve: `gatsby-plugin-manifest`,
Expand Down Expand Up @@ -265,6 +247,56 @@ const config: GatsbyConfig = {
generateMatchPathRewrites: false,
},
},
// i18n support
{
resolve: `gatsby-source-filesystem`,
options: {
path: path.resolve(`./i18n/locales`),
name: `locale`,
},
},
// Wraps the entire page with a custom layout component
// Note: keep this before the i18n plugin declaration in order to have the
// i18n provider wrapping the layout component
{
resolve: `gatsby-plugin-layout`,
options: {
component: path.resolve(`./src/components/Layout`),
},
},
{
resolve: `gatsby-plugin-react-i18next`,
options: {
localeJsonSourceName: `locale`, // name given to `gatsby-source-filesystem` plugin.
languages: supportedLanguages,
defaultLanguage: defaultLanguage,
generateDefaultLanguagePage: true,
redirect: false,
siteUrl,
trailingSlash: "always",
// i18next options
i18nextOptions: {
fallbackLng: defaultLanguage,
interpolation: {
escapeValue: false,
},
react: {
transSupportBasicHtmlNodes: true,
transKeepBasicHtmlNodesFor: [
"br",
"strong",
"i",
"bold",
"b",
"em",
"sup",
],
},
keySeparator: false,
nsSeparator: false,
},
},
},
],
// https://www.gatsbyjs.com/docs/reference/release-notes/v2.28/#feature-flags-in-gatsby-configjs
flags: {
Expand Down
125 changes: 77 additions & 48 deletions gatsby-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,11 +290,16 @@ export const createPages: GatsbyNode<any, Context>["createPages"] = async ({
isOutdated: false,
isContentEnglish: true,
relativePath, // Use English path for template MDX query
// gatsby i18n theme context
locale: lang,
hrefLang: lang,
originalPath: langSlug.slice(3),
dateFormat: "MM/DD/YYYY",
// gatsby i18n plugin
i18n: {
language: lang,
languages: supportedLanguages,
defaultLanguage: defaultLanguage,
generateDefaultLanguagePage: false,
routed: true,
originalPath: langSlug.slice(3),
path: langSlug,
},
},
})
}
Expand All @@ -310,11 +315,16 @@ export const createPages: GatsbyNode<any, Context>["createPages"] = async ({
isOutdated: !!node.fields.isOutdated,
isDefaultLang: language === defaultLanguage,
relativePath,
// gatsby i18n theme context
locale: language,
hrefLang: language,
originalPath: slug.slice(3),
dateFormat: "MM/DD/YYYY",
// gatsby i18n plugin
i18n: {
language,
languages: supportedLanguages,
defaultLanguage: defaultLanguage,
generateDefaultLanguagePage: false,
routed: true,
originalPath: slug.slice(3),
path: slug,
},
},
})
})
Expand Down Expand Up @@ -344,9 +354,7 @@ export const createPages: GatsbyNode<any, Context>["createPages"] = async ({
page,
lang
)

const slug = `/${lang}${originalPath}`

createPage<Context>({
path: slug,
component: path.resolve(`src/pages-conditional/${page}.tsx`),
Expand All @@ -355,11 +363,16 @@ export const createPages: GatsbyNode<any, Context>["createPages"] = async ({
slug,
isContentEnglish,
isOutdated,
// gatsby i18n theme context
locale: lang,
hrefLang: lang,
originalPath,
dateFormat: "MM/DD/YYYY",
// gatsby i18n plugin
i18n: {
language: lang,
languages: supportedLanguages,
defaultLanguage: defaultLanguage,
generateDefaultLanguagePage: false,
routed: true,
originalPath,
path: slug,
},
},
})
}
Expand All @@ -376,51 +389,67 @@ export const onCreatePage: GatsbyNode<any, Context>["onCreatePage"] = async ({
}) => {
const { createPage, deletePage, createRedirect } = actions

const isDefaultLang = page.path.startsWith(`/${defaultLanguage}`)

if (isDefaultLang) {
const path = page.path.slice(3)

if (IS_DEV) {
// create routes without the lang prefix e.g. `/{path}` as our i18n plugin
// only creates `/{lang}/{path}` routes. This is useful on dev env to avoid
// getting a 404 since we don't have server side redirects
createPage({ ...page, path })
}

if (!IS_DEV && !path.match(/^\/404(\/|.html)$/)) {
// on prod, indicate our servers to redirect the root paths to the
// `/{defaultLang}/{path}`
createRedirect({
...commonRedirectProps,
fromPath: path,
toPath: page.path,
})
}
}

if (!page.context) {
return
}

const isTranslated = page.context.locale !== defaultLanguage
const hasNoContext = page.context.isOutdated === undefined
// these are the native Gatsby pages (those living under `/pages`)
// which do not pass through the `createPages` hook thus they don't have our
// custom context in them
const isPageWithoutCustomContext = page.context.isOutdated === undefined

if (isPageWithoutCustomContext) {
const { language, i18n } = page.context
const isDefaultLang = language === defaultLanguage

if (isTranslated && hasNoContext) {
// as we don't have our custom context for this page, we calculate & add it
// later to them
const { isOutdated, isContentEnglish } = await checkIsPageOutdated(
page.context.originalPath,
page.context.locale
i18n.originalPath,
language
)
deletePage(page)
createPage<Context>({

let newPage = {
...page,
context: {
...page.context,
isOutdated,
//display TranslationBanner for translation-component pages that are still in English
isContentEnglish,
},
})
}

// there seems to be a bug in the i18n plugin where 404 pages get a
// duplicated `/lang` in their `matchPath`s
if (newPage.matchPath?.includes(`/${language}/${language}/*`)) {
newPage = { ...newPage, matchPath: `/${language}/*` }
}

// on dev, we will have 2 pages for the default lang
// - 1 for the ones with the prefix `/{defaultLang}/learn/`
// - 1 for the ones without the prefix `/learn/`
// we do this to avoid having a 404 on those without the prefix since in
// dev we don't have the redirects from the server
deletePage(page)

if (IS_DEV) {
createPage<Context>(newPage)
}

// `routed` means that the page have the lang prefix on the url
// e.g. `/en/learn` or `/en`
if (!IS_DEV && i18n.routed) {
createPage<Context>(newPage)

const rootPath = page.path.slice(3)
if (isDefaultLang && !rootPath.match(/^\/404(\/|.html)$/)) {
createRedirect({
...commonRedirectProps,
fromPath: rootPath,
toPath: page.path,
})
}
}
}
}

Expand Down
31 changes: 0 additions & 31 deletions gatsby-ssr.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,3 @@
*
* See: https://www.gatsbyjs.org/docs/ssr-apis/
*/

import React from "react"

import type { GatsbySSR } from "gatsby"

import Layout from "./src/components/Layout"

import { Context } from "./src/types"
import { IS_DEV } from "./src/utils/env"
import { isLang } from "./src/utils/languages"

// Prevents <Layout/> from unmounting on page transitions
// https://www.gatsbyjs.com/docs/layout-components/#how-to-prevent-layout-components-from-unmounting
// @ts-ignore: returning `null` is not accepted by the `GatsbySSR` type def.
export const wrapPageElement: GatsbySSR<any, Context>["wrapPageElement"] = ({
element,
props,
}) => {
const { location } = props
const { pathname } = location

const [, pathLocale] = pathname.split("/")

// this is to avoid having hydration issues on dev mode. Check the logic
// inside gatsby-browser.tsx
if (IS_DEV && !isLang(pathLocale)) {
return null
}

return <Layout {...props}>{element}</Layout>
}
Loading