lifeiscontent / storybook-addon-next-router

Addon to use Next.js Router in Storybook
MIT License
107 stars 23 forks source link

`router is null` - How to lift router provider higher in the component tree? #54

Open abohannon opened 2 years ago

abohannon commented 2 years ago

When running Storybook, I'm getting the error Uncaught TypeError: router is null presumably because I am using useRouter in a provider that's rendering higher in the tree than RouterContext.Provider

My preview.js looks like this

const AppDecorator = (storyFn) => <RootProviders>{storyFn()}</RootProviders>;

export const decorators = [mswDecorator, AppDecorator];

export const parameters = {
  nextRouter: {
    Provider: RouterContext.Provider,
  },
//.....

Is there a way to render the Next router before any other providers? If not, this maybe should be considered a bug because as you'll see from the screenshots below, in a regular build the router is rendered above providers in the tree.

Regular app tree Screen Shot 2022-03-04 at 9 48 20 PM

Storybook tree Screen Shot 2022-03-04 at 8 20 42 PM

FeeLeeeD commented 2 years ago

Hello, @abohannon. I'm running the same issue. Any updates on that?

crhistianramirez commented 2 years ago

Is there a workaround for this?

hisapy commented 2 years ago

Hi, I had this problem but when running Storyshots.

So in my case, instead of adding this package as an addon in .storybook/main.js:

module.exports = {
  ...config,
  addons: [
    ...your addons
    "storybook-addon-next-router",
  ],
};

I added the decorator directly to the Component in the story

...
import { WithNextRouter } from 'storybook-addon-next-router/dist/decorators'
...

export default {
  title: 'MyComponent',
  component: MyComponent,
  decorators: [WithNextRouter],
} as ComponentMeta<typeof Sidebar>
TomFreudenberg commented 2 years ago

In my case I had to inject the WithNextRouter decorator after my AppDecorator.

So I dropped that from main.js

module.exports = {
  ...config,
  addons: [
    ...your addons
    // "storybook-addon-next-router", do not use it here
  ],
};

and brought it into in preview.js

...

import { RouterContext } from "next/dist/shared/lib/router-context";
import { decorators as RouterDecorators } from 'storybook-addon-next-router/dist/preset/addDecorator';

const withAppProviders = (Story, session, context) => (
  <SessionProvider session={session}>
    <AppContextProviders>
      <LocaleContextProviders>
        <ThemeContextProvider>
          <Story {...context} />
        </ThemeContextProvider>
      </LocaleContextProviders>
    </AppContextProviders>
  </SessionProvider>
);

export const decorators = [withAppProviders, ...RouterDecorators];

...

export const parameters = {
  nextRouter: {
    locale: i18n.locales[0],
    Provider: RouterContext.Provider
  },

...

That did the magic on my side

TomFreudenberg commented 2 years ago

@hisapy

doing like me should help to prevent importing that to ANY story


Hey Aaron @lifeiscontent

maybe you allow ordering / priorisation of presets or put that in documentation?

In any case thanks for your component!

shilman commented 2 years ago

@tmeasday @yannbf

This is a case where the addon's (storybook-addon-next-router's) decorator is getting inserted too late in the decorator chain.

I think we discussed having some kind of priority for decorators at one point. Do either of you know the current status/thinking on that?

tmeasday commented 2 years ago

@shilman - We have an internal API for "first/second" pass arg type enhancers, but that's it right now.

We've discussed a bunch of use cases / thoughts around decorator application but it's not clear what the solution should or could be.

lifeiscontent commented 1 year ago

@tmeasday @shilman any updates with v7 on the horizon?

tmeasday commented 1 year ago

@lifeiscontent it's not something we've talked about, no :/