Built with β€οΈ for all Astro crewmates π§βπ
Provide an internationalization (i18n) integration for Astro that:
- Supports the
defaultLocale
- Avoids template file duplication
- Is adapter agnostic
- Is UI framework agnostic
- Is compatible with
@astrojs/sitemap
Install via npm:
npm install astro-i18n-aut
In your Astro config file:
import { defineConfig } from "astro/config";
import i18n from "astro-i18n-aut";
import sitemap from "@astrojs/sitemap";
const defaultLocale = "en";
const locales = {
en: "en-US", // the `defaultLocale` value must present in `locales` keys
es: "es-ES",
fr: "fr-CA",
};
export default defineConfig({
site: "https://example.com",
trailingSlash: "always",
build: {
format: "directory",
},
integrations: [
i18n({
locales,
defaultLocale,
}),
sitemap({
i18n: {
locales,
defaultLocale,
},
}),
],
});
Now that you have set up the config, each .astro
page will have additional renders with your other languages. For example, src/pages/about.astro
will render as:
/about
/es/about
/fr/about
Please note that the getStaticPaths()
function will only run once. This limitation means that you cannot have translated urls, such as /es/acerca-de
for /about
. However, it also ensures compatibility with @astrojs/sitemap
.
The Astro frontmatter and page content is re-run for every translated page. For example, the Astro.url.pathname
will be:
/about
/es/about
/fr/about
It is up to you to detect which language is being rendered. You can use Astro content collections or any i18n UI framework, such as react-i18next
, for your translations. Here is a pure Hello World
example:
---
import Layout from "../layouts/Layout.astro";
const locale = Astro.url.pathname.slice(1, 3);
let title: string;
switch (locale) {
case "es":
title = "Β‘Hola Mundo!";
break;
case "fr":
title = "Bonjour Monde!";
break;
default:
title = "Hello World!";
}
---
<Layout title={title}>
<h1>{title}</h1>
</Layout>
include
: glob pattern(s) to include (default:["pages/**/*"]
)exclude
: glob pattern(s) to exclude (default:["pages/api/**/*"]
)
Other Astro page file types:
- β
.astro
- β
.md
- β
.mdx
(with the MDX Integration installed) - β
.html
- β
.js
β/β.ts
(as endpoints)
cannot be translated. If you choose to use them, please add them to the ignore glob patterns. For example, ["pages/api/**/*", "pages/**/*.md"]
MIT Licensed
PRs welcome! Thank you for your contributions.
Unfortunately, i18n is not a first-class concern for Astro. While Astro documents i18n in their cookbook, they do not support a defaultLocale
.
The other community integrations that Astro links do not support all adapters:
- astro-i18next An Astro integration for i18next including some utility components.
- astro-i18n A TypeScript-first internationalization library for Astro.
Astro does not easily support two pages having the same content:
- Route variables
/[lang]/about
cannot be undefined or an empty string - Middleware
request.url
is read-only, so it is not possible to retrieve content from a different url - Configured redirects do not support route transitions like
'/article': '/blog/[...slug]'
, only'/blog/[...slug]': '/articles/[...slug]'
- The
injectRoute
method cannot inject anentryPoint
that is already being used in the build command
We duplicate the src/pages
folder multiple times and use injectRoute
as a workaround. You can safely delete any src/astro_tmp_pages_LOCALE
folders, but those will be automatically cleaned on every started and completed build.