Fix: i18n Not Enabled in Astro

Error message:
i18n Not Enabled.
Internationalization 2025-01-25

What Causes This Error?

This error occurs when you try to use Astro’s i18n features (like astro:i18n imports or Astro.currentLocale) without enabling i18n in your configuration.

The Problem

---
// ❌ Using i18n without config
import { getRelativeLocaleUrl } from 'astro:i18n';

const url = getRelativeLocaleUrl('es', '/about');
---
// astro.config.mjs
export default defineConfig({
  // No i18n config!
});

The Fix

Add i18n Configuration

// astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'es', 'fr'],
  },
});

Common Scenarios

Basic i18n Setup

// astro.config.mjs
export default defineConfig({
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'es', 'fr', 'de'],
    routing: {
      prefixDefaultLocale: false,  // /about vs /es/about
    },
  },
});

Using i18n Features

---
// ✅ Now works after adding config
import {
  getRelativeLocaleUrl,
  getAbsoluteLocaleUrl,
} from 'astro:i18n';

// Build localized URLs
const aboutEs = getRelativeLocaleUrl('es', '/about');
const homeFr = getRelativeLocaleUrl('fr', '/');

// Access current locale
const currentLocale = Astro.currentLocale;
const preferredLocale = Astro.preferredLocale;
---

<p>Current locale: {currentLocale}</p>
<a href={aboutEs}>About (Spanish)</a>

With Fallbacks

export default defineConfig({
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'es', 'fr'],
    fallback: {
      es: 'en',  // Spanish falls back to English
      fr: 'en',  // French falls back to English
    },
  },
});

With Domains

export default defineConfig({
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'es'],
    domains: {
      es: 'https://es.example.com',
    },
  },
});

Minimal Configuration

// Minimum required config
export default defineConfig({
  i18n: {
    defaultLocale: 'en',
    locales: ['en'],  // At least one locale
  },
});

Locale-Specific Types

// After enabling i18n, these types are available
const locale: string = Astro.currentLocale;
const preferred: string | undefined = Astro.preferredLocale;
const preferredList: string[] = Astro.preferredLocaleList;

Creating Locale Routes

src/pages/
├── index.astro          # / (default locale)
├── about.astro          # /about
├── es/
│   ├── index.astro      # /es/
│   └── about.astro      # /es/about
└── fr/
    ├── index.astro      # /fr/
    └── about.astro      # /fr/about

Language Switcher Component

---
// src/components/LanguageSwitcher.astro
import { getRelativeLocaleUrl } from 'astro:i18n';

const locales = ['en', 'es', 'fr'];
const currentLocale = Astro.currentLocale || 'en';
const currentPath = Astro.url.pathname.replace(/^\/[a-z]{2}(?=\/|$)/, '') || '/';
---

<nav class="language-switcher">
  {locales.map((locale) => (
    <a
      href={getRelativeLocaleUrl(locale, currentPath)}
      class:list={[{ active: locale === currentLocale }]}
    >
      {locale.toUpperCase()}
    </a>
  ))}
</nav>

Without i18n (Manual Approach)

If you don’t want to use Astro’s i18n:

---
// Manual locale handling without i18n config
const locale = Astro.params.locale || 'en';
const validLocales = ['en', 'es', 'fr'];

if (!validLocales.includes(locale)) {
  return Astro.redirect('/404');
}
---

Quick Checklist

  • Add i18n object to astro.config.mjs
  • Set defaultLocale (required)
  • Set locales array (required)
  • Configure routing options as needed
  • Create locale-specific page folders