Light and easy solution to translate your Next.js apps.
This is a simpler alternative to next-i18next.
Table of contents
Example
Installation
# regular NPM package install
npm install --save @mies-co/next-lng
# install directly from GitHub
npm install --save github:@mies-co/next-lng
# install NPM package via Yarn
yarn add @mies-co/next-lng
OR USING THE GITHUB REGISTRY
You may also create a .npmrc file at the root of your Next.js app, with the following content:
# Specifies the registraty for @mies-co packages
@mies-co:registry=https://npm.pkg.github.com/
Then add this in package.json:
{
"dependencies": {
"@mies-co/next-lng": "latest"
}
}
Basic translation
import { withLng, useLng, getServerSidePropsLng, Link } from "@mies-co/next-lng";
const HomePage = props => {
// useLng can be used anywhere in your app, it's a React context.
const { lng, setLng, t } = useLng();
// NB! the ids on dom elements are used only for testing purposes and can be safely deleted
return (
<>
<h1>Basic example</h1>
<h2 id="x-greet">{t("greet")}</h2>
<p id="x-whoami">{t("whoami", { firstname: "Bob" })}</p>
<button onClick={() => setLng("en")}>EN</button>
<button onClick={() => setLng("fr")}>FR</button>
<p>Current language is {lng}</p>
<br />
<h2>Links:</h2>
<Link href="/legacy">
<a>Legacy example</a>
</Link>
<br />
<Link href="/scoped">
<a>Scoped example</a>
</Link>
<br />
<Link href="/[slug]" as="/with-slug">
<a>Slug example</a>
</Link>
</>
);
};
export { getServerSidePropsLng as getServerSideProps };
export default withLng(HomePage);
-
withLng
: A HOC to wrap your page with. -
useLng
: A react context exposinglng
,setLng
andt
. -
getServerSidePropsLng
: An async function fetches your lng API route
Scoped translation
// Example of scoped translation
import { withLng, useLng, getTranslations } from "@mies-co/next-lng";
const Scoped = () => {
// useLng can be used anywhere in your app, it's a React context.
const { lng, setLng, t } = useLng();
// NB! the ids on dom elements are used only for testing purposes and can be safely deleted
return (
<>
<h1>Scoped example</h1>
<h2 id="x-header-title">{t("header:title")}</h2>
<p id="x-greet">{t("greet")}</p>
<p id="x-whoami">{t("whoami", { firstname: "Bob" })}</p>
<button onClick={() => setLng("en")}>EN</button>
<button onClick={() => setLng("fr")}>FR</button>
<p>Current language is {lng}</p>
</>
);
};
// Arguments:
// [0] - a string or string[] of globs
// [1] - an object that overrides the default `options` defined in next.config.js
const getServerSideProps = getTranslations(["*/common", "header"], { shallow: false });
export { getServerSideProps };
export default withLng(Scoped);
-
withLng
: A HOC to wrap your page with. -
useLng
: A react context exposinglng
,setLng
andt
. -
getTranslations
: A function that passes extra arguments to the default getServerSideProps (fetching your API routes)- [0] A glob string or an array of glob strings that match the translations files to be fetched
- [1] The options object overrides the options defined in your
next.config.js
file. It enables to override "per-file".
Legacy getInitialProps translation
// Example of legacy getInitialProps usage
import { withLng, useLng, getTranslations } from "@mies-co/next-lng";
const Legacy = props => {
// useLng can be used anywhere in your app, it's a React context.
const { lng, setLng, t } = useLng();
// NB! the ids on dom elements are used only for testing purposes and can be safely deleted
return (
<>
<h1>Legacy example</h1>
<h2 id="x-header-title">{t("header:title")}</h2>
<p id="x-greet">{t("greet")}</p>
<p id="x-whoami">{t("whoami", { firstname: "Bob" })}</p>
<button onClick={() => setLng("en")}>EN</button>
<button onClick={() => setLng("fr")}>FR</button>
<p>Current language is {lng}</p>
</>
);
};
Legacy.getInitialProps = async () => {
return {
// Pass a lng object that describes the scope and options to pass
// This is only if you want to use scoped translations or customize the options. Otherwise don't even return anything.
lng: {
scope: ["*/common", "header"],
// options: { shallow: false }
}
};
};
export default withLng(Legacy);