Basics of i18n and localization on Astro.
Prerequisites
- Astro v5
Setting up astro.config.mjs
Astro provides built-in i18n routing.
You can configure routing and fallback behavior in astro.config.mjs
.
# astro.config.mjs
export default defineConfig({
i18n: {
defaultLocale: "ja",
locales: ["ja", "en"],
fallback: {
en: "ja",
},
},
});
This configuration means:
- default language: Japanese
- URLs
- Japanese (default): https://chocolat5.com
- English: https://chocolat5.com/en/
- If a file doesn’t exist for English, redirect to Japanese
You can also use subdirectories like https://en.chocolat5.com/
or include the default language in URL such as https://chocolat5.com/ja/
.
( You can check details on Astro DOCS )
Pages Directory
Create a locale forlder inside the pages directory.
Here’s an example when using prefixDefaultLocale: false
.
src/
pages/
index.astro
about/
index.astro
en/
index.astro
about/
index.astro
Each locale must follow the same structure as the default language. Also, folder names must exactly match your locales.
Setting <html>
Tag
You can get the current locale using an Astro API.
# Layout.astro
---
const currentLocale = Astro.currentLocale;
---
<html lang={currentLocale}>
...
</html>
Links
You can generate relaative URLs using the Astro API getRelativeLocaleUrl
.
Pass the arguments ()locale
and path
) to getRelativeLocaleUrl
.
path
is optional.
# Header.astro, Nav.astro etc.
---
import { getRelativeLocaleUrl } from "astro:i18n";
const currentLocale = Astro.currentLocale; // return "ja", "en"
---
<header>
<nav>
<a href={getRelativeLocaleUrl(currentLocale, "about")}>About</a>
</nav>
</header>
Result:
- if
locale = "ja"
→href="/about/"
- if
locale = "en"
→href="/en/about/"
Language Switcher UI
Here’s an example language switcher. I’m using this on my site. I made it simple sincce I only support two languages.
---
const locales = ["ja", "en"];
const languages = {
ja: "Japanese",
en: "English",
};
---
{
locales.map((locale: string, index: number) => (
<a class="support_button" href={getLocaleSwitcherURL(locale, pathname)}>
{languages[locale]}
</a>
))
}
getLocaleSwitcherURL()
is a custom helper function to generate the proper URL.
It returns a /
-prefixed URL for Japanese, and /en
-prefixed URL for English.
export const getLocaleSwitcherURL = (
locale: string,
pathname: string
): string => {
if (locale === "ja") {
return pathname.replace("/en", "");
} else {
return pathname.startsWith("/en") ? pathname : `/en${pathname}`;
}
};
References
- Internationalization API Reference – Astro DOCS https://docs.astro.build/en/reference/modules/astro-i18n/ (2026-08-24)
- Internationalization (i18n) Routing – Astro DOCS https://docs.astro.build/en/guides/internationalization/ (2026-08-24)