What Causes This Error?
This error occurs when you use a locale that isn’t defined in your i18n.locales configuration. All locales used in your site must be declared in the Astro config.
The Problem
// astro.config.mjs
export default defineConfig({
i18n: {
defaultLocale: 'en',
locales: ['en', 'es'], // Only en and es configured
},
});
---
// ❌ Using 'fr' which isn't in locales
import { getRelativeLocaleUrl } from 'astro:i18n';
const url = getRelativeLocaleUrl('fr', '/about');
---
The Fix
Add Locale to Config
// astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
i18n: {
defaultLocale: 'en',
locales: ['en', 'es', 'fr'], // ✅ Add 'fr'
},
});
Or Use Configured Locale
---
import { getRelativeLocaleUrl } from 'astro:i18n';
// ✅ Use a configured locale
const url = getRelativeLocaleUrl('es', '/about');
---
Common Scenarios
Basic i18n Setup
// astro.config.mjs
export default defineConfig({
i18n: {
defaultLocale: 'en',
locales: ['en', 'es', 'fr', 'de'],
routing: {
prefixDefaultLocale: false,
},
},
});
Using Locale Codes
// With region codes
export default defineConfig({
i18n: {
defaultLocale: 'en',
locales: ['en', 'en-US', 'en-GB', 'es', 'es-MX'],
},
});
---
// ✅ Must match exactly
getRelativeLocaleUrl('en-US', '/about'); // OK
getRelativeLocaleUrl('en-us', '/about'); // ❌ Case matters!
---
Custom Locale Paths
export default defineConfig({
i18n: {
defaultLocale: 'en',
locales: [
'en',
{
path: 'spanish', // URL will use /spanish/
codes: ['es', 'es-ES'],
},
],
},
});
Dynamic Locale Detection
---
import { getRelativeLocaleUrl } from 'astro:i18n';
// ✅ Validate locale before using
const validLocales = ['en', 'es', 'fr'];
const requestedLocale = Astro.params.locale;
const locale = validLocales.includes(requestedLocale)
? requestedLocale
: 'en';
const url = getRelativeLocaleUrl(locale, '/about');
---
Locale in Routes
src/pages/
├── index.astro # Default locale (en)
├── es/
│ └── index.astro # Spanish
└── fr/
└── index.astro # French - must be in config!
Get Available Locales
---
// Access configured locales
const locales = Astro.currentLocale;
const preferredLocale = Astro.preferredLocale;
const preferredLocaleList = Astro.preferredLocaleList;
---
Translation Helpers
---
import { getRelativeLocaleUrl, getAbsoluteLocaleUrl } from 'astro:i18n';
// ✅ Build locale-aware URLs
const currentLocale = Astro.currentLocale || 'en';
const aboutUrl = getRelativeLocaleUrl(currentLocale, '/about');
---
<a href={aboutUrl}>About</a>
Fallback Locale
// astro.config.mjs
export default defineConfig({
i18n: {
defaultLocale: 'en',
locales: ['en', 'es', 'fr'],
fallback: {
fr: 'en', // Fall back to English for French
},
},
});
TypeScript Safety
// src/i18n.ts
export const locales = ['en', 'es', 'fr'] as const;
export type Locale = typeof locales[number];
export function isValidLocale(locale: string): locale is Locale {
return locales.includes(locale as Locale);
}
---
import { isValidLocale } from '../i18n';
const locale = Astro.params.locale;
if (!isValidLocale(locale)) {
return Astro.redirect('/404');
}
---
Quick Checklist
- All locales must be in
i18n.localesarray - Locale codes are case-sensitive
- Match exact format (en vs en-US)
- Validate dynamic locales before use
- Create page folders for each locale