logo
  • Guide
  • Config
  • Plugin
  • API
  • Examples
  • Community
  • Modern.js 2.x Docs
  • English
    • 简体中文
    • English
    • Start
      Introduction
      Quick Start
      Upgrading
      Glossary
      Tech Stack
      Core Concept
      Page Entry
      Build Engine
      Web Server
      Basic Features
      Routes
      Routing
      Config Routes
      Data Solution
      Data Fetching
      Data Writing
      Data Caching
      Rendering
      Server-Side Rendering
      Streaming SSR
      Rendering Cache
      Static Site Generation
      Render Preprocessing
      Styling
      Styling
      Use CSS Modules
      Using CSS-in-JS
      Using Tailwind CSS
      HTML Template
      Import Static Assets
      Import JSON Files
      Import SVG Assets
      Import Wasm Assets
      Debug
      Data Mocking
      Network Proxy
      Using Rsdoctor
      Using Storybook
      Testing
      Playwright
      Vitest
      Jest
      Cypress
      Path Alias
      Environment Variables
      Output Files
      Deploy Application
      Advanced Features
      Using Rspack
      Using BFF
      Basic Usage
      Runtime Framework
      Extend BFF Server
      Extend Request SDK
      File Upload
      Cross-Project Invocation
      Optimize Page Performance
      Code Splitting
      Inline Static Assets
      Bundle Size Optimization
      React Compiler
      Improve Build Performance
      Browser Compatibility
      Low-Level Tools
      Source Code Build Mode
      Server Monitor
      Monitors
      Logs Events
      Metrics Events
      Internationalization
      Basic Concepts
      Quick Start
      Configuration
      Locale Detection
      Resource Loading
      Routing Integration
      API Reference
      Advanced Usage
      Best Practices
      Custom Web Server
      Topic Detail
      Module Federation
      Introduction
      Getting Started
      Application-Level Modules
      Server-Side Rendering
      Deployment
      Integrating Internationalization
      FAQ
      Dependencies FAQ
      CLI FAQ
      Build FAQ
      HMR FAQ
      Deprecated
      📝 Edit this page
      Previous pageRouting IntegrationNext pageAdvanced Usage

      #API Reference

      #useModernI18n Hook

      useModernI18n is a React Hook provided by the plugin for accessing internationalization functionality in components.

      #Return Value

      interface UseModernI18nReturn {
        /** Current language code */
        language: string;
      
        /** Function to change language */
        changeLanguage: (newLang: string) => Promise<void>;
      
        /** i18next instance (for advanced usage) */
        i18nInstance: I18nInstance;
      
        /** Supported language list */
        supportedLanguages: string[];
      
        /** Check if language is supported */
        isLanguageSupported: (lang: string) => boolean;
      
        /** Indicates if translation resources for current language are ready to use */
        isResourcesReady: boolean;
      }

      #Usage Example

      import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
      
      function LanguageSwitcher() {
        const { language, changeLanguage, supportedLanguages, isLanguageSupported } =
          useModernI18n();
      
        return (
          <div>
            <p>Current language: {language}</p>
            <div>
              {supportedLanguages.map(lang => (
                <button
                  key={lang}
                  onClick={() => changeLanguage(lang)}
                  disabled={lang === language}
                >
                  {lang}
                </button>
              ))}
            </div>
            <button
              onClick={() => {
                if (isLanguageSupported('ja')) {
                  changeLanguage('ja');
                }
              }}
            >
              Switch to Japanese
            </button>
          </div>
        );
      }

      #changeLanguage Method

      The changeLanguage method is used to switch languages. It will:

      1. Update the language of the i18next instance
      2. Update browser cache (Cookie/LocalStorage)
      3. Update URL path (if localePathRedirect is enabled)
      const { changeLanguage } = useModernI18n();
      
      // Switch language
      await changeLanguage('zh');
      Info

      changeLanguage is an async function that returns a Promise.

      #Language Support Check

      isLanguageSupported is used to check if a language is in the supported language list:

      const { isLanguageSupported, changeLanguage } = useModernI18n();
      
      function handleLanguageChange(lang: string) {
        if (isLanguageSupported(lang)) {
          changeLanguage(lang);
        } else {
          console.warn(`Language ${lang} is not supported`);
        }
      }

      #Resource Loading State

      isResourcesReady indicates whether the translation resources for the current language are loaded and ready to use. This is particularly useful when using SDK backend to load resources dynamically.

      import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
      
      function MyComponent() {
        const { isResourcesReady } = useModernI18n();
      
        if (!isResourcesReady) {
          return <div>Loading translation resources...</div>;
        }
      
        return <div>Translation resources are ready</div>;
      }

      When to use:

      • Display a loading state while resources are being loaded
      • Prevent rendering content that depends on translations before resources are ready
      • Handle resource loading errors gracefully
      Info

      isResourcesReady automatically checks:

      • If i18n instance is initialized
      • If any resources for the current language are currently loading (SDK backend only)
      • If all required namespaces for the current language are loaded in the store

      #I18nLink Component

      The I18nLink component is used to create links with language prefixes.

      #Props

      interface I18nLinkProps {
        /** Target path (no need to include language prefix) */
        to: string;
        /** Child elements */
        children: React.ReactNode;
        /** Other Link component props (such as replace, state, etc.) */
        [key: string]: any;
      }

      #Usage Example

      import { I18nLink } from '@modern-js/plugin-i18n/runtime';
      
      function Navigation() {
        return (
          <nav>
            <I18nLink to="/">Home</I18nLink>
            <I18nLink to="/about">About</I18nLink>
            <I18nLink to="/contact" replace>
              Contact
            </I18nLink>
          </nav>
        );
      }

      #Runtime Plugin API

      In the onBeforeRender hook of Runtime plugins, you can modify the language using the context.changeLanguage method. This is useful for scenarios where you need to dynamically set the language based on request information (such as user preferences, geographic location, etc.).

      #context.changeLanguage

      In the onBeforeRender hook, the i18n plugin adds a changeLanguage method to the context for use by other Runtime plugins.

      Type Definition:

      interface TInternalRuntimeContext {
        i18nInstance?: I18nInstance;
        changeLanguage?: (lang: string) => Promise<void>;
      }

      #Usage Example

      import type { RuntimePlugin } from '@modern-js/runtime';
      
      const myRuntimePlugin = (): RuntimePlugin => ({
        name: 'my-runtime-plugin',
        setup: api => {
          api.onBeforeRender(async context => {
            // Check if changeLanguage method exists (ensure i18n plugin is loaded)
            if (context.changeLanguage) {
              // Determine language based on some condition
              const userLang = getUserLanguageFromRequest(context);
      
              // Change language
              await context.changeLanguage(userLang);
            }
          });
        },
      });
      
      function getUserLanguageFromRequest(context: any): string {
        // Get user language from request headers, cookies, or other sources
        const acceptLanguage = context.ssrContext?.req?.headers['accept-language'];
        // Parse and return appropriate language code
        return parseAcceptLanguage(acceptLanguage) || 'zh';
      }
      
      export default myRuntimePlugin;

      #Notes

      1. Execution Order: Ensure the i18n plugin is registered before other plugins that use changeLanguage, so that context.changeLanguage is available.

      2. Async Operation: changeLanguage is an async method and requires using await to wait for completion.

      3. Error Handling: If an invalid language code is passed, an error will be thrown. It's recommended to add error handling:

      api.onBeforeRender(async context => {
        if (context.changeLanguage) {
          try {
            await context.changeLanguage('zh');
          } catch (error) {
            console.error('Failed to change language:', error);
          }
        }
      });
      1. Language Validation: It's recommended to verify that the language is in the supported language list before calling changeLanguage:
      api.onBeforeRender(async context => {
        if (context.changeLanguage && context.i18nInstance) {
          const supportedLngs = context.i18nInstance.options?.supportedLngs || [];
          const targetLang = 'zh';
      
          if (supportedLngs.includes(targetLang)) {
            await context.changeLanguage(targetLang);
          }
        }
      });
      Info

      The changeLanguage method will:

      • Update the language of the i18n instance
      • Cache the language selection in the browser environment (Cookie/LocalStorage)
      • Trigger callbacks related to language switching

      However, it will not automatically update the URL path. If you need to update the URL, you need to coordinate with the routing plugin or handle it manually.

      #Integration with react-i18next

      The plugin is fully compatible with react-i18next and can use the useTranslation Hook and other react-i18next features.

      #useTranslation Hook

      import { useTranslation } from 'react-i18next';
      
      function MyComponent() {
        const { t, i18n } = useTranslation();
      
        return (
          <div>
            <h1>{t('welcome')}</h1>
            <p>{t('description', { name: 'Modern.js' })}</p>
          </div>
        );
      }

      #Accessing i18next Instance

      You can get the i18next instance through useModernI18n:

      import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
      import { useTranslation } from 'react-i18next';
      
      function MyComponent() {
        const { i18nInstance } = useModernI18n();
        const { t } = useTranslation();
      
        // Directly access i18next instance
        console.log(i18nInstance.language);
        console.log(i18nInstance.options);
      
        return <div>{t('hello')}</div>;
      }

      #Type Definitions

      #I18nInstance Interface

      interface I18nInstance {
        language: string;
        isInitialized: boolean;
        init: (options?: I18nInitOptions) => void | Promise<void>;
        changeLanguage: (lang: string) => void | Promise<void>;
        use: (plugin: any) => void;
        createInstance: (options?: I18nInitOptions) => I18nInstance;
        cloneInstance?: () => I18nInstance;
        services?: {
          languageDetector?: {
            detect: (request?: any, options?: any) => string | string[] | undefined;
            [key: string]: any;
          };
          [key: string]: any;
        };
        options?: {
          backend?: BackendOptions;
          [key: string]: any;
        };
      }

      #I18nInitOptions Interface

      interface I18nInitOptions {
        lng?: string;
        fallbackLng?: string;
        supportedLngs?: string[];
        initImmediate?: boolean;
        detection?: LanguageDetectorOptions;
        backend?: BackendOptions;
        resources?: Resources;
        ns?: string | string[];
        defaultNS?: string | string[];
        react?: {
          useSuspense?: boolean;
          [key: string]: any;
        };
        [key: string]: any;
      }

      #LanguageDetectorOptions Interface

      interface LanguageDetectorOptions {
        /** Detection order */
        order?: string[];
        /** Query parameter key name, default 'lng' */
        lookupQuerystring?: string;
        /** Cookie key name, default 'i18next' */
        lookupCookie?: string;
        /** LocalStorage key name, default 'i18nextLng' (browser only) */
        lookupLocalStorage?: string;
        /** SessionStorage key name (browser only) */
        lookupSession?: string;
        /** Starting index in path for language detection, default 0 */
        lookupFromPathIndex?: number;
        /** Cache method, can be false or string array (e.g., ['cookie', 'localStorage']) */
        caches?: boolean | string[];
        /** Cookie expiration time (minutes) */
        cookieMinutes?: number;
        /** Cookie expiration date (Date object, takes precedence over cookieMinutes) */
        cookieExpirationDate?: Date;
        /** Cookie domain */
        cookieDomain?: string;
        /** Request header key name, default 'accept-language' */
        lookupHeader?: string;
      }

      #Resources Type

      type Resources = {
        [lng: string]: {
          [ns: string]: string | Record<string, string>;
        };
      };
      Info

      The namespace value can be a string (for simple key-value pairs) or an object (for nested translation structures).