The i18n tool for next.js ssg project.
yarn add i18next-ssg next-i18next react-i18next i18next
First, create a next-i18next.config.js
file in the root of your project.
next-i18next.config.js
module.exports = {
i18n: {
defaultLocale: "en", // the default language
locales: ["en", "zh"], // language list
},
};
And You have to expose the i18n
config as the next.js Environment Variable NEXT_PUBLIC_I18N
.
next.config.js
const { i18n } = require("./next-i18next.config");
module.exports = {
env: {
NEXT_PUBLIC_I18N: i18n,
},
};
- public
- locales
- zh
- common.json
- en
- common.json
- ... other languages
public/locales/en/common.json
{
"title": "English Title"
}
If you want to structure your translations/namespaces in a custom way, you will need to pass modified localePath
and localeStructure
values into next-i18next.config.js
. Check detail here https://github.com/i18next/next-i18next#options
pages/_app.tsx
add appWithTranslation
logic
import { appWithTranslation } from "i18next-ssg";
const App = ({ Component, pageProps }) => <Component {...pageProps} />;
export default appWithTranslation(App);
pages
- [locale]
- index.tsx
- second.tsx
- third.tsx
/second/index.tsx
and/second.tsx
both work fine for/second
Add locale inject logic in every page, for example:
pages/[locale]/index.tsx
import { makeStaticProps, getStaticPaths } from "i18next-ssg/server";
export default Page(){
return <div>Page</div>
}
const getStaticProps = makeStaticProps(["common"]);
export { getStaticPaths, getStaticProps };
for example:
import { useTranslation } from "i18next-ssg";
export default function Title() {
const { t } = useTranslation("common");
return <div>{t("title")}</div>;
}
First, create [[...paths]].tsx
under the pages
folder (i18next-ssg will auto generate the root pages based on the pages you created under [locale]
)
pages/[[...paths]].tsx
copy pause the code directly without any changes, it will works fine for your project.
export { getStaticProps, getStaticPaths } from "i18next-ssg/Redirect";
import { useRootPathRedirect } from "i18next-ssg";
export default function Page() {
useRootPathRedirect();
return <div>Redirecting...</div>;
}
Then, the auto redirect logic works like this:
- / => /[locale]
- /second => /[locale]/second
- /third => /[locale]/third
The [locale]
value based on getLocale
, which strategy works follow this:
[url locale]
> [user set locale in localStorage]
> [locale detect from browser navigator]
After all these steps and run yarn build
(next build && next export -o build
), you will get output files below:
- build
- locales
- ... your locale json files
- index.html
- second.html
- third.html
- zh.html
- en.html
- en
- second.html
- third.html
- zh
- second.html
- third.html
this work fine on both server and browser.
import { config } from "i18next-ssg";
console.log(config.locales);
console.log(config.defaultLocale);
import {
appWithTranslation,
serverSideTranslations,
i18n,
withTranslation,
I18nContext,
Trans,
Translation,
useTranslation,
} from "i18next-ssg";
import { I18NLink } from "i18next-ssg";
export default function Pages() {
return <I18NLink href="/sansa">Sansa</I18NLink>; // /sansa => /[locale]/sansa
}
import { useRouter } from "next/router";
import { localize } from "i18next-ssg";
export default function Pages() {
const router = useRouter();
return (
<span
onClick={() => {
router.push(localize("/sansa")); // /sansa => /[locale]/sansa
}}
>
Sansa
</span>
);
}
import Link from "next/link";
import { useLocaleSwitcher, setUserLocale } from "i18next-ssg";
const localeMap: Record<Locale, string> = {
en: "English",
zh: "中文",
};
function LocaleSwitcher() {
const {
label, // current locale label
options, // the option list of other locales
} = useLocaleSwitcher({ localeMap });
return (
<div>
<label>{label}</label>
<ul>
{options.map(({ label, path, locale }) => (
<li key={path}>
<Link href={path}>
<span
onClick={() => {
setUserLocale(locale);
}}
>
{label}
</span>
</Link>
</li>
))}
</ul>
</div>
);
}
export default LocaleSwitcher;