next-translate icon indicating copy to clipboard operation
next-translate copied to clipboard

Error: No router instance found. You should only use "next/router" on the client side of your app.

Open meightythree opened this issue 3 years ago • 16 comments

I could repro the issue on stackblitz

What version of this package are you using? "next": "13.3.0", "next-translate": "^2.0.4", "next-translate-plugin": "^2.0.4"

What operating system, Node.js, and npm version? stackblitz, node v16.14.2, npm 7.17.0

What happened? I got an error when I change the language.

Ucaught (in promise) Error: No router instance found.
You should only use "next/router" on the client side of your app.

    at getRouter (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/client/router.js:144:15)
    at Object.get (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/client/router.js:155:26)
    at eval (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next-translate/lib/esm/setLanguage.js:104:86)
    at step (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next-translate/lib/esm/setLanguage.js:81:27)
    at Object.eval [as next] (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next-translate/lib/esm/setLanguage.js:30:53)
    at eval (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next-translate/lib/esm/setLanguage.js:23:71)
    at new Promise (<anonymous>)
    at __awaiter (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next-translate/lib/esm/setLanguage.js:9:12)
    at setLanguage (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next-translate/lib/esm/setLanguage.js:100:12)
    at _callee$ (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./app/page.tsx:73:114)
    at tryCatch (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/regenerator-runtime/runtime.js:45:40)
    at Generator.invoke [as _invoke] (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/regenerator-runtime/runtime.js:274:22)
    at prototype.<computed> [as next] (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/regenerator-runtime/runtime.js:97:21)
    at asyncGeneratorStep (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/@babel/runtime/helpers/esm/asyncToGenerator.js:7:28)
    at _next (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/@babel/runtime/helpers/esm/asyncToGenerator.js:27:17)
    at eval (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/@babel/runtime/helpers/esm/asyncToGenerator.js:32:13)
    at new Promise (<anonymous>)
    at eval (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/@babel/runtime/helpers/esm/asyncToGenerator.js:24:16)
    at HTMLUnknownElement.callCallback (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:19200:14)
    at Object.invokeGuardedCallbackDev (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:19249:16)
    at invokeGuardedCallback (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:19313:31)
    at invokeGuardedCallbackAndCatchFirstError (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:19327:25)
    at executeDispatch (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:30596:3)
    at processDispatchQueueItemsInOrder (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:30628:7)
    at processDispatchQueue (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:30641:5)
    at dispatchEventsForPlugins (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:30652:3)
    at eval (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:30842:12)
    at batchedUpdates$1 (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:23705:12)
    at batchedUpdates (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:27540:12)
    at dispatchEventForPluginEventSystem (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:30841:3)
    at dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:28045:5)
    at dispatchEvent (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:28037:5)
    at dispatchDiscreteEvent (webpack-internal:///(nexttranslateerrornorouterinst-jkmr--3000--b5037fed.local-credentialless.webcontainer.io/app-client)/./node_modules/next/dist/compiled/react-dom/cjs/react-dom.development.js:28010:5)

What did you expect to happen? Language should change without error.

Are you willing to submit a pull request to fix this bug? Hell yea, this would be my first open source contribution, I might need a little help thou.

meightythree avatar Apr 09 '23 14:04 meightythree

Are you using useRouter? Please provide a reproducible example

aralroca avatar Apr 11 '23 13:04 aralroca

The example is on the stackblitz link. There are two buttons english/spanish, if you click either of them the error will occur.

meightythree avatar Apr 11 '23 13:04 meightythree

Ah ok. Yes, setLanguage is not adapted yet to app dir, you can use useRouter from 'next/navigation': https://beta.nextjs.org/docs/api-reference/use-router

aralroca avatar Apr 11 '23 13:04 aralroca

Thank you for the quick answer @aralroca

meightythree avatar Apr 11 '23 14:04 meightythree

I have extended stackblitz with the provided example in next-translate docs, however it does not change the language with Link tags either. What am I missing @aralroca?

meightythree avatar Apr 12 '23 06:04 meightythree

I'm gonna explain. Well, setLanguage has Router provided from next/router which is deprecated in Next.js 13 (I mean, specifically, only in appDir) and should use next/navigation instead. This is why your current stackblitz is not working.

rikusen0335 avatar Apr 23 '23 16:04 rikusen0335

This is how I solved this issue, I created a custom hook

function useSetLanguage() {
    const router = useRouter();
    const pathname = usePathname();
    const searchParams = useSearchParams();

    return (locale: string) => {
        // now you got a read/write object
        const current = new URLSearchParams(Array.from(searchParams.entries())); // -> has to use this form

        current.set('lang', locale);

        // cast to string
        const search = current.toString();
        // or const query = `${'?'.repeat(search.length && 1)}${search}`;
        const query = search ? `?${search}` : '';

        router.push(`${pathname}${query}`);
    };
}

Which then I use like this:

const MyComponent = () => {
    const { lang } = useTranslation('common');
    const setLanguage = useSetLanguage();

    return (
        <Select
            onValueChange={(value) => setLanguage(value)}
            defaultValue={lang}
        >
      ...
        </Select>
    );
};

And this is where I found this solution: https://github.com/vercel/next.js/discussions/47583#discussioncomment-5449707

@aralroca I can try to make a PR to include this if it makes sense to you 👍

joaopedrodcf avatar Jun 27 '23 17:06 joaopedrodcf

@joaopedrodcf feel free to PR 👌 thanks

aralroca avatar Jun 27 '23 21:06 aralroca

@joaopedrodcf is there a way not to include lang as a queryParam and use NEXT_LOCALE cookie?

meightythree avatar Aug 20 '23 09:08 meightythree

Didn't have time to create the PR about this sorry @aralroca maybe someone can take it over :/

joaopedrodcf avatar Aug 24 '23 09:08 joaopedrodcf

@meightythree I would say that is possible but I didn't tried it, just remove the part where we see the query params and check the cookie, then you shouldn't need to add the router.push as well, as the url will be the same.

joaopedrodcf avatar Aug 24 '23 09:08 joaopedrodcf

@meightythree I would say that is possible but I didn't tried it, just remove the part where we see the query params and check the cookie, then you shouldn't need to add the router.push as well, as the url will be the same.

Thanks I will take a look and comment again if I succeed!

meightythree avatar Aug 24 '23 09:08 meightythree

Hi @meightythree,

I was wondering if you managed to discover a viable solution to utilize the setLanguage feature.

ThijmenGThN avatar Sep 14 '23 20:09 ThijmenGThN

Hi @meightythree

I second the question from @ThijmenGThN Did you manage to find a solution? 😊

Steven-Thelin avatar Jan 04 '24 14:01 Steven-Thelin

May close the issue for no activity 🙃

rikusen0335 avatar Jan 04 '24 16:01 rikusen0335

I haven't found a solution... started using another package next-international. Sorry it's not the answer you wanted to see.

meightythree avatar Jan 04 '24 22:01 meightythree