Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use NextJS's 'useRouter()' hook inside Storybook

I've been attempting to use the useRouter hooks from Next.js inside Storybook. However, every time I load up Storybook, I get 'cannot read property 'pathname' of null'. How might I resolve this issue?

import { useRouter } from "next/router";

const NavStrip = () => {
  const router = useRouter();

  return (
    ...
            <Link href="/dashboard" passHref>
              <StyledLink active={router.pathname === "/dashboard"}>
                ...
              </StyledLink>
            </Link>
    ...
         )
}

NavStrip.stories.tsx

import React from "react";
import NavStrip from "./index";

export default {
  component: NavStrip,
  title: "NavStrip",
};

export const Default = () => <NavStrip />;
like image 814
Brennan Avatar asked Jun 01 '20 18:06

Brennan


3 Answers

You should use Storybook Addon Next Router. As this answer states, you need to run Link inside Next and Storybook doesn't load Next, so this addon will mock the Router for you.

In my config, all I needed to do was:

// .storybook/preview.js
import { withNextRouter } from 'storybook-addon-next-router';

export const decorators = [withNextRouter()]

That should fix it.

like image 117
Angelo Dias Avatar answered Nov 16 '22 04:11

Angelo Dias


The setup for storybook-addon-next-router has changed a bit.

For version 3.x:

Add the addon to your configuration in .storybook/main.js:

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

Add the RouterContext.Provider to .storybook/preview.js:

import { RouterContext } from "next/dist/shared/lib/router-context"; // next 12
// import { RouterContext } from "next/dist/shared/lib/router-context"; // next 11.1
// import { RouterContext } from "next/dist/next-server/lib/router-context"; // next < 11.1

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

There are some other options (e.g. the ability to customize what the Next router provides). See the documentation.

like image 2
Cully Avatar answered Nov 16 '22 04:11

Cully


Storybook components run outside of the Next environment and outside of the page component which enables the use of next/router. Therefore you will not be able to use this outside of your Next page and its children.

Next's router functionalities are created in a Context API provider, therefore in order to use useRouter your component must be a child of that provider (which in the case of storybook it will never be).

like image 1
james Avatar answered Nov 16 '22 04:11

james