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:
- I18nProvider: Main provider that wraps the application
- Translation Files: JSON files containing translations for each language
- Language Selector: UI component for switching languages
- 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:
- Create a new translation file:
// src/i18n/messages/fr.json
{
"AUTH.LOGIN.TITLE": "Connexion",
"AUTH.LOGIN.BUTTON": "Se connecter",
// Other translations...
}
- 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.