Skip to content

[Astro] How to Set Up i18n and Localization

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:

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>

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