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)