Overview
The internationalization system provides:- Four supported languages: French (fr), English (en), Arabic (ar), Spanish (es)
- URL-based routing: Language prefix in all URLs (
/fr/,/en/, etc.) - Default language: French (fr)
- Prefix all locales: Even the default locale uses a prefix
- Translation files: JSON-based translation system
- User preferences: Users can select their preferred language
Configuration
The i18n configuration is defined inastro.config.mjs.
Astro i18n Setup
Root Redirect
/) are automatically redirected to /fr/ (French homepage).
Supported Languages
- Français (fr)
- English (en)
- العربية (ar)
- Español (es)
French - Default language
- Primary language for the Annecy region
- Most complete translations
- Used as reference for other translations
- File:
src/i18n/fr.json
Translation Files
Translations are stored as JSON files insrc/i18n/:
Translation File Structure
Each translation file follows the same structure with nested objects:Translation Keys
Common translation namespaces:URL Structure
All routes include language prefixes:- Clear language indication in URL
- SEO-friendly (each language is a separate URL)
- Easy sharing of language-specific links
- No ambiguity about content language
User Language Preferences
Users can set their preferred language in their profile.Profile Language Setting
1
New user signs up
Default
preferred_language is set to "fr" (French)2
User updates profile
User can change language preference in account settings
3
System respects preference
Platform displays content in user’s preferred language when available
4
Fallback to default
If translation missing, falls back to French
Content Translation Strategy
UI Translations
Interface elements (buttons, labels, messages) are translated via JSON files:- Navigation menus:
nav.*keys - Form labels:
forms.*keys - Error messages:
errors.*keys - Validation messages:
validation.*keys
User-Generated Content
Concordia uses separate translation tables for user-generated content:Place Translations
- Each place can have translations in multiple languages
- Unique constraint ensures one translation per language
- Place owners can provide translations for their listings
Article Content (Future)
RTL (Right-to-Left) Support
Arabic requires special handling for right-to-left layout.CSS Direction
Logical Properties
Use CSS logical properties for better RTL support:- Automatically flips for RTL languages
- No need for duplicate RTL-specific styles
- Better maintainability
Language Detection
The system detects user language through:- URL path: Primary method (e.g.,
/fr/,/en/) - User profile: Logged-in users’
preferred_language - Browser headers:
Accept-Languageheader for first visit - Cookie: Remembers anonymous user’s language choice
Detection Priority
Email Translations
System emails are bilingual (French/English) in the same message:- Password reset (bilingual subject)
- Email verification (bilingual subject)
- Organization invitations (bilingual)
- Moderation notifications
Translation Best Practices
1
Keep keys consistent
Use the same key structure across all language files
2
Use nested objects
Group related translations (e.g.,
nav.home, nav.about)3
Avoid hardcoded text
Always use translation keys, never hardcode text in components
4
Provide context
Add comments in JSON files to explain context for translators
5
Test RTL layout
Always test UI in Arabic to ensure proper RTL rendering
6
Maintain parity
When adding new features, update all language files simultaneously
Adding a New Language
To add support for a new language:1
Update Astro config
Add language code to
locales array in astro.config.mjs2
Create translation file
Copy
src/i18n/fr.json to src/i18n/de.json3
Translate content
Translate all keys in the new file to the target language
4
Update database enum
Add language to profile schema if storing in database:
5
Add RTL support (if needed)
For RTL languages (Hebrew, Farsi, Urdu), add CSS direction rules
6
Test thoroughly
- Check all pages in new language
- Verify URL routing works
- Test language switcher
- Validate email templates
Translation File Example
Comparing French and English for the same content:- French (fr.json)
- English (en.json)