ice/src/routes/i18n.ts
Claude Code 8b1787ec47 Add comprehensive internationalization (i18n) with Spanish language support
This major feature introduces complete internationalization architecture with Spanish (Mexico) as the first additional language:

## New Features:
- **I18n Architecture**: Complete client-side and server-side internationalization system
- **Spanish (Mexico) Support**: Full es-MX translations for all user-facing text
- **Language Selector**: Dynamic language switching UI component in header
- **API Endpoints**: RESTful endpoints for serving translations (/api/i18n)
- **Progressive Enhancement**: Language detection via Accept-Language header and cookies

## Technical Implementation:
- **Frontend**: Client-side i18n.js with automatic DOM translation and language selector
- **Backend**: Server-side i18n service with locale detection middleware
- **Build Process**: Automated copying of translation files to dist/ directory
- **Responsive Design**: Language selector integrated into header controls layout

## Files Added:
- public/i18n.js - Client-side internationalization library
- src/i18n/index.ts - Server-side i18n service
- src/i18n/locales/en.json - English translations
- src/i18n/locales/es-MX.json - Spanish (Mexico) translations
- src/routes/i18n.ts - API endpoints for translations

## Files Modified:
- package.json - Updated build process to include i18n files
- public/index.html - Added i18n attributes and language selector
- public/app.js - Integrated dynamic translation updates
- src/server.ts - Added locale detection middleware
- src/scss/pages/_index.scss - Language selector styling

This implementation supports easy addition of future languages and maintains backward compatibility while providing a seamless multilingual experience.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-07 12:25:44 -04:00

76 lines
No EOL
1.9 KiB
TypeScript

import { Router, Request, Response } from 'express';
import { i18nService } from '../i18n';
export function createI18nRoutes(): Router {
const router = Router();
/**
* Get translations for a specific locale
* GET /api/i18n/:locale
*/
router.get('/:locale', (req: Request, res: Response): void => {
const { locale } = req.params;
// Validate locale
if (!i18nService.isLocaleSupported(locale)) {
res.status(400).json({
error: 'Unsupported locale',
supportedLocales: i18nService.getAvailableLocales()
});
return;
}
// Get translations for the locale
const translations = i18nService.getTranslations(locale);
if (!translations) {
res.status(404).json({
error: 'Translations not found for locale',
locale
});
return;
}
// Set appropriate headers for caching
res.set({
'Cache-Control': 'public, max-age=3600', // Cache for 1 hour
'Content-Type': 'application/json'
});
res.json(translations);
});
/**
* Get available locales and their display names
* GET /api/i18n
*/
router.get('/', (req: Request, res: Response): void => {
const locales = i18nService.getAvailableLocales().map(locale => ({
code: locale,
name: i18nService.getLocaleDisplayName(locale)
}));
res.json({
default: i18nService.getDefaultLocale(),
available: locales
});
});
/**
* Detect user's preferred locale based on Accept-Language header
* GET /api/i18n/detect
*/
router.get('/detect', (req: Request, res: Response): void => {
const acceptLanguage = req.get('Accept-Language');
const detectedLocale = i18nService.detectLocale(acceptLanguage);
res.json({
detected: detectedLocale,
displayName: i18nService.getLocaleDisplayName(detectedLocale)
});
});
return router;
}
export default createI18nRoutes;