47ng/nuqs

Storybook issue "invariant expected app router to be mounted"

isBatak opened this issue · 5 comments

Context

What's your version of nuqs?

"next-usequerystate": "1.15.2"

Next.js information (obtained by running next info):

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.1.0: Mon Oct  9 21:28:45 PDT 2023; root:xnu-10002.41.9~6/RELEASE_ARM64_T6020
Binaries:
  Node: 20.10.0
  npm: 10.2.3
  Yarn: 3.2.3
  pnpm: 8.6.12
Relevant Packages:
  next: 14.0.4
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.2.2
Next.js Config:
  output: N/A

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

When running components that uses useQueryState in Storybook this error is shown
image

Storybook version:
"storybook": "7.6.8"
"@storybook/nextjs": "7.6.8"

Docs: https://github.com/storybookjs/storybook/blob/next/code/frameworks/nextjs/README.md#nextjs-navigation

My project uses just pages folder so I don't have appDirectory set to true.

parameters: {
    nextjs: {
      appDirectory: true, // as we are using pages folder I don't have this flag in the story
    },
  },

If I enable it then I get this error
image

This is logical because we are using useRouter in our components.
From next issue https://nextjs.org/docs/messages/next-router-not-mounted

This can also happen when you try to use the useRouter hook from next/router inside the app directory, as the App Router's useRouter from next/navigation has different behavior to the useRouter hook in pages.

Reproduction

CodeSandbox Link

Thanks for the report. nuqs uses imports from next/navigation to be compatible with both routers under a unified API, but it seems like Storybook doesn't support importing the pages router from there.

This is a gray area of compatibility with Next.js, as the compat layer for the pages router from next/navigation is not feature-complete and downright buggy in some configuration combinations. We had to go around those issues by tapping into Next.js internals in such cases, see #454.

Unfortunately there's not much advice I can give you here but watch that thread in storybookjs/storybook#24722 for potential solutions.

Thx @franky47 for the quick response.
I figured this would be the answer from the storybook issue. It seems they are working on the solution for v8 release.
As you can see, I opened issues on bot sides so it's more visible, and helpful to others with the same issue :D
Maybe it's safe to close this issue because there's nothing you can do form the lib perspective.

Sounds good. Feel free to ping back here if/when you find a suitable solution.

Here is the workaround until Storybook fix the issue.

import {
	AppRouterContext,
	type AppRouterInstance,
} from 'next/dist/shared/lib/app-router-context.shared-runtime';

const meta = {
	decorators: [
		(Story) => (
			<AppRouterContext.Provider value={{} as AppRouterInstance}>
				<Story />
			</AppRouterContext.Provider>
		),
	],
};

@franky47 do you maybe know the answer to this question?storybookjs/storybook#24722 (comment)