astro-i18next
An astro integration of i18next + some utility components to help you trans...
README
🧪 astro-i18next
Note
Status - 🚧 Beta
[👉 Road to v1.0.0](https://github.com/yassinedoghri/astro-i18next/issues/19)
You can use it, and feedback is more than welcome! Note that some breaking
changes may still be introduced during this phase as the goal for v1 is to get
the best possible DX for translating your Astro pages.
Examples
Example | Status |
---|---|
------------------------------------- | ---------------------------------------------------------------------------------------------------- |
[SSG | [![example-up-badge]](examples/basics) |
[SSR | [![example-up-badge]](examples/node) |
[**React**](examples/react) | [![example-up-badge]](examples/react) |
[SSR | [![example-down-badge]](examples/netlify) |
SSR | [![example-down-badge]](examples/basics) |
🚀 Getting started
1. Install
- ``` sh
- npm install astro-i18next
- ```
2. Configure
- ``` js
- import { defineConfig } from "astro/config";
- import astroI18next from "astro-i18next";
- export default defineConfig({
- integrations: [astroI18next()],
- });
- ```
- ``` js
- /** @type {import('astro-i18next').AstroI18nextConfig} */
- export default {
- defaultLocale: "en",
- locales: ["en", "fr"],
- };
- ```
- ``` sh
- public
- └── locales # create this folder to store your translation strings
- ├── en
- | └── translation.json
- └── fr
- └── translation.json
- ```
3. Start translating
- ```astro
- ---
- // src/pages/index.astro
- import i18next, { t } from "i18next";
- import { Trans, HeadHrefLangs } from "astro-i18next/components";
- ---
- <html lang={i18next.language}>
- <head>
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width" />
- <title>{t("site.title")}</title>
- <meta name="description" content={t("site.description")} />
- <HeadHrefLangs />
- </head>
- <body>
- <h1>{t("home.title")}</h1>
- <p>
- <Trans i18nKey="home.subtitle">
- This is a <em>more complex</em> string to translate, mixed with <strong
- >html elements
- </strong> such as /example.com/">a cool link</a>!
- </Trans>
- </p>
- </body>
- </html>
- ```
- ``` json
- // public/locales/en/translation.json
- {
- "site": {
- "title": "My awesome website!",
- "description": "Here is the description of my awesome website!"
- },
- "home": {
- "title": "Welcome to my awesome website!",
- "subtitle": "This is a <0>more complex</0> string to translate, mixed with <1>html elements</1>, such as a <2>a cool link</2>!"
- }
- }
- ```
- ``` json
- // public/locales/fr/translation.json
- {
- "site": {
- "title": "Mon super site web !",
- "description": "Voici la description de mon super site web !"
- },
- "home": {
- "title": "Bienvenue sur mon super site web !",
- "subtitle": "Ceci est une chaine de charactères <0>plus compliquée</0> à traduire, il y a des <1>éléments html</1>, comme <2>un super lien</2> par exemple !"
- }
- }
- ```
- ``` sh
- npx astro-i18next generate
- ```
Note
For a real world example, see the demo project or try the _Astro
i18n basics example_ on StackBlitz:\
💻 CLI commands
generate
- ``` sh
- npx astro-i18next generate
- ```
- ``` sh
- src
- └── pages
- ├── about.astro
- └── index.astro
- ```
- ``` sh
- src
- └── pages
- ├── es
- | ├── about.astro
- | └── index.astro
- ├── fr
- | ├── about.astro
- | └── index.astro
- ├── about.astro
- └── index.astro
- ```
🔄 Translate Routes
- ``` sh
- src
- └── pages
- ├── about.astro
- ├── contact-us.astro
- └── index.astro
- ```
- ``` js
- /** @type {import('astro-i18next').AstroI18nextConfig} */
- export default {
- defaultLocale: "en",
- locales: ["en", "fr", "es"],
- routes: {
- fr: {
- "about": "a-propos",
- "contact-us": "contactez-nous",
- "products": {
- "index": "produits",
- "categories": "categories",
- }
- }
- es: {
- "about": "a-proposito",
- "contact-us": "contactenos",
- "products": {
- "index": "productos",
- "categories": "categorias",
- }
- }
- },
- };
- ```
- ``` sh
- src
- └── pages
- ├── es
- | ├── productos
- | | ├── categorias.astro
- | | └── index.astro
- | ├── a-proposito.astro
- | ├── contactenos.astro
- | └── index.astro
- ├── fr
- | ├── produits
- | | ├── categories.astro
- | | └── index.astro
- | ├── a-propos.astro
- | ├── contactez-nous.astro
- | └── index.astro
- ├── products
- | ├── categories.astro
- | └── index.astro
- ├── about.astro
- ├── contact-us.astro
- └── index.astro
- ```
Note
The localizedPath and
localizeUrl utility functions will retrieve the
correct route based on your mappings.
📦 Utility components
Trans component
- ```astro
- ---
- import { Trans } from "astro-i18next/components";
- ---
- <Trans i18nKey="superCoolKey">
- An <a href="https://astro.build" title="Astro website">astro</a> integration of
- <a href="https://www.i18next.com/" title="i18next website">i18next</a> and utility
- components to help you translate your astro websites!
- </Trans>
- ```
- ``` json
- // fr.json
- {
- "superCoolKey": "Une intégration <0>astro</0> d'<1>i18next</1> + quelques composants utilitaires pour vous aider à traduire vos sites astro !"
- }
- ```
Trans Props
Prop | Type | Description |
---|---|---|
--------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
i18nKey | ?string | Internationalization |
ns | ?string | Namespace |
LanguageSelector component
- ```astro
- ---
- import { LanguageSelector } from "astro-i18next/components";
- ---
- <LanguageSelector showFlag={true} class="my-select-class" />
- ```
LanguageSelector Props
Prop | Type | Description |
---|---|---|
--------- | ------------------ | --------------------------------------------------------- |
showFlag | ?boolean | Choose |
HeadHrefLangs component
- ```astro
- ---
- import i18next from "i18next";
- import { HeadHrefLangs } from "astro-i18next/components";
- ---
- <html lang={i18next.language}>
- <head>
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width" />
- <title>...</title>
- <meta name="description" content="..." />
- <HeadHrefLangs />
- </head>
- <body>...</body>
- </html>
- ```
- ``` html
- <link rel="alternate" hreflang="en" href="https://www.example.com/about/" />
- <link rel="alternate" hreflang="fr" href="https://www.example.com/fr/about/" />
- <link rel="alternate" hreflang="es" href="https://www.example.com/es/about/" />
- ```
📦 Utility functions
interpolate function
localizePath function
Note
This should be used instead of hard coding paths to other pages. It will take
care of setting the right path depending on the locale you set.
- ```astro
- ---
- import { localizePath } from "astro-i18next";
- import i18next from "i18next";
- i18next.changeLanguage("fr");
- ---
- <a href={localizePath("/about")}>...</a>
- ```
localizeUrl function
Note
This should be used instead of hard coding urls for internal links. It will
take care of setting the right url depending on the locale you set.
- ```astro
- ---
- import { localizeUrl } from "astro-i18next";
- import i18next from "i18next";
- i18next.changeLanguage("fr");
- ---
- <a href={localizeUrl("https://www.example.com/about")}>...</a>
- ```
👀 Going further
Namespaces
- ``` sh
- public
- ├-- locales
- | |-- en
- | | |-- about.json # "about" namespace
- | | |-- common.json # "common" namespace
- | | └-- home.json # "home" namespace
- | └-- fr # same files in other locale folders
- src
- └-- pages
- |-- about.astro
- └-- index.astro
- ```
- ```ts
- /** @type {import('astro-i18next').AstroI18nextConfig} */
- export default {
- defaultLocale: "en",
- locales: ["en", "fr"],
- namespaces: ["about", "common", "home"],
- defaultNamespace: "common",
- };
- ```
- ```astro
- ---
- import { t, setDefaultNamespace } from "i18next";
- import { Trans } from "astro-i18next/components";
- setDefaultNamespace("home");
- ---
- <h1>{t("myHomeTitle")}</h1>
- <p>
- <Trans i18nKey="myHomeDescription">
- This translation is loaded from the default <strong>home</strong> namespace!
- </Trans>
- </p>
- <p>
- <Trans i18nKey="myCommonCTA" ns="common">
- This translation is loaded from the <strong>common</strong> namespace!
- </Trans>
- </p>
- <button>{t("common:buttonCTA")}</button>
- ```
AstroI18nextConfig Props
Prop | Type | Description |
---|---|---|
-------------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
defaultLocale | `string` | The |
locales | `string[]` | Your |
namespaces | `string` | String |
defaultNamespace | `string` | Default |
load | `Array<"server" | Load |
i18nextServer | `?InitOptions` | The |
i18nextServerPlugins | `?{[key: | Set |
i18nextClient | `?InitOptions` | The |
i18nextClientPlugins | `?{[key: | Set |
routes | `[segment: | The |
showDefaultLocale | `boolean`(`false`) | Whether |