Understanding i18n Provider
An i18n provider is an object with methods for translation and locale management:Quick Setup
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import Backend from "i18next-http-backend";
import detector from "i18next-browser-languagedetector";
i18n
.use(Backend)
.use(detector)
.use(initReactI18next)
.init({
supportedLngs: ["en", "es", "fr", "de"],
backend: {
loadPath: "/locales/{{lng}}/{{ns}}.json",
},
defaultNS: "common",
fallbackLng: ["en"],
});
export default i18n;
import { I18nProvider } from "@refinedev/core";
import { useTranslation } from "react-i18next";
export const i18nProvider: I18nProvider = {
translate: (key, options, defaultMessage) => {
const { t } = useTranslation();
return t(key, options, defaultMessage);
},
changeLocale: (locale: string) => {
return i18n.changeLanguage(locale);
},
getLocale: () => {
return i18n.language;
},
};
import { Refine } from "@refinedev/core";
import { i18nProvider } from "./i18nProvider";
import "./i18n"; // Initialize i18next
const App = () => (
<Refine
i18nProvider={i18nProvider}
// ... other props
>
{/* Your app */}
</Refine>
);
{
"pages": {
"login": {
"title": "Sign in to your account",
"signin": "Sign in",
"signup": "Sign up",
"email": "Email",
"password": "Password"
}
},
"posts": {
"posts": "Posts",
"titles": {
"list": "Posts",
"create": "Create Post",
"edit": "Edit Post",
"show": "Post Details"
},
"fields": {
"id": "ID",
"title": "Title",
"content": "Content",
"status": "Status",
"createdAt": "Created At"
}
},
"buttons": {
"create": "Create",
"save": "Save",
"edit": "Edit",
"delete": "Delete",
"cancel": "Cancel",
"refresh": "Refresh"
}
}
{
"pages": {
"login": {
"title": "Inicia sesión en tu cuenta",
"signin": "Iniciar sesión",
"signup": "Registrarse",
"email": "Correo electrónico",
"password": "Contraseña"
}
},
"posts": {
"posts": "Publicaciones",
"titles": {
"list": "Publicaciones",
"create": "Crear Publicación",
"edit": "Editar Publicación",
"show": "Detalles de Publicación"
},
"fields": {
"id": "ID",
"title": "Título",
"content": "Contenido",
"status": "Estado",
"createdAt": "Creado el"
}
},
"buttons": {
"create": "Crear",
"save": "Guardar",
"edit": "Editar",
"delete": "Eliminar",
"cancel": "Cancelar",
"refresh": "Actualizar"
}
}
Using Translations
useTranslation Hook
With Default Values
With Interpolation
Pluralization
Changing Locales
useSetLocale Hook
With Flags
Translating Refine Components
Refine’s built-in components automatically use translations if available.Resource Names
Button Labels
Field Labels
Notification Messages
Advanced Patterns
Lazy Loading Translations
Namespace Organization
Date and Number Formatting
Right-to-Left (RTL) Support
Translation Keys from API
Persist Language Choice
Translation Management
Tools for managing translations:- Lokalise - Translation management platform
- Crowdin - Collaborative translation
- i18n-tasks - Find missing translations
- Translation.io - Rails-style translation management
Complete Translation Reference
Here’s a complete example with all Refine keys:public/locales/en/common.json
Testing Translations
Unit Tests
E2E Tests
Best Practices
- Organize by feature - Use namespaces for different sections
- Keep keys semantic - Use descriptive keys, not sentences
- Provide context - Add comments for translators
- Use interpolation - Don’t concatenate strings
- Handle plurals properly - Use pluralization features
- Test all languages - Ensure UI works with long translations
- Extract hard-coded strings - Use linters to find untranslated text
- Version translations - Track changes to translation files
Troubleshooting
Translations Not Loading
- Check file paths match configuration
- Verify JSON files are valid
- Check network tab for 404 errors
- Ensure i18n is initialized before rendering
Missing Translations
- Use fallback values
- Enable debug mode to see missing keys
- Use tools to find untranslated strings
Next Steps
- Learn about Authentication
- Explore Notifications
- Discover UI Frameworks