# Internationalization (i18n) Setup This project includes a comprehensive internationalization system built with Astro 5.x. The system supports multiple languages with URL-based routing and automatic language detection. ## Features - ✅ URL-based language routing (Spanish: `/`, English: `/en/`) - ✅ Spanish as default language (no URL prefix) - ✅ Automatic language detection from URL - ✅ Language switcher component - ✅ Type-safe translation keys - ✅ Fallback to default language - ✅ Middleware for automatic redirects - ✅ SEO-friendly URLs ## Supported Languages Currently supported languages: - **Spanish (es)** - Default language (no URL prefix) - **English (en)** - Secondary language (with `/en/` prefix) ## URL Structure - **Spanish (default)**: `/`, `/elements`, `/about` - **English**: `/en/`, `/en/elements`, `/en/about` ## How to Use ### 1. Adding New Translations Edit the translation dictionaries in `src/lib/i18n.ts`: ```typescript const translations = { es: { 'your.new.key': 'Texto en español', // ... more translations }, en: { 'your.new.key': 'English text', // ... more translations } } ``` ### 2. Using Translations in Components ```astro --- import { t, getLanguageFromPath } from '../lib/i18n'; const currentLang = getLanguageFromPath(Astro.url.pathname); ---

{t('your.new.key', currentLang)}

``` ### 3. Creating Language-Specific Pages For English pages, create them in the `src/pages/[lang]/` directory: ```astro --- // src/pages/[lang]/about.astro (English only) import { t, isSupportedLanguage, type SupportedLanguage, DEFAULT_LANGUAGE } from '../../lib/i18n'; const { lang } = Astro.params; if (!lang || !isSupportedLanguage(lang)) { return Astro.redirect('/about'); } const currentLang = lang as SupportedLanguage; // Redirect Spanish to root if (currentLang === DEFAULT_LANGUAGE) { return Astro.redirect('/about'); } ---

{t('about.title', currentLang)}

``` For Spanish pages (default), create them directly in `src/pages/`: ```astro --- // src/pages/about.astro (Spanish default) import { t, DEFAULT_LANGUAGE } from '../lib/i18n'; const currentLang = DEFAULT_LANGUAGE; ---

{t('about.title', currentLang)}

``` ### 4. Adding the Language Switcher The language switcher is automatically included in the main layout. To add it to other components: ```astro --- import LanguageSwitcher from '../components/LanguageSwitcher.astro'; --- ``` ### 5. Creating Localized Links Use the `getLocalizedPath` function for navigation: ```astro --- import { getLocalizedPath, getLanguageFromPath } from '../lib/i18n'; const currentLang = getLanguageFromPath(Astro.url.pathname); --- About ``` ## File Structure ``` src/ ├── lib/ │ └── i18n.ts # Main i18n utilities and translations ├── components/ │ ├── LanguageSwitcher.astro # Language selection component │ └── ... # Other components ├── pages/ │ ├── [lang]/ # English-specific pages │ │ ├── index.astro # Redirects Spanish to root │ │ ├── elements.astro # Redirects Spanish to root │ │ └── ... │ ├── index.astro # Spanish default homepage │ ├── elements.astro # Spanish default elements page │ └── ... # Other Spanish default pages └── middleware.ts # Language routing middleware ``` ## API Reference ### Translation Functions #### `t(key, lang?)` Get a translation for a given key and language. ```typescript t('nav.home', 'es') // Returns: "Inicio" t('nav.home', 'en') // Returns: "Home" ``` #### `getLanguageFromPath(pathname)` Extract language from URL path. ```typescript getLanguageFromPath('/en/elements') // Returns: "en" getLanguageFromPath('/elements') // Returns: "es" (default) getLanguageFromPath('/') // Returns: "es" (default) ``` #### `getLocalizedPath(path, lang)` Generate a localized URL path. ```typescript getLocalizedPath('/elements', 'es') // Returns: "/elements" getLocalizedPath('/elements', 'en') // Returns: "/en/elements" ``` #### `isSupportedLanguage(lang)` Check if a language is supported. ```typescript isSupportedLanguage('es') // Returns: true isSupportedLanguage('fr') // Returns: false ``` ### Constants - `SUPPORTED_LANGUAGES` - Array of supported language codes (['es', 'en']) - `DEFAULT_LANGUAGE` - Default language code ('es') - `TranslationKey` - TypeScript type for translation keys ## Adding New Languages 1. Add the language code to `SUPPORTED_LANGUAGES` in `src/lib/i18n.ts` 2. Add translations for the new language in the `translations` object 3. Update the language switcher component if needed 4. Create language-specific pages in `src/pages/[lang]/` Example for French: ```typescript export const SUPPORTED_LANGUAGES = ['es', 'en', 'fr'] as const; const translations = { es: { /* Spanish translations */ }, en: { /* English translations */ }, fr: { /* French translations */ } } ``` ## Best Practices 1. **Use descriptive keys**: Use namespaced keys like `nav.home`, `elements.title` 2. **Keep translations organized**: Group related translations together 3. **Test all languages**: Ensure all translations are complete 4. **Use TypeScript**: Leverage the `TranslationKey` type for type safety 5. **Handle missing translations**: The system falls back to the default language 6. **Spanish first**: Always put Spanish translations first in the dictionary ## SEO Considerations - Spanish content is served at root URLs (better for SEO) - English content has `/en/` prefix - Language is properly set in the HTML `lang` attribute - Search engines can index content in multiple languages - Use proper hreflang tags if needed for advanced SEO ## Troubleshooting ### Common Issues 1. **Translation not found**: Check if the key exists in all language dictionaries 2. **Language not detected**: Ensure the URL follows the correct pattern 3. **Redirect loops**: Check middleware configuration 4. **Type errors**: Use the `TranslationKey` type for translation keys ### Debug Mode Enable debug logging by adding console logs in the i18n functions: ```typescript export function t(key: TranslationKey, lang: SupportedLanguage = DEFAULT_LANGUAGE): string { console.log(`Translating: ${key} for language: ${lang}`); // ... rest of function } ```