Closed bryanltobing closed 1 year ago
I just fixed the error. I had to put these versions: "react-i18next": "^12.2.0", "i18next": "^22.4.10",
Nice. Can you give the output of 'npm why -r react-i18next i18next'
And then let me know if you're importing useTranslation from react-i18next or from next-i18next ?
npm why -r react-i18next i18next
Remembering that these data are with the application working correctly. If you want, I can go back to the previous state, with a bug, and redo what you requested. And I do importging the useTranslation from "next-i18next".
data are with the application working correctly
Just to confirm, to make it work you've downgraded versions right ? Or I miss something cause it looks fine.
If you want, I can go back to the previous state
Yes that would be interesting for me to be sure about what I wrote in the https://github.com/i18next/next-i18next/blob/master/TROUBLESHOOT.md#how-to-debug-installation. I've tested yarn and pnpm but not yet npm. And this might be related to your error message as well
Just to confirm, to make it work you've downgraded versions right ? Or I miss something cause it looks fine.
Yes. I made the downgraded.
Yes that would be interesting for me to be sure about what I wrote in the https://github.com/i18next/next-i18next/blob/master/TROUBLESHOOT.md#how-to-debug-installation. I've tested yarn and pnpm but not yet npm. And this might be related to your error message as well
I don't know why but when updating the version to "react-i18next": "^12.3.1", "i18next": "^22.5.0", "next-i18next": "^13.2.2", now it just appears the alert: Generating static pages (0/34)react-i18next:: You will need to pass in an i18next instance by using initReactI18next react-i18next:: You will need to pass in an i18next instance by using initReactI18next.
But it doesn't give an error when building. And then the system is not working anymore. If you look at https://www.smartmeet.digital you will see that.
Can you give the output of 'npm why -r react-i18next i18next'
After updade the version...
Now I'm going to try to get it working again, just local. If I get it I'll get back to you here.
Could you try to run
npm dedupe npx -y rimraf --glob '**/node_modules' npm install
And see if the see if the problem persist. I would be very grateful 🙏
And if it doesn't I'll try to reproduce
Thanks a lot
Here is the sequence of the test I did now: First my package.json.
After I run: npm why -r react-i18next i18next
Then... npm dedupe
npx -y rimraf --glob '**/node_modules'
npm install
Perhaps the error is in some configuration. Then here's some other data:
Part of _app.jsx
So far the application is with the bug. It's not working properly.
Thank you so much... Can I ask you 2 more things:
// _app.tsx
import type { AppProps } from 'next/app'
import { appWithTranslation } from 'next-i18next'
import nextI18NextConfig from '../next-i18next.config'
const MyApp = ({ Component, pageProps }: AppProps) => (
<Component {...pageProps} />
)
export default appWithTranslation(MyApp, nextI18NextConfig)
import nextI18nextConfig from '../../next-i18next.config'
//...
...(await serverSideTranslations(locale, namespacesRequired, config)
//...
If it fixes the issue, I think I know where to look for and might take to time to rework it in there https://github.com/i18next/next-i18next/pull/1973 (esmodules and dual packaging)
I don't know what happened, I just rebuild the application and it works again... 🤷🏻♂️ before I do nothing
After I do rebuild.
I am using next-i18next which has a react-i18next dependency. I updated my project to use ESM by adding "type": "module" to my package.json
I had the same problem after this change to my package.json. "react-i18next:: You will need to pass in an i18next instance by using initReactI18next "
The issue for me was resolved by removing "type": "module" from the package.json and renaming the next.config.cjs back to next.config.js.
Root Cause for my setup: The "type": "module" setting tells Node.js to treat .js files as ESM. By default, Node.js treats .js files as CommonJS modules. However, as for next-i18next, it seems there was still ongoing discussion and no official support yet for ESM syntax
The issue with useTranslation appears to have been a side effect of a conflict in the module system. After removing "type": "module" from package.json (thereby treating .js files as CommonJS modules by default), I could rename next.config.cjs back to next.config.js and useTranslation started functioning correctly again.
Sharing this experience here for anyone who might encounter a similar situation. Further investigation might be required to see if there's a more effective way to handle this transition or to clarify the documentation on how Next.js and react-i18next handle ESM.
Cannot promise, but I'll try to come with a pr for full esm. Thanks for digging into it.
FYI I have a repo https://github.com/belgattitude/nextjs-monorepo-example where esm seem to work without warning but my setup explicitly set the config https://github.com/i18next/next-i18next/blob/master/TROUBLESHOOT.md#how-to-explicitly-pass-the-config... see https://github.com/belgattitude/nextjs-monorepo-example/blob/main/apps/nextjs-app/src/backend/i18n/getServerTranslations.ts
having the same error in a remix app using react-i18next react-i18next:: You will need to pass in an i18next instance by using initReactI18next which i have correctly passed already: /**
npx remix reveal
✨import {PassThrough} from "node:stream"; import {createReadableStreamFromReadable} from "@remix-run/node"; import {RemixServer} from "@remix-run/react"; import isbot from "isbot"; import {renderToPipeableStream} from "react-dom/server"; import {CacheProvider} from '@emotion/react'; import ServerStyleContext from '../app/styles/server.context'; import createEmotionCache from '../app/styles/createEmotionCache'; import createEmotionServer from '@emotion/server/create-instance'; import {renderToString} from 'react-dom/server'; import {createInstance} from "i18next"; import Backend from "i18next-fs-backend"; import {resolve} from "node:path"; import {I18nextProvider, initReactI18next} from "react-i18next"; import i18next from "./i18next.server"; // The backend file we created import i18n from "./i18n"; // The configuration file we created const ABORT_DELAY = 5_000;
export default async function handleRequest( request, responseStatusCode, responseHeaders, remixContext, ) { const cache = createEmotionCache(); const {extractCriticalToChunks} = createEmotionServer(cache);
const html = renderToString(
<ServerStyleContext.Provider value={null}>
<CacheProvider value={cache}>
<RemixServer
context={remixContext}
url={request.url}
/>
</CacheProvider>
</ServerStyleContext.Provider>,
);
const chunks = extractCriticalToChunks(html);
const markup = renderToString(
<ServerStyleContext.Provider value={chunks.styles}>
<CacheProvider value={cache}>
<RemixServer
context={remixContext}
url={request.url}
/>
</CacheProvider>
</ServerStyleContext.Provider>,
);
let instance = createInstance();
// We can detect the specific locale from each request
let lng = await i18next.getLocale(request);
// The namespaces the routes about to render wants to use
let ns = i18next.getRouteNamespaces(remixContext);
let callbackName = isbot(request.headers.get("user-agent"))
? "onAllReady"
: "onShellReady";
await instance
.use(initReactI18next)
.use(Backend)
.init({
...i18n,
lng,
ns,
backend: {
loadPath: resolve("./public/locales/{{lng}}/{{ns}}.json"),
},
});
return new Promise((resolve, reject) => {
let didError = false;
let {pipe, abort} = renderToPipeableStream(
<I18nextProvider i18n={instance}>
<RemixServer context={remixContext} url={request.url}/>
</I18nextProvider>,
{
[callbackName]: () => {
let body = new PassThrough();
responseHeaders.set("Content-Type", "text/html");
resolve(
new Response("<!DOCTYPE html>" + body, {
headers: responseHeaders,
status: didError ? 500 : responseStatusCode,
})
);
pipe(body);
},
onShellError(error) {
reject(error);
},
onError(error) {
didError = true;
console.error(error);
},
}
);
setTimeout(abort, ABORT_DELAY);
})
}
function handleBotRequest( request, responseStatusCode, responseHeaders, remixContext ) { return new Promise((resolve, reject) => { let shellRendered = false; const {pipe, abort} = renderToPipeableStream( <RemixServer context={remixContext} url={request.url} abortDelay={ABORT_DELAY} />, { onAllReady() { shellRendered = true; const body = new PassThrough(); const stream = createReadableStreamFromReadable(body);
responseHeaders.set("Content-Type", "text/html");
resolve(
new Response(stream, {
headers: responseHeaders,
status: responseStatusCode,
})
);
pipe(body);
},
onShellError(error) {
reject(error);
},
onError(error) {
responseStatusCode = 500;
// Log streaming rendering errors from inside the shell. Don't log
// errors encountered during initial shell rendering since they'll
// reject and get logged in handleDocumentRequest.
if (shellRendered) {
console.error(error);
}
},
}
);
setTimeout(abort, ABORT_DELAY);
});
}
function handleBrowserRequest( request, responseStatusCode, responseHeaders, remixContext ) { return new Promise((resolve, reject) => { let shellRendered = false; const {pipe, abort} = renderToPipeableStream( <RemixServer context={remixContext} url={request.url} abortDelay={ABORT_DELAY} />, { onShellReady() { shellRendered = true; const body = new PassThrough(); const stream = createReadableStreamFromReadable(body);
responseHeaders.set("Content-Type", "text/html");
resolve(
new Response(stream, {
headers: responseHeaders,
status: responseStatusCode,
})
);
pipe(body);
},
onShellError(error) {
reject(error);
},
onError(error) {
responseStatusCode = 500;
// Log streaming rendering errors from inside the shell. Don't log
// errors encountered during initial shell rendering since they'll
// reject and get logged in handleDocumentRequest.
if (shellRendered) {
console.error(error);
}
},
}
);
setTimeout(abort, ABORT_DELAY);
});
} /**
npx remix reveal
✨import {RemixBrowser} from "@remix-run/react"; import {startTransition, StrictMode} from "react"; import {hydrateRoot} from "react-dom/client"; import {useCallback, useState} from 'react'; import {CacheProvider} from '@emotion/react'; import ClientStyleContext from '../app/styles/client.context'; import createEmotionCache from '../app/styles/createEmotionCache'; import i18next from "i18next"; import LanguageDetector from "i18next-browser-languagedetector"; import Backend from "i18next-http-backend"; import {I18nextProvider, initReactI18next} from "react-i18next"; import {getInitialNamespaces} from "remix-i18next"; import i18n from "./i18n"; // The configuration file we created
function ClientCacheProvider({children}) { const [cache, setCache] = useState(createEmotionCache());
const reset = useCallback(() => {
setCache(createEmotionCache());
}, []);
return (
<ClientStyleContext.Provider value={{reset}}>
<CacheProvider value={cache}>{children}</CacheProvider>
</ClientStyleContext.Provider>
);
}
i18next .use(initReactI18next) .use(LanguageDetector) .use(Backend) .init({ ...i18n, ns: getInitialNamespaces(), backend: { loadPath: "/locales/{{lng}}/{{ns}}.json", }, detection: { order: ["htmlTag"], caches: [], }, }) .then(() => { startTransition(() => { hydrateRoot( document,
);
});
}
)
i solve the issue by replace
import { useTranslation } from "react-i18next";
with
import { useTranslation } from "next-i18next";
🐛 Bug Report
This is only happening when I run
build
script and my layout calluseTranslation
hookTo Reproduce
A small repo to reproduce
pnmp run build
you'll see the warningThis is the only place I call useTranslation hook
my only page is
pages/index.tsx
and I already called the
serverSideTranslation
the translation is working, and I believe as mentioned here https://github.com/i18next/next-i18next/issues/1840#issuecomment-1145614232
the only issue is that there are warnings happen when running
build
Expected behavior
There's no warning that says
react-i18next:: You will need to pass in an i18next instance by using initReactI18next
when running build scriptYour Environment