Last active
September 2, 2019 11:22
-
-
Save acewf/e7f183a0cbc38b6dcd6581bdc10ed9ee to your computer and use it in GitHub Desktop.
gatsby i18next localisation for static pages
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// load your translations | |
// add whatever number namespaces you need | |
const localesNSContent = { | |
'en':[ | |
{ | |
content:fs.readFileSync(`src/locales/en/translations.json`, 'utf8'), | |
ns:'translations' | |
} | |
], | |
'pt':[ | |
{ | |
content:fs.readFileSync(`src/locales/pt/translations.json`, 'utf8'), | |
ns:'translations' | |
} | |
], | |
}; | |
const availableLocales = [ | |
{ value: 'en', text: 'English' }, | |
{ value: 'de', text: 'Deutsch' } | |
] | |
exports.onCreatePage = async (props) => { | |
const { page, actions: { createPage, deletePage, createRedirect } } = props; | |
deletePage(page); | |
if (page.path.includes('404')) { | |
createPage({ | |
...page, | |
context: { | |
locale: 'en-us', | |
data: localesNSContent['en-us'] | |
} | |
}) | |
} | |
if (page.path === '/') { | |
createPage({ | |
...page, | |
context: { | |
availableLocales | |
} | |
}); | |
} else { | |
availableLocales.map(({ value }) => { | |
let newPath = `/${value}${page.path}`; | |
if (page.path === '/homepage/') { | |
newPath = `/${value}` | |
} | |
const localePage = { | |
...page, | |
originalPath: page.path, | |
path: newPath, | |
context: { | |
availableLocales, | |
locale: value, | |
routed: true, | |
data: localesNSContent[value], | |
originalPath: page.path | |
}, | |
} | |
createPage(localePage) | |
}); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// file location could be src/i18n/index.js | |
import i18n from "i18next" | |
export const defaultLocale = 'en' | |
export const defaultNamespace = 'translations' | |
export const options = { | |
fallbackLng: defaultLocale, | |
ns: [defaultNamespace], | |
defaultNS: defaultNamespace, | |
debug: true, | |
interpolation: { | |
escapeValue: false, // not needed for react!! | |
}, | |
react: { | |
wait: true, | |
} | |
} | |
export default () => { | |
i18n.init(options); | |
return i18n; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// file location should be src/pages/page-2.js | |
import React from 'react' | |
import { Link } from 'gatsby' | |
import Layout from '../components/layout' | |
import SEO from '../components/seo' | |
import withI18next from '../components/withI18next' | |
const SecondPage = ({ pageContext: { locale }, t }) => { | |
return ( | |
<Layout> | |
<SEO title="Page two" /> | |
<h1>{t('title')}</h1> | |
<p>Welcome to page 2</p> | |
<p>{'login'}</p> | |
<Link to={`/${locale}/`}>Go back to the homepage</Link> | |
</Layout> | |
) | |
} | |
export default withI18next({ ns: 'translations' })(SecondPage); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// file location could be src/components/withI18next.js | |
import React, { Component } from 'react'; | |
import { I18nextProvider } from 'react-i18next'; | |
import { I18nProvider } from 'gatsby-i18n'; | |
import { I18n } from 'react-i18next'; | |
// import from /src/i18n/index.js | |
import setupI18next from '../i18n'; | |
const lngFormat = (locale) => (locale.replace(/-[a-z]{2}$/, e => (e.toUpperCase()))) | |
const withI18next = (options = {}) => Comp => { | |
class I18nHOC extends Component { | |
constructor(props) { | |
super(props); | |
const { pageContext, data } = props; | |
this.state = { | |
...options, | |
data: (data) ? data : pageContext.data | |
} | |
this.i18n = setupI18next(pageContext); | |
this.activateLng(); | |
} | |
activateLng = () => { | |
const { pageContext } = this.props; | |
const { data, parserMethod } = this.state; | |
this.parseFromContext(data); | |
this.i18n.changeLanguage(lngFormat(pageContext.locale)); | |
}; | |
parseFromContext = (data) => { | |
const { pageContext } = this.props; | |
if (data) { | |
const lng = lngFormat(pageContext.locale); | |
data.forEach(({ ns = 'translations', content }) => { | |
if (!this.i18n.hasResourceBundle(lng, ns)) { | |
this.i18n.addResources(lng, ns, content); | |
} | |
}); | |
} | |
} | |
componentDidUpdate(prevProps) { | |
if (this.props.pageContext.locale !== prevProps.pageContext.locale) { | |
this.activateLng(); | |
} | |
} | |
render() { | |
const { ns } = this.state; | |
return ( | |
<I18nextProvider i18n={this.i18n} defaultNS={ns}> | |
<I18nProvider {...this.props.pageContext}> | |
<I18n> | |
{t => ( | |
<Comp {...this.props} t={t} locale={this.props.pageContext.locale} /> | |
)} | |
</I18n> | |
</I18nProvider> | |
</I18nextProvider> | |
); | |
} | |
} | |
return I18nHOC; | |
}; | |
export default withI18next; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment