Internationalization Basics: Implementing i18n in React Dashboards
Learn to implement i18n in your React dashboard. We cover managing language state and using context to provide localized UI strings to your components.
Previously in this course, we explored Managing Global Modals: A Scalable Pattern for React UI to decouple UI overlays from component logic. In this lesson, we apply similar architectural principles to solve a different challenge: globalizing your application through i18n (internationalization).
Making an application truly global isn't just about translating text; it's about building a system that can handle different languages, date formats, and layout directions. For our dashboard, we will implement a robust provider-based architecture that allows users to toggle their preferred language dynamically.
Understanding i18n Architecture from First Principles
At its core, i18n is the process of preparing your software to be adapted to various languages and regions without engineering changes. The companion process, localization (often abbreviated as l10n), is the actual translation and formatting.
To implement this in React, we need three distinct layers:
- The Translation Dictionary: A JSON object or external service containing key-value pairs for each supported locale.
- The Language State: A mechanism to track the user's current selection (e.g., 'en', 'es', 'fr').
- The Context Provider: A wrapper that broadcasts the current language and a helper function to retrieve the correct string based on that language.
We avoid hardcoding strings directly in our components. Instead, we reference keys, ensuring our UI remains clean and maintainable.
Building a Translation Context
We’ll start by creating a dedicated provider. This keeps our language state centralized, similar to how we managed state in Advanced Context Patterns: Scalable State for React Dashboards.
JAVASCRIPT// src/context/I18nContext.jsx import React, { createContext, useContext, useState } from CE9178">'react'; const translations = { en: { welcome: "Welcome to your Dashboard" }, es: { welcome: "Bienvenido a su Panel" } }; const I18nContext = createContext(); export const I18nProvider = ({ children }) => { const [locale, setLocale] = useState(CE9178">'en'); const t = (key) => translations[locale][key] || key; return ( <I18nContext.Provider value={{ locale, setLocale, t }}> {children} </I18nContext.Provider> ); }; export const useTranslation = () => useContext(I18nContext);
By exposing a t function, any component can now access localized text without knowing the internal structure of our dictionary.
Implementing Localization in the Dashboard
Now, integrate this into your dashboard. In your main layout or root component, wrap your application with the I18nProvider.
JAVASCRIPT// Example usage in a dashboard header const DashboardHeader = () => { const { t, setLocale } = useTranslation(); return ( <header> <h1>{t(CE9178">'welcome')}</h1> <select onChange={(e) => setLocale(e.target.value)}> <option value="en">English</option> <option value="es">Español</option> </select> </header> ); };
This approach allows your dashboard to react instantly to language changes. When setLocale is called, the context value updates, causing all components consuming useTranslation to re-render with the new language strings.
Hands-on Exercise
Your task is to extend the existing dashboard settings.
- Create a
localesfolder and move your translation dictionary into a separate JSON file. - Add a third language (e.g., 'fr') to your dictionary.
- Update the
I18nProviderto persist the chosen language tolocalStorage. You can reference the logic we built in Building a useLocalStorage Hook to ensure the user's preference survives a page refresh.
Common Pitfalls
- Hardcoding Fallbacks: Always ensure your
tfunction returns the key if the translation is missing. This makes it immediately obvious during development when a string hasn't been localized. - Context Re-renders: Because the
I18nContextvalue changes every time the user switches languages, ensure your provider value is memoized if the dictionary grows large, or keep the dictionary outside the component tree to avoid unnecessary object recreation. - Directionality (RTL): Remember that some languages (Arabic, Hebrew) are written Right-to-Left. If you plan to support these, you'll need to toggle a CSS class on the
<body>or root<div>to handle layout mirroring.
Recap
We have successfully decoupled our UI text from our components using a custom I18nProvider. By centralizing language state and providing a helper function, we've created a scalable foundation for a multi-language dashboard. This pattern of using context to distribute configuration—like language or theme—is a standard approach in professional React applications.
Up next: We will integrate real-time communication into our dashboard by learning to handle WebSocket connections for live updates.
Work with me

Headless WordPress + Next.js Frontend Development
Keep WordPress for content, get a lightning-fast Next.js frontend. The best of both worlds — familiar editing, modern speed.

React & Next.js Dashboard / Admin UI Development
A clean, data-rich dashboard UI in React or Next.js — charts, tables, and real-time data that your users will actually enjoy using.