astro-i18n-aut
The i18n integration for Astro π§βπ
Built with β€οΈ for all Astro crewmates π§βπ
Motivation
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
Quick start
Install
Install via npm:
npm install astro-i18n-aut
Configure
In your Astro config file:
import { defineConfig } from "astro/config";
import { i18n, defaultLocaleSitemapFilter } 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({
experimental: {
redirects: true,
},
site: "https://example.com",
trailingSlash: "always",
build: {
format: "directory",
},
integrations: [
i18n({
locales,
defaultLocale,
}),
sitemap({
i18n: {
locales,
defaultLocale,
},
filter: defaultLocaleSitemapFilter({ defaultLocale }),
}),
],
});
In your Astro middleware file:
import { sequence } from "astro/middleware";
import { i18nMiddleware } from "astro-i18n-aut";
const i18n = i18nMiddleware({ defaultLocale: "en" });
export const onRequest = sequence(i18n);
In your .gitignore
file:
astro_tmp_pages_*
Usage
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
If you have enabled redirectDefaultLocale
(true
by default) and have setup the i18nMiddleware
, redirects will be:
/en/about
=>/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 { getLocale } from "astro-i18n-aut";
import Layout from "../layouts/Layout.astro";
const locale = getLocale(Astro.url);
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>
Options
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"]
License
MIT Licensed
Contributing
PRs welcome! Thank you for your contributions.
The How
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.
Astro also does not support Configured Redirects for non-existent routes, so middleware must be used with src/astro_tmp_pages_DEFAULTLOCALE
to create redirects.