1

I'm working on a Next.js app with App Router and I'm implementing localization using i18next with dynamic JSON imports for translations. I'm running into the following error:

Error: Only plain objects, and a few built-ins, can be passed to Client Components from Server Components. Classes or null prototypes are not supported.
 {common: Module}
 ^^^^^^

This error happens when I try to load my translations in layout.tsx like this:

const locale = "en";
const namespaces = ["common"];
const resources = await import(`@/locales/${locale}/${"common"}.json`);
<TranslationsProvider
 locale={locale}
 namespaces={namespaces}
 resources={{ [locale]: { ["common"]: resources } }}
>
 {children}
</TranslationsProvider>

i18nConfig.ts:

const i18nConfig = {
 locales: ["en", "ar"],
 defaultLocale: "en",
};
export default i18nConfig;

middleware.ts:

import { i18nRouter } from "next-i18n-router";
import i18nConfig from "../i18nConfig";
import { NextRequest, NextResponse } from "next/server";
export function middleware(request: NextRequest): NextResponse {
 return i18nRouter(request, i18nConfig);
}
export const config = {
 matcher: "/((?!api|static|.*\\..*|_next).*)",
};

i18n.ts:

import { createInstance } from "i18next";
import { initReactI18next } from "react-i18next/initReactI18next";
import resourcesToBackend from "i18next-resources-to-backend";
import i18nConfig from "../../i18nConfig";
export default async function initTranslations(locale, namespaces, i18nInstance?, resources?) {
 i18nInstance = i18nInstance || createInstance();
 i18nInstance.use(initReactI18next);
 if (!resources) {
 i18nInstance.use(
 resourcesToBackend(
 (language, namespace) =>
 import(`@/locales/${language}/${namespace}.json`)
 )
 );
 }
 await i18nInstance.init({
 lng: locale,
 fallbackLng: i18nConfig.defaultLocale,
 supportedLngs: i18nConfig.locales,
 defaultNS: namespaces[0],
 fallbackNS: namespaces[0],
 ns: namespaces,
 resources,
 preload: resources ? [] : i18nConfig.locales,
 });
 return {
 i18n: i18nInstance,
 resources: {
 [locale]: i18nInstance.services.resourceStore.data[locale],
 },
 t: i18nInstance.t,
 };
}

My Question: How can I correctly pass the translation resources to a client component like TranslationsProvider in Next.js App Router without triggering this error? What is the best practice for passing translations from server to client components using i18next in the App Router?

Any help or best practices would be appreciated!

Iaroslav Sobolev
1,6172 gold badges13 silver badges26 bronze badges
asked May 20, 2025 at 17:54

1 Answer 1

1

The problem is that await import(...) returns Module not a plain object.

This simples trick to solve your problem would be destructure resources like this:

const locale = "en";
const namespaces = ["common"];
const resources = await import(`@/locales/${locale}/${"common"}.json`);
<TranslationsProvider
 locale={locale}
 namespaces={namespaces}
 resources={{ [locale]: { ["common"]: {...resources} } }}
>
 {children}
</TranslationsProvider>

JSON.parse(JSON.stringify(resources)) will do the job as well, but {...resources} is faster and looks nicer :)

answered May 21, 2025 at 7:53
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.