Skip to content

Adding Languages

Goal: Add Italian support in 4 steps (~15 minutes).

Language selector

  1. Update src/i18n/ui.ts

    Add the language to the languages object:

    src/i18n/ui.ts
    export const languages = {
    fr: { name: 'Français', flag: '🇫🇷' },
    de: { name: 'Deutsch', flag: '🇩🇪' },
    it: { name: 'Italiano', flag: '🇮🇹' },
    } as const;

    Add all translations to the ui object:

    src/i18n/ui.ts
    export const ui = {
    fr: { /* French translations */ },
    de: { /* German translations */ },
    it: {
    'nav.home': 'Home',
    'nav.work': 'I nostri lavori',
    'nav.about': 'Informazioni',
    'nav.contact': 'Contattaci',
    'business.name': 'La tua azienda',
    'business.tagline': 'Il tagline della tua azienda',
    'site.title': 'Titolo del tuo sito',
    'site.description': 'Descrizione del tuo sito per SEO',
    'author.name': 'Tu Numero',
    'author.email': 'tu@email.com',
    'theme.toggle': 'Cambia argomento',
    // ... copy all other keys from FR or DE
    },
    } as const;
  2. Update astro.config.mjs

    Add the locale to the Astro configuration:

    astro.config.mjs
    i18n: {
    defaultLocale: "fr",
    locales: ["fr", "de", "it"],
    routing: {
    prefixDefaultLocale: false,
    },
    },
  3. Create Page Folder

    Create src/pages/it/index.astro:

    src/pages/it/index.astro
    ---
    import BaseLayout from "../../layouts/BaseLayout.astro";
    import Header from "../../components/Header.astro";
    import Landing from "../../components/Landing.astro";
    ---
    <BaseLayout>
    <Header />
    <Landing />
    </BaseLayout>
  4. Test

    Start your dev server and visit:

    http://localhost:4321/it/

    Success indicators:

    • Italian appears in the language selector
    • Italian-speaking browsers auto-redirect to /it/
    • HTML has lang="it" attribute
    • All content displays in Italian

The BaseLayout.astro checks if the current locale exists in the languages object:

const lang: Language = (currentLocale && currentLocale in languages)
? currentLocale as Language
: defaultLang;

No hardcoded checks! If you add a language to ui.ts, it’s automatically supported.

The middleware.ts redirects based on the languages object:

if (preferredLang in languages && preferredLang !== defaultLang) {
return redirect(`/${preferredLang}/`);
}

Fully scalable - Any language you add will be auto-detected from the browser.

The LanguageSelector.astro imports from ui.ts:

import { languages } from "@/i18n/ui";

It automatically displays all available languages with their flags.


The easiest way is to:

  1. Copy the French or German section from ui.ts
  2. Paste it as your new language
  3. Translate each value

Make sure to include all these keys (copy from existing languages):

  • Navigation: nav.*
  • Business: business.*
  • Portfolio: portfolio.*
  • Owner: owner.*
  • Contact: contact.*
  • Site metadata: site.*
  • Author: author.*

Some values like author.email and author.phone should be the same across all languages (unless you have different contact info per region).


src/
├── i18n/
│ ├── ui.ts ← Add language here (Step 1)
│ └── utils.ts ← No changes needed (dynamic)
├── layouts/
│ └── BaseLayout.astro ← No changes needed (dynamic)
├── middleware.ts ← No changes needed (dynamic)
├── pages/
│ ├── index.astro ← French (default)
│ ├── de/
│ │ └── index.astro
│ └── it/ ← Create this (Step 3)
│ └── index.astro
└── astro.config.mjs ← Add locale (Step 2)

src/i18n/ui.ts
// 1. src/i18n/ui.ts
export const languages = {
fr: { name: 'Français', flag: '🇫🇷' },
de: { name: 'Deutsch', flag: '🇩🇪' },
es: { name: 'Español', flag: '🇪🇸' },
} as const;
export const ui = {
fr: {
// ... French translations
},
de: {
// ... German translations
},
es: {
'nav.home': 'Inicio',
'nav.work': 'Nuestros Trabajos',
'nav.about': 'Acerca de',
'nav.contact': 'Contacto',
// ... rest of translations
},
} as const;
astro.config.mjs
// 2. astro.config.mjs
locales: ["fr", "de", "es"],
3. Create: src/pages/es/index.astro
4. Test at: http://localhost:4321/es/

Check that it’s added to the languages object in ui.ts with the as const modifier.

Section titled “Dropdown shows but page doesn’t translate?”

Verify all translation keys exist in the ui object for that language.

Clear your browser cache or test in incognito. The middleware caches the accept-language header.

Make sure you have the as const on both the languages and ui objects in ui.ts.