amannn / next-intl

🌐 Internationalization (i18n) for Next.js
https://next-intl-docs.vercel.app
MIT License
2.58k stars 236 forks source link

Got `Error: NextRouter was not mounted` when using `next/router` directly #1227

Closed LikeDreamwalker closed 3 months ago

LikeDreamwalker commented 3 months ago

Description

This issue is weird, and I don't know if next-intl is supposed to do this. For a next.js project with next-intl, normally, we should do this by the official documentation:

import { useRouter } from "@/library/navigation";
...
const router = useRouter();

And for some reasons, I am trying to import and use the useRouter from next/router, so codes become like this:

import { useRouter } from "next/router"
...
const router = useRouter();

I will receive an issue like: image

I can understand that next-intl needs some support from next/router and maybe modified it, but I didn't notice this from the official documentation, and this issue took me some time to figure out. And for my scenario, I am trying to develop a public component, which needs next/router, and I import it directly. Now I need to build a setup for this component to make it okay with both the original next.js project and the next-intl project.

Verifications

Mandatory reproduction URL

https://github.com/LikeDreamwalker/nextjs-mui-zustand-template/tree/dev-next-router-issue

Reproduction description

I make the demo in my public repo, so you can try it as:

  1. pnpm i
  2. pnpm run dev
  3. In src\components\MenuList\index.tsx, you can see the comment and by using the different useRouter to reproduce the issue

Also you can do this:

  1. Open an project with next-intl
  2. By changing the using like:
    // If we are trying to use the useRouter hook from next/router
    // We will receive an issue like:
    // Error: NextRouter was not mounted. https://nextjs.org/docs/messages/next-router-not-mounted
    import { useRouter } from "next/router";
    // But using from next-intl will be okay
    // import { useRouter } from "@/library/navigation";
    ...
    const router = useRouter();

Expected behaviour

  1. Use useRouter from next/router shouldn't have an error
  2. Or next-intl can make a more preceding notification
  3. Or next-intl can make a more clear alert in the official document (and please forgive me if I missed it)
LikeDreamwalker commented 3 months ago

Also, for my scenario, if I am trying to use render or portal from react-dome to attach a component to the app, I actually can't use the useRouter even if it comes from next-intl's createSharedPathnamesNavigation, which will bring me in: image Really need some help now.

jeremybosma commented 3 months ago

im not great with this but maybe import useRouter from next/navigation instead and see if that works