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 i18n block in the config, and URL helpers in astro: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: true puts 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) from astro: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 out as const and the Lang type. In the layout, leave out interface Props and type 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

ToolWhat it does
Astro.currentLocaleThe language of the current page, from its URL
Astro.preferredLocaleThe 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 hreflang links 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

MistakeCorrect idea
Hard-coded /about links on Tamil pagesUse getRelativeLocaleUrl("ta", "about")
<html lang="en"> on every pageSet lang from the page's locale
Text spread across many componentsKeep each language's words in one dictionary
No fallback for missing pagesAdd fallback: { ta: "en" } or translate every page