i18next
Framework Next.js 13 Internationalization (i18n) i18next
Categories:
Start to using i18next
Install Packages
yarn add i18next
yarn add i18next-fs-backend
Create your locale json file
// public/locales/en/translation.json
{
"hello": "Hello",
"world": "World"
}
// public/locales/zh_TW/translation.json
{
"hello": "你好",
"world": "世界"
}
Init yout i18next setting
// app/layout.js
import i18next from 'i18next';
import Backend from 'i18next-fs-backend';
// init i18next locale language setting
i18next
.use(Backend)
.init({
// Let i18n can read later
initImmediate: false,
nonExplicitSupportedLngs: false,
// debug: true,
lng: 'en',
// fallbackLng: 'en',
fallbackLng: {
// Find language code => mapping exist language code
'zh': ['zh_TW'],
'zh-TW': ['zh_TW'],
'zh-Hant': ['zh_TW'],
'default': ['en']
},
preload: [
'en',
'zh_TW'
],
ns: ['translation'],
defaultNS: 'translation',
backend: {
loadPath: '../../public/locales/{{lng}}/{{ns}}.json'
},
}, (err, t) => {
// Debug
if (err) return console.error(err)
console.log('i18next is ready...')
console.log(t('hello'))
console.log(t('hello', { lng: 'zh_TW' }))
});
Show your locale messages
// app/layout.js
import i18next from 'i18next';
import Backend from 'i18next-fs-backend';
export default function RootLayout({ children }) {
<html lang="en">
<body>
{i18next.t('hello')}
{i18next.t('hello', { lng: 'zh_TW' })}
{children}
</body>
</html>
}
Detect and Change Browser Preference language
Install packages
yarn add accept-language-parser
Create i18next locale manager file
// app/i18NextLocaleManager.js
// https://beta.nextjs.org/docs/api-reference/headers
import { cookies, headers } from 'next/headers';
// https://www.i18next.com/
import i18next from 'i18next';
// https://www.npmjs.com/package/accept-language-parser?activeTab=readme
import acceptLanguageParser from 'accept-language-parser';
const DEFAULT_ALLOW_LANGUAGES_CODE_LIST = [
'en',
'zh-TW'
];
const DEFAULT_LOCALE_COOKIE_NAME = 'locale';
const getHeaderAcceptLanguagePreferenceLanguage = async function(
allow_language_code_list = DEFAULT_ALLOW_LANGUAGES_CODE_LIST
) {
// Get accept language from header
const accept_languages_header = headers().get('accept-language');
// Parse accept language header
const accept_language = acceptLanguageParser.pick(allow_language_code_list, accept_languages_header);
if (!accept_language) {
// Accept language not exist
return false;
}
return accept_language;
};
const getCookiePreferenceLanguage = async function(
locale_cookie_name = DEFAULT_LOCALE_COOKIE_NAME
) {
// Locale cookie
const locale_cookie = await cookies().get(locale_cookie_name);
if (!locale_cookie) {
// No locale cookie value
return null;
}
return locale_cookie.value;
}
const getCookiePreferenceLanguage = async function(
locale_cookie_name = DEFAULT_LOCALE_COOKIE_NAME
) {
// Locale cookie
const locale_cookie = await cookies().get(locale_cookie_name);
if (!locale_cookie) {
// No locale cookie value
return null;
}
return locale_cookie.value;
}
const getI18nextPreferenceLanguage = async function({
locale_cookie_name,
allow_language_code_list
}) {
// Get preference language from cookie
const cookie_locale = await getCookiePreferenceLanguage(locale_cookie_name);
if (cookie_locale) {
console.log('Set cookie locale', cookie_locale);
i18next.changeLanguage(cookie_locale);
// console.log(i18next.language);
return i18next.resolvedLanguage;
}
// Get preference language from header accept language
const header_accept_language_locale = await getHeaderAcceptLanguagePreferenceLanguage(allow_language_code_list);
if (header_accept_language_locale) {
console.log('Set header locale', header_accept_language_locale);
i18next.changeLanguage(header_accept_language_locale);
return i18next.resolvedLanguage;
}
return i18next.resolvedLanguage;
}
export {
getHeaderAcceptLanguagePreferenceLanguage,
getCookiePreferenceLanguage,
getI18nextPreferenceLanguage
}
Setting preference language
// app/layout.js
// https://www.i18next.com/
import i18next from 'i18next';
import { getI18nextPreferenceLanguage } from './i18NextLocaleManager';
export default async function RootLayout({ children }) {
await getI18nextPreferenceLanguage({
locale_cookie_name: 'locale',
allow_language_code_list: ['en', 'zh-TW']
});
return (
<html lang={i18next.language}>
<body>
{children}
</body>
</html>
);
}