# Internationalization (i18n) Usage Guide This guide explains how to use the internationalization (i18n) features in your Ship Monitoring System built with Umi Max. ## πŸ“‹ Table of Contents 1. [Setup Overview](#setup-overview) 2. [File Structure](#file-structure) 3. [Basic Usage](#basic-usage) 4. [Advanced Usage](#advanced-usage) 5. [Custom Hook](#custom-hook) 6. [Language Switcher](#language-switcher) 7. [Best Practices](#best-practices) 8. [Troubleshooting](#troubleshooting) ## πŸš€ Setup Overview ### Configuration Files **`.umirc.ts`** - Main i18n configuration: ```typescript locale: { default: 'vi-VN', baseNavigator: false, antd: true, title: false, baseSeparator: '-', locales: [ ['vi-VN', 'TiαΊΏng Việt'], ['en-US', 'English'], ], }, ``` **`src/app.tsx`** - Runtime configuration: ```typescript // Enable locale in menu menu: { locale: true, }, // Add language switcher to header rightContentRender: () => [ , ], ``` ## πŸ“ File Structure ``` src/ β”œβ”€β”€ locales/ # Translation files β”‚ β”œβ”€β”€ vi-VN.ts # Vietnamese translations β”‚ └── en-US.ts # English translations β”œβ”€β”€ components/ β”‚ β”œβ”€β”€ LanguageSwitcher/ # Language switcher component β”‚ β”‚ └── index.tsx β”‚ └── I18nExamples/ # Example components β”‚ β”œβ”€β”€ index.tsx β”‚ β”œβ”€β”€ BasicUsage.tsx β”‚ β”œβ”€β”€ FormValidation.tsx β”‚ └── CustomHookExample.tsx β”œβ”€β”€ hooks/ β”‚ └── useTranslation.ts # Custom i18n hook └── app.tsx # Runtime configuration ``` ## πŸ”§ Basic Usage ### 1. Using `useIntl` Hook ```typescript import { useIntl } from '@umijs/max'; import React from 'react'; const MyComponent: React.FC = () => { const intl = useIntl(); return (
{/* Simple translation */}

{intl.formatMessage({ id: 'common.save' })}

{/* Translation with variables */}

{intl.formatMessage( { id: 'validation.minLength' }, { min: 6 } )}

); }; ``` ### 2. Using `FormattedMessage` Component ```typescript import { FormattedMessage } from '@umijs/max'; import React from 'react'; const MyComponent: React.FC = () => { return (
{/* Simple translation */} {/* Translation with variables */}
); }; ``` ## 🎯 Advanced Usage ### 1. Form Validation with i18n ```typescript import { Form, Input, Button } from 'antd'; import { useIntl } from '@umijs/max'; import React from 'react'; const MyForm: React.FC = () => { const intl = useIntl(); return (
); }; ``` ### 2. Conditional Rendering ```typescript import { useIntl } from '@umijs/max'; import React from 'react'; const LocalizedContent: React.FC = () => { const intl = useIntl(); return (
{intl.locale === 'vi-VN' ? (

ChΓ o mα»«ng Δ‘αΊΏn vα»›i hệ thα»‘ng!

) : (

Welcome to the system!

)}
); }; ``` ## πŸͺ Custom Hook Usage For more convenient usage, use the custom `useTranslation` hook: ```typescript import { useTranslation } from '@/hooks/useTranslation'; import React from 'react'; const MyComponent: React.FC = () => { const { t, isLocale, formatDate, formatNumber } = useTranslation(); return (
{/* Simple translation */}

{t('common.save')}

{/* Translation with variables */}

{t('validation.minLength', { min: 6 })}

{/* Locale detection */} {isLocale('vi-VN') &&

Xin chΓ o!

} {/* Date formatting */}

{formatDate(new Date(), { year: 'numeric', month: 'long', day: 'numeric' })}

{/* Number formatting */}

{formatNumber(1234.56, { style: 'currency', currency: 'VND' })}

); }; ``` ## 🌐 Language Switcher The language switcher component is automatically included in the header. You can also use it manually: ```typescript import LanguageSwitcher from '@/components/LanguageSwitcher'; import React from 'react'; const Header: React.FC = () => { return (
{/* or */}
); }; ``` ### Language Switcher Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `className` | `string` | - | Additional CSS classes | | `type` | `'dropdown' \| 'button'` | `'dropdown'` | Display type | | `size` | `'small' \| 'middle' \| 'large'` | `'middle'` | Component size | ## πŸ“ Translation Keys Translation keys follow a hierarchical structure using dot notation: ``` common.save // Save button text auth.login.title // Login page title map.ship.status.online // Ship online status validation.required // Validation message ``` ### Adding New Translations 1. **Vietnamese** (`src/locales/vi-VN.ts`): ```typescript export default { // Add new key 'my.new.key': 'Nα»™i dung mα»›i', }; ``` 2. **English** (`src/locales/en-US.ts`): ```typescript export default { // Add corresponding English translation 'my.new.key': 'New content', }; ``` ## βœ… Best Practices ### 1. **Consistent Key Naming** - Use dot notation for hierarchical structure - Group related translations together - Use descriptive, meaningful names - Example: `'map.ship.status.online'` instead of `'online'` ### 2. **Variable Interpolation** - Use descriptive variable names - Provide context for variables - Example: `'validation.minLength': 'Minimum {min} characters required'` ### 3. **Component Organization** - Group translations by feature/module - Keep related keys together - Use consistent prefixes for modules ### 4. **Performance Considerations** - Use the `useTranslation` hook for better performance - Avoid inline `formatMessage` calls in render loops - Cache translated strings when used frequently ### 5. **Translation Maintenance** - Keep all translations in sync - Add new keys to both language files - Review translations regularly for consistency ## πŸ›  Troubleshooting ### Common Issues #### 1. **Translation not appearing** ```typescript // ❌ Wrong // βœ… Correct - check if key exists in locale files ``` #### 2. **Locale not changing** - Ensure `localStorage.setItem('umi_locale', locale)` is called - Check that locale is properly configured in `.umirc.ts` - Verify that translation files exist for the target locale #### 3. **Missing Ant Design translations** ```typescript // In .umirc.ts locale: { antd: true, // Ensure this is enabled } ``` #### 4. **TypeScript errors** ```typescript // Ensure proper import import { useIntl } from '@umijs/max'; // Check if translation key exists in locale files const intl = useIntl(); const text = intl.formatMessage({ id: 'existing.key' }); ``` ### Debug Mode To debug translation issues, add logging to your component: ```typescript import { useIntl } from '@umijs/max'; import React from 'react'; const DebugComponent: React.FC = () => { const intl = useIntl(); console.log('Current locale:', intl.locale); console.log('Available messages:', intl.messages); return
Check console for debug info
; }; ``` ## πŸ”„ Testing Translations To test your i18n implementation: 1. **Manual Testing**: - Switch languages using the language switcher - Verify all text updates correctly - Check forms with validation messages 2. **Component Testing**: ```typescript import { render } from '@testing-library/react'; import { I18nProvider } from '@umijs/max'; import MyComponent from './MyComponent'; // Test with different locales render( ); ``` 3. **Translation Coverage**: - Ensure all UI text is translatable - Check that no hardcoded strings remain - Verify all keys exist in both language files ## πŸ“š Additional Resources - [Umi Max i18n Documentation](https://umijs.org/docs/max/i18n) - [React Intl Documentation](https://formatjs.io/docs/react-intl/) - [Ant Design i18n Guide](https://ant.design/docs/react/internationalization) ## πŸŽ‰ Summary Your i18n setup is now complete! You have: βœ… **Configuration**: Umi Max i18n properly configured βœ… **Translations**: Vietnamese and English translation files βœ… **Components**: Language switcher and example components βœ… **Custom Hook**: Simplified i18n API βœ… **Best Practices**: Guidelines for maintainable translations The system is ready for multi-language support and can be easily extended with additional languages or translations as needed. --- **Last Updated**: 2025-01-20 **Version**: 1.0.0