react-i18next Introduction
react-i18next is a React-specific binding library for i18next, providing React Hooks and components to make internationalization more convenient in React applications.
Installation
bashnpm install react-i18next i18next # or yarn add react-i18next i18next
Basic Configuration
Initialization
javascriptimport i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; import Backend from 'i18next-http-backend'; import LanguageDetector from 'i18next-browser-languagedetector'; i18n .use(Backend) // load translation resources .use(LanguageDetector) // detect user language .use(initReactI18next) // bind react-i18next .init({ fallbackLng: 'en', debug: true, interpolation: { escapeValue: false // React already handles XSS } }); export default i18n;
Import in App Entry
javascriptimport React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import './i18n'; // import i18n configuration ReactDOM.render(<App />, document.getElementById('root'));
Using useTranslation Hook
Basic Usage
javascriptimport React from 'react'; import { useTranslation } from 'react-i18next'; function Welcome() { const { t } = useTranslation(); return <h1>{t('welcome')}</h1>; }
Specify Namespace
javascriptfunction MyComponent() { const { t } = useTranslation('common'); return <button>{t('save')}</button>; }
Multiple Namespaces
javascriptfunction MyComponent() { const { t } = useTranslation(['common', 'errors']); return ( <div> <button>{t('common:save')}</button> <p>{t('errors:notFound')}</p> </div> ); }
Using Trans Component
Basic Usage
javascriptimport { Trans } from 'react-i18next'; function MyComponent() { return ( <Trans i18nKey="user.profile"> Welcome <strong>{{name}}</strong> to your profile </Trans> ); } // translation resources // "user.profile": "Welcome <1>{{name}}</1> to your profile"
Nested Components
javascript<Trans i18nKey="description"> Click <Link to="/about">here</Link> to learn more </Trans>
Using withTranslation HOC
javascriptimport { withTranslation } from 'react-i18next'; class MyComponent extends React.Component { render() { const { t } = this.props; return <h1>{t('title')}</h1>; } } export default withTranslation()(MyComponent);
Using I18nextProvider
javascriptimport { I18nextProvider } from 'react-i18next'; import i18n from './i18n'; function App() { return ( <I18nextProvider i18n={i18n}> <MyComponent /> </I18nextProvider> ); }
Language Switching
Create Language Switcher
javascriptimport { useTranslation } from 'react-i18next'; function LanguageSwitcher() { const { i18n } = useTranslation(); const changeLanguage = (lng) => { i18n.changeLanguage(lng); }; return ( <div> <button onClick={() => changeLanguage('en')}>English</button> <button onClick={() => changeLanguage('zh')}>中文</button> </div> ); }
Listen to Language Changes
javascriptfunction MyComponent() { const { t, i18n } = useTranslation(); const [currentLanguage, setCurrentLanguage] = useState(i18n.language); useEffect(() => { const handleLanguageChange = (lng) => { setCurrentLanguage(lng); }; i18n.on('languageChanged', handleLanguageChange); return () => { i18n.off('languageChanged', handleLanguageChange); }; }, [i18n]); return <p>Current language: {currentLanguage}</p>; }
Lazy Loading Namespaces
javascriptfunction LazyComponent() { const { t, ready } = useTranslation('lazyNamespace', { useSuspense: false }); if (!ready) { return <div>Loading...</div>; } return <p>{t('content')}</p>; }
Best Practices
- On-demand Loading: Use namespaces and lazy loading to optimize performance
- Type Safety: Use type definitions for TypeScript projects
- Error Handling: Handle missing translations
- Testing: Write internationalization-related unit tests
- Code Splitting: Separate translation resources from application code