Appendix A: Internationalization Guide
By Syncfusion®, Inc. · Last updated
Build an Astro site in more than one language: locale folders, the i18n config, translation dictionaries, getRelativeLocaleUrl(), hreflang and fallbacks.
Appendix A: Internationalization (i18n) Guide
- Internationalization (often written i18n: "i", 18 letters, "n") means making a site work in more than one language.
- Asha wants her journal in English and Tamil.
- Astro gives you three things: a folder per language, an
i18nblock in the config, and URL helpers inastro:i18n.
Simple lesson: one folder per language, an i18n config block, and helpers to build the right links.
Step 1: A Folder per Language
src/pages/
├── index.astro → / (English, the default)
├── about.astro → /about
└── ta/
├── index.astro → /ta/ (Tamil)
└── about.astro → /ta/about
- The default language can live at the root (
/about) or in its own folder (/en/about). - Each other language gets a folder named with its language code:
ta,hi,fr.
Step 2: The i18n Config
// astro.config.mjs
import { defineConfig } from "astro/config";
export default defineConfig({
i18n: {
locales: ["en", "ta"],
defaultLocale: "en",
routing: {
prefixDefaultLocale: false, // English at /about, Tamil at /ta/about
},
},
});
locales: every language the site has.defaultLocale: the main language.prefixDefaultLocale: trueputs English under/en/too.- Optional
fallback: { ta: "en" }shows the English page when a Tamil page is missing.
Step 3: Translations and Links
- Keep the words for each language in one dictionary file.
- Build links with
getRelativeLocaleUrl(locale, path)fromastro:i18n. It adds the language folder only when needed. - Set
<html lang={locale}>on every page, so screen readers and search engines know the language.
Press ▶ Run. Switch between English and தமிழ். The menu text and links change with the language.
- [JS] In
ui.js, leave outas constand theLangtype. In the layout, leave outinterface Propsandtype Lang.
Content collections work well for translated posts: put them in src/content/posts/en/ and src/content/posts/ta/, and filter with getCollection("posts", (p) => p.id.startsWith("ta/")).
More i18n Tools
| Tool | What it does |
|---|---|
Astro.currentLocale | The language of the current page, from its URL |
Astro.preferredLocale | The visitor's browser language, if the site has it (on-demand pages) |
getAbsoluteLocaleUrl(locale, path) | A full URL with site, for canonical and hreflang links |
getRelativeLocaleUrlList(path) | The same page in every language, for a language switcher |
routing: "manual" | Turn off automatic routing and write your own middleware |
- Add
hreflanglinks in the<head>, so search engines show the right language:<link rel="alternate" hreflang="ta" href="https://asha.dev/ta/about" />.
Do not translate with automatic tools alone. Ask a native speaker to check, especially buttons and error messages.
i18n is about more than words: dates, numbers and money also change. Use Intl.DateTimeFormat("ta-IN") and toLocaleString("ta-IN").
Common mistakes
| Mistake | Correct idea |
|---|---|
Hard-coded /about links on Tamil pages | Use getRelativeLocaleUrl("ta", "about") |
<html lang="en"> on every page | Set lang from the page's locale |
| Text spread across many components | Keep each language's words in one dictionary |
| No fallback for missing pages | Add fallback: { ta: "en" } or translate every page |