Files
FE-DEVICE-SGW/I18N_USAGE_GUIDE.md
2025-11-20 16:21:17 +07:00

9.3 KiB

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
  2. File Structure
  3. Basic Usage
  4. Advanced Usage
  5. Custom Hook
  6. Language Switcher
  7. Best Practices
  8. Troubleshooting

🚀 Setup Overview

Configuration Files

.umirc.ts - Main i18n configuration:

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:

// Enable locale in menu
menu: {
  locale: true,
},

// Add language switcher to header
rightContentRender: () => [
  <LanguageSwitcher key="language-switcher" />,
],

📁 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

import { useIntl } from '@umijs/max';
import React from 'react';

const MyComponent: React.FC = () => {
  const intl = useIntl();

  return (
    <div>
      {/* Simple translation */}
      <h1>{intl.formatMessage({ id: 'common.save' })}</h1>

      {/* Translation with variables */}
      <p>{intl.formatMessage(
        { id: 'validation.minLength' },
        { min: 6 }
      )}</p>
    </div>
  );
};

2. Using FormattedMessage Component

import { FormattedMessage } from '@umijs/max';
import React from 'react';

const MyComponent: React.FC = () => {
  return (
    <div>
      {/* Simple translation */}
      <FormattedMessage id="common.save" />

      {/* Translation with variables */}
      <FormattedMessage
        id="validation.minLength"
        values={{ min: 6 }}
      />
    </div>
  );
};

🎯 Advanced Usage

1. Form Validation with i18n

import { Form, Input, Button } from 'antd';
import { useIntl } from '@umijs/max';
import React from 'react';

const MyForm: React.FC = () => {
  const intl = useIntl();

  return (
    <Form>
      <Form.Item
        label={intl.formatMessage({ id: 'common.username' })}
        name="username"
        rules={[
          {
            required: true,
            message: intl.formatMessage({ id: 'validation.required' }),
          },
          {
            type: 'email',
            message: intl.formatMessage({ id: 'validation.email' }),
          },
        ]}
      >
        <Input
          placeholder={intl.formatMessage({ id: 'common.username' })}
        />
      </Form.Item>
    </Form>
  );
};

2. Conditional Rendering

import { useIntl } from '@umijs/max';
import React from 'react';

const LocalizedContent: React.FC = () => {
  const intl = useIntl();

  return (
    <div>
      {intl.locale === 'vi-VN' ? (
        <p>Chào mừng đến với hệ thống!</p>
      ) : (
        <p>Welcome to the system!</p>
      )}
    </div>
  );
};

🪝 Custom Hook Usage

For more convenient usage, use the custom useTranslation hook:

import { useTranslation } from '@/hooks/useTranslation';
import React from 'react';

const MyComponent: React.FC = () => {
  const { t, isLocale, formatDate, formatNumber } = useTranslation();

  return (
    <div>
      {/* Simple translation */}
      <h1>{t('common.save')}</h1>

      {/* Translation with variables */}
      <p>{t('validation.minLength', { min: 6 })}</p>

      {/* Locale detection */}
      {isLocale('vi-VN') && <p>Xin chào!</p>}

      {/* Date formatting */}
      <p>{formatDate(new Date(), {
        year: 'numeric',
        month: 'long',
        day: 'numeric'
      })}</p>

      {/* Number formatting */}
      <p>{formatNumber(1234.56, {
        style: 'currency',
        currency: 'VND'
      })}</p>
    </div>
  );
};

🌐 Language Switcher

The language switcher component is automatically included in the header. You can also use it manually:

import LanguageSwitcher from '@/components/LanguageSwitcher';
import React from 'react';

const Header: React.FC = () => {
  return (
    <div>
      <LanguageSwitcher type="dropdown" />
      {/* or */}
      <LanguageSwitcher type="button" size="small" />
    </div>
  );
};

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):
export default {
  // Add new key
  'my.new.key': 'Nội dung mới',
};
  1. English (src/locales/en-US.ts):
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

// ❌ Wrong
<FormattedMessage id="wrong.key" />

// ✅ Correct - check if key exists in locale files
<FormattedMessage id="common.save" />

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

// In .umirc.ts
locale: {
  antd: true, // Ensure this is enabled
}

4. TypeScript errors

// 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:

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 <div>Check console for debug info</div>;
};

🔄 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:

    import { render } from '@testing-library/react';
    import { I18nProvider } from '@umijs/max';
    import MyComponent from './MyComponent';
    
    // Test with different locales
    render(
      <I18nProvider locale="en-US">
        <MyComponent />
      </I18nProvider>
    );
    
  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

🎉 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