Metronic React
Getting Started

Internationalization

Implement and customize multi-language support in Metronic React.

Metronic React includes built-in internationalization support using React Intl. This guide explains how to use and customize the i18n features.

i18n Architecture

The internationalization system is built around these key components:

  1. I18nProvider: Main provider that wraps the application
  2. Translation Files: JSON files containing translations for each language
  3. Language Selector: UI component for switching languages
  4. useIntl Hook: Accessing translations in components

I18n Provider

The I18n Provider is implemented in src/i18n/i18n-provider.tsx and provides language state and translation functions:

// src/i18n/i18n-provider.tsx
import { FC, createContext, useEffect, useState, ReactNode } from 'react';
import { IntlProvider } from 'react-intl';
import { useSettings } from '@/providers/settings-provider';
 
// Supported locales
import enMessages from './messages/en.json';
import deMessages from './messages/de.json';
import esMessages from './messages/es.json';
import frMessages from './messages/fr.json';
import jaMessages from './messages/ja.json';
import zhMessages from './messages/zh.json';
 
const allMessages = {
  en: enMessages,
  de: deMessages,
  es: esMessages,
  fr: frMessages,
  ja: jaMessages,
  zh: zhMessages,
};
 
const I18nContext = createContext({
  locale: 'en',
  selectLanguage: (lang: string) => {},
  currentLanguage: { title: 'English', flag: '🇬🇧' },
  languages: [
    // Available languages
  ],
});
 
export const useLang = () => useContext(I18nContext);
 
export const I18nProvider: FC<{ children: ReactNode }> = ({ children }) => {
  const { settings, saveSettings } = useSettings();
  const [locale, setLocale] = useState(settings.lang || 'en');
 
  // Language switching logic...
 
  // Context provider...
 
  return (
    <I18nContext.Provider value={{ locale, selectLanguage, currentLanguage, languages }}>
      <IntlProvider locale={locale} messages={allMessages[locale]}>
        {children}
      </IntlProvider>
    </I18nContext.Provider>
  );
};

Translation Files

Translation messages are defined in JSON files in the src/i18n/messages directory:

// src/i18n/messages/en.json
{
  "AUTH.LOGIN.TITLE": "Sign In",
  "AUTH.LOGIN.BUTTON": "Sign In",
  "AUTH.REGISTER.TITLE": "Sign Up",
  "AUTH.GENERAL.EMAIL_FIELD": "Email",
  "AUTH.GENERAL.PASSWORD_FIELD": "Password",
  "AUTH.GENERAL.CONFIRM_PASSWORD_FIELD": "Confirm Password",
  "AUTH.GENERAL.REMEMBER_ME": "Remember me",
  "AUTH.GENERAL.FORGOT_PASSWORD": "Forgot Password?",
  "AUTH.NEW_USER": "Don't have an account yet?",
  "AUTH.ALREADY_HAVE_ACCOUNT": "Already have an account?",
 
  "NAV.DASHBOARD": "Dashboard",
  "NAV.PROFILE": "Profile",
  "NAV.SETTINGS": "Settings",
  "NAV.LOGOUT": "Logout",
 
  "SETTINGS.TITLE": "Settings",
  "SETTINGS.LANGUAGE": "Language",
  "SETTINGS.THEME": "Theme",
  "SETTINGS.NOTIFICATIONS": "Notifications",
 
  "GENERAL.SAVE": "Save",
  "GENERAL.CANCEL": "Cancel",
  "GENERAL.CONFIRM": "Confirm",
  "GENERAL.LOADING": "Loading...",
  "GENERAL.ERROR": "An error occurred",
  "GENERAL.SUCCESS": "Success"
}

Using Translations in Components

Using the FormattedMessage Component

For static text, use the FormattedMessage component:

import { FormattedMessage } from 'react-intl';
 
function LoginForm() {
  return (
    <form>
      <h1>
        <FormattedMessage id="AUTH.LOGIN.TITLE" />
      </h1>
      <label>
        <FormattedMessage id="AUTH.GENERAL.EMAIL_FIELD" />
      </label>
      <input type="email" />
 
      <label>
        <FormattedMessage id="AUTH.GENERAL.PASSWORD_FIELD" />
      </label>
      <input type="password" />
 
      <button type="submit">
        <FormattedMessage id="AUTH.LOGIN.BUTTON" />
      </button>
    </form>
  );
}

Using the useIntl Hook

For dynamic content, use the useIntl hook:

import { useIntl } from 'react-intl';
 
function ProfileCard({ username, joinDate }) {
  const intl = useIntl();
 
  const formattedDate = intl.formatDate(joinDate, {
    year: 'numeric',
    month: 'long',
    day: 'numeric'
  });
 
  const welcomeMessage = intl.formatMessage(
    { id: 'PROFILE.WELCOME' },
    { username }
  );
 
  return (
    <div>
      <h2>{welcomeMessage}</h2>
      <p>{intl.formatMessage({ id: 'PROFILE.JOIN_DATE' })}: {formattedDate}</p>
    </div>
  );
}

Language Selector

A language selector component is provided to allow users to switch languages:

// src/i18n/language-selector.tsx
import { useLang } from '@/i18n/i18n-provider';
 
export function LanguageSelector() {
  const { currentLanguage, languages, selectLanguage } = useLang();
 
  return (
    <div className="language-selector">
      <div className="current-language">
        <span className="flag">{currentLanguage.flag}</span>
        <span className="title">{currentLanguage.title}</span>
      </div>
 
      <ul className="language-dropdown">
        {languages.map((lang) => (
          <li key={lang.lang} onClick={() => selectLanguage(lang.lang)}>
            <span className="flag">{lang.flag}</span>
            <span className="title">{lang.title}</span>
          </li>
        ))}
      </ul>
    </div>
  );
}

Date and Number Formatting

React Intl provides utilities for formatting dates and numbers according to the current locale:

import { useIntl } from 'react-intl';
 
function TransactionList({ transactions }) {
  const intl = useIntl();
 
  return (
    <ul>
      {transactions.map((transaction) => (
        <li key={transaction.id}>
          <span>{transaction.description}</span>
          <span>
            {intl.formatNumber(transaction.amount, {
              style: 'currency',
              currency: 'USD'
            })}
          </span>
          <span>
            {intl.formatDate(transaction.date, {
              year: 'numeric',
              month: 'short',
              day: 'numeric'
            })}
          </span>
        </li>
      ))}
    </ul>
  );
}

RTL (Right-to-Left) Support

For languages that are read from right to left (like Arabic), Metronic React provides RTL support:

// In I18nProvider
const rtlLanguages = ['ar'];
 
useEffect(() => {
  document.documentElement.dir = rtlLanguages.includes(locale) ? 'rtl' : 'ltr';
  // Apply RTL-specific styles or classes
}, [locale]);

Adding a New Language

To add a new language:

  1. Create a new translation file:
// src/i18n/messages/fr.json
{
  "AUTH.LOGIN.TITLE": "Connexion",
  "AUTH.LOGIN.BUTTON": "Se connecter",
  // Other translations...
}
  1. Add the new language to the provider:
// src/i18n/i18n-provider.tsx
import frMessages from './messages/fr.json';
 
const allMessages = {
  en: enMessages,
  fr: frMessages,
  // Other languages...
};
 
// Add to languages array
const languages = [
  {
    lang: 'en',
    title: 'English',
    flag: '🇬🇧',
  },
  {
    lang: 'fr',
    title: 'Français',
    flag: '🇫🇷',
  },
  // Other languages...
];

For more information on internationalization, check the files in the src/i18n directory and the React Intl documentation.