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

feat(theme-i18n) Allow localization of a subset of pages for individual locales #133

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion packages/gatsby-theme-i18n/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand All @@ -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/?$"]
}
]
```
Expand Down
5 changes: 5 additions & 0 deletions packages/gatsby-theme-i18n/gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const {
localizedPath,
getLanguages,
getDefaultLanguage,
isLocalizedPage,
} = require(`./src/helpers`)

function writeFile(filePath, data, reporter) {
Expand Down Expand Up @@ -82,6 +83,7 @@ exports.createSchemaCustomization = ({ actions }) => {
code: String
hrefLang: String
dateFormat: String
pages: [String]
langDir: String
localName: String
name: String
Expand Down Expand Up @@ -158,6 +160,9 @@ exports.onCreatePage = ({ page, actions }, themeOptions) => {
})

languages.forEach((locale) => {

if (!isLocalizedPage(locale, originalPath)) return null

const newPage = {
...page,
path: localizedPath({
Expand Down
3 changes: 2 additions & 1 deletion packages/gatsby-theme-i18n/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion packages/gatsby-theme-i18n/src/components/localized-link.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand All @@ -15,6 +15,7 @@ export const LocalizedLink = ({ to, language, ...props }) => {
prefixDefault,
locale: linkLocale,
path: to,
config: language ? null : config,
})}
/>
)
Expand Down
2 changes: 2 additions & 0 deletions packages/gatsby-theme-i18n/src/components/localized-router.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down
5 changes: 3 additions & 2 deletions packages/gatsby-theme-i18n/src/components/seo.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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}${
Expand Down Expand Up @@ -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 (
<meta
key={l.code}
Expand Down
18 changes: 17 additions & 1 deletion packages/gatsby-theme-i18n/src/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@ function isDefaultLang(locale, defaultLang) {
return locale === defaultLang
}

function localizedPath({ defaultLang, prefixDefault, locale, path }) {
function isLocalizedPage({ pages }, path) {
if (pages && !pages.find((rule) => 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
Expand All @@ -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}`
}

Expand Down Expand Up @@ -53,4 +68,5 @@ module.exports = {
localizedPath,
getLanguages,
getDefaultLanguage,
isLocalizedPage,
}
1 change: 1 addition & 0 deletions packages/gatsby-theme-i18n/src/hooks/use-localization.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const useLocalization = () => {
langDir
localName
name
pages
}
}
}
Expand Down