Best Practices

Resource File Organization

It's recommended to organize resource files as follows:

locales/
├── en/
│   ├── translation.json    # Default namespace
│   ├── common.json         # Common translations
│   └── errors.json         # Error messages
└── zh/
    ├── translation.json
    ├── common.json
    └── errors.json

Configure Multiple Namespaces:

export default defineRuntimeConfig({
  i18n: {
    initOptions: {
      ns: ['translation', 'common', 'errors'],
      defaultNS: 'translation',
    },
  },
});

Using Namespaces:

import { useTranslation } from 'react-i18next';

function MyComponent() {
  const { t } = useTranslation('common');

  return <div>{t('welcome')}</div>;
}

Error Handling

It's recommended to provide fallback options when resource loading fails:

Check Resource Loading State

When using SDK backend or need to ensure resources are loaded, use isResourcesReady from useModernI18n:

import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
import { useTranslation } from 'react-i18next';

function MyComponent() {
  const { isResourcesReady } = useModernI18n();
  const { t } = useTranslation();

  // Check if resources are loaded and ready
  if (!isResourcesReady) {
    return <div>Loading translation resources...</div>;
  }

  return <div>{t('content', { defaultValue: 'Default content' })}</div>;
}

Alternative: Check i18next Initialization

For simpler cases, you can also check i18next initialization status:

import { useTranslation } from 'react-i18next';

function MyComponent() {
  const { t, i18n } = useTranslation();

  // Check if i18n is initialized
  if (!i18n.isInitialized) {
    return <div>Loading...</div>;
  }

  return <div>{t('content', { defaultValue: 'Default content' })}</div>;
}
Tip

isResourcesReady is more accurate for SDK backend scenarios as it checks if all required resources are actually loaded, not just if the instance is initialized.

Type Safety

Add type definitions for translation keys to improve development experience:

// types/i18n.d.ts
import 'react-i18next';

declare module 'react-i18next' {
  interface CustomTypeOptions {
    defaultNS: 'translation';
    resources: {
      translation: {
        hello: string;
        world: string;
        welcome: string;
      };
      common: {
        submit: string;
        cancel: string;
      };
    };
  }
}

Using type-safe translations:

import { useTranslation } from 'react-i18next';

function MyComponent() {
  const { t } = useTranslation();

  // TypeScript will check if the key exists
  return <div>{t('hello')}</div>; // ✅ Type safe
  // return <div>{t('invalid')}</div>; // ❌ TypeScript error
}