乐闻世界logo
搜索文章和话题

i18next 如何实现语言检测和切换?

2月18日 18:14

语言检测

使用 i18next-browser-languagedetector

javascript
import 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 } });

检测优先级

  1. querystring: 从 URL 查询参数中获取(如 ?lng=en
  2. cookie: 从 cookie 中获取
  3. localStorage: 从本地存储中获取
  4. navigator: 从浏览器的语言设置中获取
  5. htmlTag: 从 HTML 标签的 lang 属性中获取

语言切换

基本切换

javascript
import { 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> ); }

异步切换

javascript
async function changeLanguageAsync(lng) { try { await i18n.changeLanguage(lng); console.log('语言切换成功'); } catch (error) { console.error('语言切换失败:', error); } }

带加载状态的切换

javascript
function 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> ); }

监听语言变化

使用事件监听

javascript
function MyComponent() { const { i18n } = useTranslation(); const [currentLanguage, setCurrentLanguage] = useState(i18n.language); useEffect(() => { const handleLanguageChange = (lng) => { setCurrentLanguage(lng); console.log('语言已切换到:', lng); }; i18n.on('languageChanged', handleLanguageChange); return () => { i18n.off('languageChanged', handleLanguageChange); }; }, [i18n]); return <p>当前语言: {currentLanguage}</p>; }

使用 useTranslation 的 ready 状态

javascript
function MyComponent() { const { t, ready } = useTranslation(); if (!ready) { return <div>Loading translations...</div>; } return <h1>{t('welcome')}</h1>; }

持久化语言设置

使用 localStorage

javascript
function 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> ); }

使用 URL 参数

javascript
// 从 URL 参数获取语言 function getLanguageFromURL() { const params = new URLSearchParams(window.location.search); return params.get('lng') || 'en'; } // 更新 URL 参数 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> ); }

服务端语言检测

Express.js 示例

javascript
const 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 示例

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> ); }

最佳实践

  1. 用户偏好优先: 尊重用户的语言选择偏好
  2. 持久化设置: 使用 localStorage 或 cookie 保存用户选择
  3. 优雅降级: 当检测失败时使用默认语言
  4. 加载状态: 显示加载状态提升用户体验
  5. URL 同步: 将语言设置同步到 URL,便于分享
  6. 服务端支持: 在服务端也支持语言检测和切换
  7. 白名单过滤: 只允许支持的语言切换
标签:i18next