Astro i18n — Internationalization and Multi-Language Sites
In this tutorial, you will learn about Astro i18n. We cover key concepts, practical examples, and best practices to help you master this topic.
Learn Astro i18n: configure multi-language support, translate routes, manage locale-specific content, and implement language switching for global audiences.
In this lesson, you'll set up Internationalization in Astro, create locale-specific routes, translate content, and build a language switcher component.
What You'll Learn
How to configure i18n routing, create locale-specific pages, manage translations, implement language switching, and handle SEO for multi-language sites.
Why It Matters
Internationalization expands your audience to non-English speakers. Proper i18n setup ensures search engines index each language version correctly.
Real-World Use
DodaTech serves tutorials in English, Spanish, and French using Astro's i18n routing, with separate routes for each locale.
flowchart LR
A[URL Request] --> B{Locale Detection}
B -->|/en/| C[English Content]
B -->|/es/| D[Spanish Content]
B -->|/fr/| E[French Content]
style B fill:#ff5a03,color:#fff
Setting Up Locales
Create locale-specific content directories:
src/pages/
en/
index.astro
about.astro
es/
index.astro
about.astro
fr/
index.astro
about.astro
Configure i18n in astro.config.mjs:
import { defineConfig } from "astro/config";
export default defineConfig({
i18n: {
defaultLocale: "en",
locales: ["en", "es", "fr"],
fallback: {
es: "en",
fr: "en",
},
},
});
Language Switcher
Create a language switcher component:
---
const { currentLocale } = Astro.props;
const locales = [
{ code: "en", label: "English" },
{ code: "es", label: "Espanol" },
{ code: "fr", label: "Francais" },
];
---
<nav>
{locales.map(locale => (
<a
href={`/${locale.code}${Astro.url.pathname.replace(/^\/[a-z]{2}/, "")}`}
class={locale.code === currentLocale ? "active" : ""}
>
{locale.label}
</a>
))}
</nav>
Translating Content
Use a translation helper:
// src/i18n/translations.ts
const translations = {
en: { welcome: "Welcome", about: "About Us" },
es: { welcome: "Bienvenido", about: "Sobre Nosotros" },
fr: { welcome: "Bienvenue", about: "A Propos" },
};
export function t(locale: string, key: string): string {
return translations[locale]?.[key] ?? translations["en"][key];
}
Usage in a page:
---
import { t } from "../i18n/translations";
const locale = Astro.params.locale || "en";
---
<h1>{t(locale, "welcome")}</h1>
RTL Support
Add right-to-left support for Arabic, Hebrew, and other RTL languages:
// astro.config.mjs
i18n: {
defaultLocale: "en",
locales: ["en", "ar", "he"],
routing: {
prefixDefaultLocale: true,
rtl: ["ar", "he"],
},
},
Apply RTL styling:
<html dir={rtlLocales.includes(locale) ? "rtl" : "ltr"} lang={locale}>
SEO for i18n
Add hreflang tags for multi-language SEO:
<head>
<link rel="alternate" hreflang="en" href="https://example.com/en/about/" />
<link rel="alternate" hreflang="es" href="https://example.com/es/about/" />
<link rel="alternate" hreflang="x-default" href="https://example.com/about/" />
</head>
Common Mistakes
- Not setting
defaultLocale: Without a default locale, Astro doesn't know which language to serve for unprefixed URLs. - Missing fallback translations: When a translation key is missing, the fallback locale's value should be used.
- Ignoring RTL layout: Arabic and Hebrew text needs right-to-left alignment. Update CSS for RTL locales.
- Not prefixing the default locale:
hreflangtags work best when every locale has a separate URL, including the default. - Forgetting canonical URLs: Each language version should link to itself as canonical to avoid duplicate content issues.
Practice Questions
How do you configure default locale in Astro? Answer: Set
defaultLocalein thei18nsection ofastro.config.mjs.What is the purpose of
hreflangtags? Answer: They tell search engines which language versions of a page exist, preventing duplicate content penalties.How do you handle missing translations? Answer: Fall back to the default locale's translation. Configure
fallbackin the i18n config.Why prefix the default locale URL? Answer: It ensures every page version has a unique URL, which is required for proper
hreflangimplementation.
Challenge
Build a three-language site (English, Spanish, French) with a language switcher, fallback translations, and proper hreflang tags in the page head.
Mini Project
Create a multi-language documentation site with two locales. Each locale has its own content collection. Implement a language switcher that preserves the current page path when switching languages.
FAQ
What's Next
Learn about Astro Deployment for deploying your Astro site to production hosting platforms.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro