Skip to main content

i18n with Redwood

This is an opinionated guide of implementing Internationalization with Redwood.js

Initial Setupโ€‹

yarn rw setup i18n

i18n.jsโ€‹

Extract the allowed list for i18n.

import i18n from 'i18next'
import LanguageDetector from 'i18next-browser-languagedetector'
import { initReactI18next } from 'react-i18next'

import en from './locales/en.json'
import fr from './locales/fr.json'
import ko from './locales/ko.json'

const languages = {
en: {
translation: en,
},
fr: {
translation: fr,
},
ko: {
translation: ko,
},
}

i18n
// learn more: https://github.com/i18next/i18next-browser-languageDetector
.use(LanguageDetector)
.use(initReactI18next)
.init({
interpolation: { escapeValue: false }, // React already does escaping
fallbackLng: 'en',
resources: languages,
})

export const allowedLanguagesList = Object.keys(languages) // ๐ŸคŸ Here!

export default i18n

Routing and Navigatingโ€‹

Each path must start with the lang parameter as follows.

<Route path="/{lang:String}" page={HomePage} name="home" />

Navigating must have lang.

<Link to={routes.home({ lang: 'en' })}>English</Link>

Every page must have the following lang property

import { useEffect } from 'react'

import { useTranslation } from 'react-i18next'

import { Redirect, routes } from '@redwoodjs/router'
import { MetaTags } from '@redwoodjs/web'

import ArticlesCell from 'src/components/ArticlesCell'
import { allowedLanguagesList } from 'src/i18n'

const HomePage = ({ lang }) => {
const { i18n } = useTranslation()
useEffect(() => {
i18n.changeLanguage(lang)
}, [lang, i18n])

// 1. website.com/en/about is allowed

// 2. !lang -> The `lang` property is missing.
// i.e., website.com/about

// 3. !allowedLanguagesList.includes(lang) -> the `lang` property is not in our defined list.
// i.e., website.com/zz/about
if (!lang || !allowedLanguagesList.includes(lang)) {
if (allowedLanguagesList.includes(navigator.language)) {
// ๐Ÿ’ฌ Try to use the navigator.language
return <Redirect to={routes.home({ lang: navigator.language })} />
} else {
// ๐Ÿ‡บ๐Ÿ‡ธ English as the default fallback
return <Redirect to={routes.home({ lang: 'en' })} />
}
}

return (
<>
<MetaTags title="Home" description="Home page" />
<ArticlesCell />
</>
)
}

export default HomePage

Headersโ€‹

This will gently redirect if the lang property does not exist.

Below is hreflang to others, using allowedLanguageList

<Head lang={/* Current Language*/}></Head>

Sitemap.xmlโ€‹

... Should be generated accordingly

Considerationโ€‹

Can we redirect by inserting the current navigator language?

For example, if we land on website.com/about,

  • redirect to website.com/en/about for English users
  • redirect to website.com/ko/about for Korean users
  • That is, maintaining user location and path context.
  • One way is to use window.location.pathname

Referenceโ€‹