6月1日 09:25
How does i18next implement language detection and switching?
Language Detection
Using i18next-browser-languagedetector
javascriptimport LanguageDetector from 'i18next-browser-languagedetector'; i18next .use(LanguageDetector) .init({ detection: { order: ['querystring', 'cookie', 'localStorage', 'navigator', 'htmlTag'], caches: ['localStorage', 'cookie'], lookupQuerystring: 'lng', lookupCookie: 'i18next', lookupLocalStorage: 'i18nextLng', lookupSessionStorage: 'i18nextLng', lookupFromPathIndex: 0, checkWhitelist: true } });
Detection Priority
- querystring: Get from URL query parameter (e.g.,
?lng=en) - cookie: Get from cookie
- localStorage: Get from local storage
- navigator: Get from browser's language settings
- htmlTag: Get from HTML tag's lang attribute
Language Switching
Basic Switching
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> <button onClick={() => changeLanguage('fr')}>Français</button> </div> ); }
Asynchronous Switching
javascriptasync function changeLanguageAsync(lng) { try { await i18n.changeLanguage(lng); console.log('Language switched successfully'); } catch (error) { console.error('Language switch failed:', error); } }
Switching with Loading State
javascriptfunction LanguageSwitcher() { const { i18n } = useTranslation(); const [loading, setLoading] = useState(false); const changeLanguage = async (lng) => { setLoading(true); try { await i18n.changeLanguage(lng); } finally { setLoading(false); } }; return ( <div> {loading && <div>Loading...</div>} <button onClick={() => changeLanguage('en')} disabled={loading}> English </button> <button onClick={() => changeLanguage('zh')} disabled={loading}> 中文 </button> </div> ); }
Listening to Language Changes
Using Event Listeners
javascriptfunction MyComponent() { const { i18n } = useTranslation(); const [currentLanguage, setCurrentLanguage] = useState(i18n.language); useEffect(() => { const handleLanguageChange = (lng) => { setCurrentLanguage(lng); console.log('Language switched to:', lng); }; i18n.on('languageChanged', handleLanguageChange); return () => { i18n.off('languageChanged', handleLanguageChange); }; }, [i18n]); return <p>Current language: {currentLanguage}</p>; }
Using useTranslation's ready State
javascriptfunction MyComponent() { const { t, ready } = useTranslation(); if (!ready) { return <div>Loading translations...</div>; } return <h1>{t('welcome')}</h1>; }
Persisting Language Settings
Using localStorage
javascriptfunction LanguageSwitcher() { const { i18n } = useTranslation(); const changeLanguage = (lng) => { i18n.changeLanguage(lng); localStorage.setItem('preferredLanguage', lng); }; useEffect(() => { const savedLanguage = localStorage.getItem('preferredLanguage'); if (savedLanguage && savedLanguage !== i18n.language) { i18n.changeLanguage(savedLanguage); } }, [i18n]); return ( <div> <button onClick={() => changeLanguage('en')}>English</button> <button onClick={() => changeLanguage('zh')}>中文</button> </div> ); }
Using URL Parameters
javascript// get language from URL parameters function getLanguageFromURL() { const params = new URLSearchParams(window.location.search); return params.get('lng') || 'en'; } // update URL parameters function updateLanguageInURL(lng) { const url = new URL(window.location); url.searchParams.set('lng', lng); window.history.pushState({}, '', url); } function LanguageSwitcher() { const { i18n } = useTranslation(); const changeLanguage = (lng) => { i18n.changeLanguage(lng); updateLanguageInURL(lng); }; return ( <div> <button onClick={() => changeLanguage('en')}>English</button> <button onClick={() => changeLanguage('zh')}>中文</button> </div> ); }
Server-side Language Detection
Express.js Example
javascriptconst express = require('express'); const i18next = require('i18next'); const i18nextMiddleware = require('i18next-http-middleware'); const LanguageDetector = require('i18next-browser-languagedetector'); i18next .use(LanguageDetector) .use(i18nextMiddleware.LanguageDetector) .init({ detection: { order: ['header', 'querystring', 'cookie'], caches: ['cookie'] } }); const app = express(); app.use(i18nextMiddleware.handle(i18next)); app.get('/', (req, res) => { const language = req.language; res.send(`Current language: ${language}`); });
Next.js Example
javascript// pages/_app.js import { appWithTranslation } from 'next-i18next'; function MyApp({ Component, pageProps }) { return <Component {...pageProps} />; } export default appWithTranslation(MyApp); // pages/index.js import { useTranslation } from 'next-i18next'; export default function Home() { const { t, i18n } = useTranslation(); const changeLanguage = (lng) => { i18n.changeLanguage(lng); }; return ( <div> <h1>{t('welcome')}</h1> <button onClick={() => changeLanguage('en')}>English</button> <button onClick={() => changeLanguage('zh')}>中文</button> </div> ); }
Best Practices
- User Preference First: Respect user's language preference
- Persist Settings: Use localStorage or cookie to save user's choice
- Graceful Degradation: Use default language when detection fails
- Loading State: Show loading state to improve user experience
- URL Sync: Sync language settings to URL for easy sharing
- Server-side Support: Support language detection and switching on server-side
- Whitelist Filtering: Only allow switching to supported languages