react-i18next logs this warning when useTranslation runs and finds no i18next instance: none passed as the i18n option, none in context from I18nextProvider, and none registered globally by initReactI18next. In practice the module that calls i18n.use(initReactI18next).init(...) was never imported, or it was imported only after the first component had rendered.
Keep the setup in its own module and import it once at the entry point, before anything renders:
// src/i18n.js
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
i18n.use(initReactI18next).init({
resources: { en: { translation: { welcome: 'Welcome' } } },
lng: 'en',
fallbackLng: 'en',
interpolation: { escapeValue: false },
});
export default i18n;
// src/main.jsx (Vite) or src/index.js (Create React App)
import './i18n';
import { createRoot } from 'react-dom/client';
import App from './App';
createRoot(document.getElementById('root')).render(<App />);
Importing useTranslation in a component does not initialize anything; the side-effect import of ./i18n is what binds the instance. The explicit alternative is I18nextProvider, which the docs use for multiple instances and server-side rendering:
import { I18nextProvider } from 'react-i18next';
import i18n from './i18n';
<I18nextProvider i18n={i18n}>
<App />
</I18nextProvider>
In Next.js the setup has to reach the browser bundle: import it in pages/_app, or with the App Router in a 'use client' component rendered by the root layout, since useTranslation is a hook and only runs in client components. The react-i18next docs point to next-i18next, which handles this for both routers since v16.
Tests hit the same warning because nothing imports the setup. Either add it to Jest setupFiles or Vitest setupFiles (the testing page shows a minimal config with inline resources), wrap the render in I18nextProvider, or mock the package with the documented shape:
jest.mock('react-i18next', () => ({
useTranslation: () => ({
t: (key) => key,
i18n: { changeLanguage: () => new Promise(() => {}) },
}),
initReactI18next: { type: '3rdParty', init: () => {} },
}));
The warning's second sentence ("make sure there is only one instance of react-i18next") names the last cause: initReactI18next stores the instance inside the copy of react-i18next it was imported from, so a second copy pulled in by a shared component library or monorepo package leaves your components asking a different module. Run npm ls react-i18next i18next; each package must resolve to a single, deduped version, so align the versions or move them to the library's peerDependencies.
Published Oct 9, 2026 · Markdown version