Open arianaamx-motorway opened 1 year ago
Hi @shilman,
I have added the repo with a reproducible bug: arianaamx-motorway/next-router-no-router-instance-found
And Stackblitz DEMO: https://stackblitz.com/github/arianaamx-motorway/next-router-no-router-instance-found?file=stories/pages/HomePage/HomePage.tsx
Hopefully, this helps with solving the problem!
Thank you so much @arianaamx-motorway !! We'll try to take care of it soon 🙏
Hi @arianaamx-motorway,
I have investigated your Stackblitz demo (thanks for that), and I see a couple of issues:
First of all, I saw it the first time, that Router as a singleton is imported to use properties like "pathname". I am pretty sure, that this is not the recommended way, and you should use useRouter
instead, like described here: https://nextjs.org/docs/api-reference/next/router.
Second, the properties in the stories were not defined properly to set pathname
to /signup
. I have created a corrected Stackblitz example: https://stackblitz.com/edit/github-vcrdnv
Hi @valentinpalkovic,
We have Class components, and by default can't use useRouter
hook. Router as singleton is still supported and we had no issues with it ever.
While we were using Storybook 7.0.0-beta.52
we mocked the router with storybook-addon-next-router
. I am trying to update it to the latest released version, and trying to mock it with the addon or without it doesn't work anymore.
I corrected the properties in the stories, still no luck.
@arianaamx-motorway Can you point me to the Next.js documentation, where this singleton pattern is described?
Well, I can't find it. They are recommending useRouter
and withRouter
.
But, there is a good discussion about the difference between the two, and when you should use singleton vs hook: https://github.com/vercel/next.js/discussions/18522#discussioncomment-2417009
As I said, it worked until I tried to update to the latest RC release.
The comment you are referring to is 1 year old. If the API is not documented officially, I would recommend to not use it, because it can change without warnings. So without having a official documentation available, I don't think that we will support this use case in the near future. But feel free to create a PR to add this functionality.
Let me know when the singleton import is an officially documented API. We will then take another look at it. For now, I marked this issue as won't fix
and close the issue.
I've successfully mocked the singletonRouter in this way.
Add new file .stoybook/mock-router.js
```javascript import singletonRouter from 'next/router' import { action } from '@storybook/addon-actions' export const createMockRouter = (...args) => { singletonRouter.router = newMockRouter(...args) singletonRouter.readyCallbacks.forEach((cb) => cb()) singletonRouter.readyCallbacks = [] return singletonRouter.router } export const defaultRouterParams = { pathname: '/', query: {}, } /** * Copied from: * https://github.com/storybookjs/storybook/blob/ca3901cd39a54b94caf0c9ab68678803670874aa/code/frameworks/nextjs/src/routing/page-router-provider.tsx#L19 */ export const newMockRouter = ({ globals, routeParams }) => ({ push(...args) { action('nextRouter.push')(...args) return Promise.resolve(true) }, replace(...args) { action('nextRouter.replace')(...args) return Promise.resolve(true) }, reload(...args) { action('nextRouter.reload')(...args) }, back(...args) { action('nextRouter.back')(...args) }, forward() { action('nextRouter.forward')() }, prefetch(...args) { action('nextRouter.prefetch')(...args) return Promise.resolve() }, beforePopState(...args) { action('nextRouter.beforePopState')(...args) }, events: { on(...args) { action('nextRouter.events.on')(...args) }, off(...args) { action('nextRouter.events.off')(...args) }, emit(...args) { action('nextRouter.events.emit')(...args) }, }, locale: globals?.locale, route: '/', asPath: '/', basePath: '/', isFallback: false, isLocaleDomain: false, isReady: true, isPreview: false, ...routeParams, }) ```
In your .storybook/preview.js
, please initialize the singletonRouter.
import { createMockRouter, defaultRouterParams } from './mock-router'
const preview = {
loaders: [
async ({ globals, parameters }) => ({
router: createMockRouter({
globals,
routeParams: {
...defaultRouterParams,
...parameters.nextjs?.router,
},
}),
}),
],
}
@valentinpalkovic, if you agree with my code, I can create a pull request that uses the provider default values and manages both AppRouter and PageRouter.
As background information, this export is marked as "Export the singletonRouter and this is the public API". Hope this API will be supported as it is well known by some users and there are projects where it is widely used
Describe the bug
Stack:
There is a Button with logic that breaks the Story:
The part that breaks is the Router.pathname . Error message:
I tried experimenting with nextjs object inside story, like so, but it didn't help:
Any help with this?
To Reproduce
arianaamx-motorway/next-router-no-router-instance-found
Stackblitz DEMO: https://stackblitz.com/github/arianaamx-motorway/next-router-no-router-instance-found?file=stories/pages/HomePage/HomePage.tsx
System
Additional context
No response