From a61bfcefa672b2196bc52caf3b8bab0f5ac7325e Mon Sep 17 00:00:00 2001 From: Olivier Lacroix Date: Mon, 31 May 2021 09:03:19 +1000 Subject: [PATCH 1/4] Allow localization of selected pages only --- packages/gatsby-theme-i18n/README.md | 4 +++- packages/gatsby-theme-i18n/gatsby-node.js | 5 +++++ packages/gatsby-theme-i18n/index.d.ts | 3 ++- .../src/components/localized-link.js | 3 ++- .../src/components/localized-router.js | 2 ++ .../gatsby-theme-i18n/src/components/seo.js | 5 +++-- packages/gatsby-theme-i18n/src/helpers.js | 18 +++++++++++++++++- .../src/hooks/use-localization.js | 1 + 8 files changed, 35 insertions(+), 6 deletions(-) diff --git a/packages/gatsby-theme-i18n/README.md b/packages/gatsby-theme-i18n/README.md index a30be894..634a13fe 100755 --- a/packages/gatsby-theme-i18n/README.md +++ b/packages/gatsby-theme-i18n/README.md @@ -36,6 +36,7 @@ A Gatsby theme for providing internationalization support to your Gatsby site by - `localName`: The local name of the locale - `langDir`: The direction of language (e.g. "ltr", "rtl") - `dateFormat`: The tokens that [Moment.js](https://momentjs.com/docs/#/parsing/string-format/) accepts for date formatting. This can be used for dates on GraphQL queries + - `pages`: Optional array of RegExp strings. If set, generates localized pages only when matching one of the RegExps (e.g. `["^\\/$", "^\\/about\\/?$"]` will generate localised version of "/" and "/about" pages only) Example config of English and German: @@ -55,7 +56,8 @@ A Gatsby theme for providing internationalization support to your Gatsby site by "name": "German", "localName": "Deutsch", "langDir": "ltr", - "dateFormat": "DD.MM.YYYY" + "dateFormat": "DD.MM.YYYY", + "pages": ["^\\/$", "^\\/about\\/?$"] } ] ``` diff --git a/packages/gatsby-theme-i18n/gatsby-node.js b/packages/gatsby-theme-i18n/gatsby-node.js index 2031881f..02e9b0b7 100644 --- a/packages/gatsby-theme-i18n/gatsby-node.js +++ b/packages/gatsby-theme-i18n/gatsby-node.js @@ -6,6 +6,7 @@ const { localizedPath, getLanguages, getDefaultLanguage, + isLocalizedPage, } = require(`./src/helpers`) function writeFile(filePath, data, reporter) { @@ -82,6 +83,7 @@ exports.createSchemaCustomization = ({ actions }) => { code: String hrefLang: String dateFormat: String + pages: [String] langDir: String localName: String name: String @@ -158,6 +160,9 @@ exports.onCreatePage = ({ page, actions }, themeOptions) => { }) languages.forEach((locale) => { + + if (!isLocalizedPage(locale, originalPath)) return null + const newPage = { ...page, path: localizedPath({ diff --git a/packages/gatsby-theme-i18n/index.d.ts b/packages/gatsby-theme-i18n/index.d.ts index 27154429..71f8a569 100755 --- a/packages/gatsby-theme-i18n/index.d.ts +++ b/packages/gatsby-theme-i18n/index.d.ts @@ -23,11 +23,12 @@ export function LocalizedRouter({ basePath, children, ...props }: { children: any; }): JSX.Element; export function LocalesList(): JSX.Element; -export function localizedPath({ defaultLang, prefixDefault, locale, path }: { +export function localizedPath({ defaultLang, prefixDefault, locale, path, config }: { defaultLang: any; prefixDefault: any; locale: any; path: any; + config: any; }): any; export function useLocalization(): { locale: string; diff --git a/packages/gatsby-theme-i18n/src/components/localized-link.js b/packages/gatsby-theme-i18n/src/components/localized-link.js index 846de21d..8e6eb97c 100644 --- a/packages/gatsby-theme-i18n/src/components/localized-link.js +++ b/packages/gatsby-theme-i18n/src/components/localized-link.js @@ -4,7 +4,7 @@ import { localizedPath } from "../helpers" import { useLocalization } from "../hooks/use-localization" export const LocalizedLink = ({ to, language, ...props }) => { - const { defaultLang, prefixDefault, locale } = useLocalization() + const { defaultLang, prefixDefault, locale, config } = useLocalization() const linkLocale = language || locale return ( @@ -15,6 +15,7 @@ export const LocalizedLink = ({ to, language, ...props }) => { prefixDefault, locale: linkLocale, path: to, + config, })} /> ) diff --git a/packages/gatsby-theme-i18n/src/components/localized-router.js b/packages/gatsby-theme-i18n/src/components/localized-router.js index 163f4670..81bdad25 100644 --- a/packages/gatsby-theme-i18n/src/components/localized-router.js +++ b/packages/gatsby-theme-i18n/src/components/localized-router.js @@ -8,12 +8,14 @@ export const LocalizedRouter = ({ basePath, children, ...props }) => { locale, defaultLang, prefixDefault, + config, } = useLocalization() const path = localizedPath({ defaultLang, prefixDefault, locale, path: basePath, + config, }) return ( diff --git a/packages/gatsby-theme-i18n/src/components/seo.js b/packages/gatsby-theme-i18n/src/components/seo.js index edb6769a..07726770 100644 --- a/packages/gatsby-theme-i18n/src/components/seo.js +++ b/packages/gatsby-theme-i18n/src/components/seo.js @@ -2,6 +2,7 @@ import * as React from "react" import { Helmet } from "react-helmet" import { useStaticQuery, graphql, withPrefix } from "gatsby" import { useLocalization } from "../hooks/use-localization" +import { isLocalizedPage } from "../helpers" const SEO = ({ location, pageContext }) => { const { locale, config, defaultLang } = useLocalization() @@ -31,7 +32,7 @@ const SEO = ({ location, pageContext }) => { {config.map((l) => { let href - if (l.code === locale) return null + if (l.code === locale || !isLocalizedPage(l, pageContext.originalPath)) return null if (l.code === defaultLang) { href = `${defaultSiteUrl}${ @@ -59,7 +60,7 @@ const SEO = ({ location, pageContext }) => { content={pageContext.hrefLang.replace(`-`, `_`)} /> {config.map((l) => { - if (l.code === locale) return null + if (l.code === locale || !isLocalizedPage(l, pageContext.originalPath)) return null return ( path.match(new RegExp(rule)))) { + return false + } else { + return true + } +} + +function localizedPath({ defaultLang, prefixDefault, locale, path, config }) { // The default language isn't prefixed if (isDefaultLang(locale, defaultLang) && !prefixDefault) { return path @@ -18,6 +26,13 @@ function localizedPath({ defaultLang, prefixDefault, locale, path }) { } // If it's another language, prefix with the locale + // falling back to defaultLang if path is not localized for locale (and config is provided) + if (config) { + const lang = config.find((lang) => lang.code === locale) + if (!isLocalizedPage(lang, path)) { + return prefixDefault ? `/${defaultLang}${path}` : path + } + } return `/${locale}${path}` } @@ -53,4 +68,5 @@ module.exports = { localizedPath, getLanguages, getDefaultLanguage, + isLocalizedPage, } diff --git a/packages/gatsby-theme-i18n/src/hooks/use-localization.js b/packages/gatsby-theme-i18n/src/hooks/use-localization.js index dd24917b..8054ccf9 100644 --- a/packages/gatsby-theme-i18n/src/hooks/use-localization.js +++ b/packages/gatsby-theme-i18n/src/hooks/use-localization.js @@ -19,6 +19,7 @@ const useLocalization = () => { langDir localName name + pages } } } From 2ef683ec28f1d43af0a9651256f1d3766bab0b42 Mon Sep 17 00:00:00 2001 From: Olivier Lacroix Date: Mon, 31 May 2021 22:18:23 +1000 Subject: [PATCH 2/4] Link does not fall back when language prop is set --- packages/gatsby-theme-i18n/src/components/localized-link.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gatsby-theme-i18n/src/components/localized-link.js b/packages/gatsby-theme-i18n/src/components/localized-link.js index 8e6eb97c..2cf4a691 100644 --- a/packages/gatsby-theme-i18n/src/components/localized-link.js +++ b/packages/gatsby-theme-i18n/src/components/localized-link.js @@ -15,7 +15,7 @@ export const LocalizedLink = ({ to, language, ...props }) => { prefixDefault, locale: linkLocale, path: to, - config, + config: language ? null : config, })} /> ) From 8e35d7871e71489d401a1ca406c2743e70d6d30d Mon Sep 17 00:00:00 2001 From: Olivier Lacroix Date: Mon, 31 May 2021 22:35:37 +1000 Subject: [PATCH 3/4] Make localizedPath config arg optional --- packages/gatsby-theme-i18n/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gatsby-theme-i18n/index.d.ts b/packages/gatsby-theme-i18n/index.d.ts index 71f8a569..b3f698d4 100755 --- a/packages/gatsby-theme-i18n/index.d.ts +++ b/packages/gatsby-theme-i18n/index.d.ts @@ -28,7 +28,7 @@ export function localizedPath({ defaultLang, prefixDefault, locale, path, config prefixDefault: any; locale: any; path: any; - config: any; + config?: any; }): any; export function useLocalization(): { locale: string; From 171e2fb5487ab77807e2d8a66447fe5a92e6eb1a Mon Sep 17 00:00:00 2001 From: Olivier Lacroix Date: Sun, 6 Jun 2021 12:15:57 +1000 Subject: [PATCH 4/4] Remove \\ --- packages/gatsby-theme-i18n/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/gatsby-theme-i18n/README.md b/packages/gatsby-theme-i18n/README.md index 634a13fe..340c09fc 100755 --- a/packages/gatsby-theme-i18n/README.md +++ b/packages/gatsby-theme-i18n/README.md @@ -36,7 +36,7 @@ A Gatsby theme for providing internationalization support to your Gatsby site by - `localName`: The local name of the locale - `langDir`: The direction of language (e.g. "ltr", "rtl") - `dateFormat`: The tokens that [Moment.js](https://momentjs.com/docs/#/parsing/string-format/) accepts for date formatting. This can be used for dates on GraphQL queries - - `pages`: Optional array of RegExp strings. If set, generates localized pages only when matching one of the RegExps (e.g. `["^\\/$", "^\\/about\\/?$"]` will generate localised version of "/" and "/about" pages only) + - `pages`: Optional array of RegExp strings. If set, generates localized pages only when matching one of the RegExps (e.g. `["^/$", "^/about/?$"]` will generate localised version of "/" and "/about" pages only) Example config of English and German: @@ -57,7 +57,7 @@ A Gatsby theme for providing internationalization support to your Gatsby site by "localName": "Deutsch", "langDir": "ltr", "dateFormat": "DD.MM.YYYY", - "pages": ["^\\/$", "^\\/about\\/?$"] + "pages": ["^/$", "^/about/?$"] } ] ```