Different instances of `next/navigation` on SSR with tRPC
luixo opened this issue · 5 comments
Context
What's your version of next-usequerystate
?
1.13.0
Next.js information (obtained by running next info
):
14.0.3
Are you using:
- ❌ The app router
- ✅ The pages router
- ❌ The
basePath
option in your Next.js config - ❌ The experimental
windowHistorySupport
flag in your Next.js config
Description
My setup is Next.js 14 + tRPC (which runs some SSR prepasses with a corresponding attribute on).
The SSR prepass is the location when it goes wrong - app crashes with invariant expected app router to be mounted
error (which basically means we don't have AppRouterContext
in react scope). This only applies to SSR, if I render page without useQueryState
hook on SSR and navigate to the problematic page client-side - there is not problem.
It happens because there are two different contexts - one from "next/navigation" (the one that actually exists in scope) and one from "next/navigation.js" (the one expected by hook in useQueryState
).
To illustrate this example, I wrote this code in my custom hook:
import { useRouter } from "next/navigation";
import { useRouter as useRouterJs } from "next/navigation.js";
console.log("Are the same?", useRouterJs === useRouter); // false server-side, true client-side
My Node.js debugger links those functions to different instances of navigation.js
file, one has link webpack-internal:///node_modules/next/dist/client/components/navigation.js
and another has file:///<my-app>/node_modules/next/dist/client/components/navigation.js
.
I suspect something's happening in the bundling process.
My current (temporary) solution is to patch the library and pass my own useRouter
and useSearchParams
, but it is not sustainable.
Reproduction
- Create a tRPC Next.js template
- Add
ssr: true
increateTRPCNext
function - Render the page with
useQueryState
hook
This is connected to a change requested in this discussion.
I'm getting a different error with a simple create-next-app + tRPC with ssr: true setup:
TypeError: useInsertionEffect only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/react-client-hook-in-server-component
This is odd since we're in the pages router, there should be no concept of client or server components there. Since the error goes away when setting ssr: false, it could be related to your issue, throwing webpack off.
Do you have a minimal reproduction example where you see your import issue?
I'm getting a different error with a simple create-next-app + tRPC with ssr: true setup
Resolved here: trpc/trpc#5133
Thanks for the patch, I'll give it a try tomorrow.
I also tried foregoing the use of useInsertionEffect in #429, but it gets trickier to sync the state of hooks with Next.js' navigation using traditional useEffects, because of the rendering order, so I probably won't explore this idea further.
There's no need to do that, tRPC uses an obsolete library react-ssr-prepass
to prerender non-suspense hooks at the moment, it's not on this library side