Language Detection
Using i18next-browser-languagedetector
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
}
});
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
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>
);
}
Asynchronous Switching
async 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
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>
);
}
Listening to Language Changes
Using Event Listeners
function 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
function MyComponent() {
const { t, ready } = useTranslation();
if (!ready) {
return <div>Loading translations...</div>;
}
return <h1>{t('welcome')}</h1>;
}
Persisting Language Settings
Using localStorage
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>
);
}
Using URL Parameters
// 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
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 Example
// 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