DEV Community

Cover image for Next.js ▲ + Typescript + Storybook The Really Simple Guide 2019
Adrian Prieto
Adrian Prieto

Posted on • Updated on • Originally published at adrianprieto.com

Next.js ▲ + Typescript + Storybook The Really Simple Guide 2019

1. Create a Basic Project

mkdir my-app
cd my-app
yarn init -y 
yarn add react react-dom next 
mkdir pages
Enter fullscreen mode Exit fullscreen mode

Then, open the package.json file in the root directory and replace scripts with the following:

"scripts": {
  "dev": "next",
  "build": "next build",
  "start": "next start"
}
Enter fullscreen mode Exit fullscreen mode

We’ll also need a page to render, let’s create pages/index.tsx:

const Home = () => <h1>Hello world!</h1>;

export default Home;
Enter fullscreen mode Exit fullscreen mode

2. Add Typescript and @types

yarn add -D typescript @types/react @types/node
Enter fullscreen mode Exit fullscreen mode

Start the dev server:

yarn dev
Enter fullscreen mode Exit fullscreen mode

You should see the following warning in your terminal window:

We detected TypeScript in your project and created a tsconfig.json file for you.
Enter fullscreen mode Exit fullscreen mode

now there should be a tsconfig.json file in the root of your project.

Optional: Let’s change the strict field in the tsconfig.json file that was generated for us, like so:

"strict": true
Enter fullscreen mode Exit fullscreen mode

Now restart the development server, so Next.js can use the updated tsconfig.json, and wait for the browser to reload.

3. Add Storybook

yarn add -D @storybook/react @babel/core babel-loader babel-preset-react-app
Enter fullscreen mode Exit fullscreen mode

Add the storybook script to the package.json file scripts:

{
  ...
  "scripts": {
    ...
    "storybook": "start-storybook -p 6006 -c .storybook"
  }
}
Enter fullscreen mode Exit fullscreen mode

Now create a .storybook folder in my-app directory. Then we need to add a config file and a webpack config file inside the .storybook directory:

mkdir .storybook
cd .storybook
touch config.js webpack.config.js
Enter fullscreen mode Exit fullscreen mode

config.js

// .storybook/config.js

import { configure } from '@storybook/react';
// automatically import all files ending in *.stories.tsx
configure(require.context('../src/stories', true, /\.stories\.tsx?$/), module);
Enter fullscreen mode Exit fullscreen mode

webpack.config.js

// .storybook/webpack.config.js

module.exports = ({ config }) => {
  config.module.rules.push({
    test: /\.(ts|tsx)$/,
    loader: require.resolve('babel-loader'),
    options: {
      presets: [require.resolve('babel-preset-react-app')],
    },
  });

  config.resolve.extensions.push('.ts', '.tsx');
  return config;
};
Enter fullscreen mode Exit fullscreen mode

Notice that I am configuring the stories directory to be inside the the src directory in config.js, you can place your stories wherever you want, just make sure you specify the correct path in the config.js file and the tsconfig.json file (if necessary).

We haven’t created those directories yet, so lets go ahead and do that in the root directory:

mkdir src 
cd src 
mkdir stories
Enter fullscreen mode Exit fullscreen mode

4. Create a Story

Let’s create a button component inside src/components so that we can see if storybook is working properly:

cd src
mkdir components
cd components
touch Button.tsx
Enter fullscreen mode Exit fullscreen mode
import * as React from 'react';

type Props = {
  text: string;
};

export default ({ text }: Props) => <button>{text}</button>;
Enter fullscreen mode Exit fullscreen mode

Now that we have a component, lets create a story in the stories directory:

// src/stories/Button.stories.tsx

import * as React from 'react';
import { storiesOf } from '@storybook/react';
import Button from '../components/Button';

storiesOf('Button', module).add('with text', () => {
  return <Button text="Click Me" />;
});
Enter fullscreen mode Exit fullscreen mode

Start storybook:

yarn storybook
Enter fullscreen mode Exit fullscreen mode

A browser window should open up in http://localhost:6006/ and storybook should render the story 😀.

Storybook window

That’s it! 🚀

Originally posted here.

Top comments (7)

Collapse
 
bangonkali profile image
Bangon Kali • Edited

You may also use CSF instead of storiesOf as the storiesOf is deprecated.

// src/stories/Button.stories.tsx
import * as React from 'react';
import Button from '../components/Button';

export default {
  title: 'Path/To/MyComponent',
  component: Button,
};

export const Basic = () => <Button text="Click Me" />;
Enter fullscreen mode Exit fullscreen mode

Preview

Preview

Collapse
 
iotheo profile image
John Theodorakopoulos

I would like to thank you for the tutorial. It's pretty neat and straight forward.

I'd like to ask, what's the intent of the test rule against ts/tsx files in the webpack.config of storybook?

Collapse
 
markohologram profile image
Marko A

I guess it modifies the default Storybook Webpack configuration in order to allow Storybook to resolve/load TS/TSX files. Project probably doesn't work without it and would probably throw you an error saying it cannot resolve files that you try to import into stories and maybe even throw errors that it cannot resolve the stories files themselves (if you write them in .tsx files as the example in this article does)

Collapse
 
jrowny profile image
Jonathan

Great article! I think there's a typo in the TS install code. Should be @types/node instead of @types/nod

Collapse
 
aprietof profile image
Adrian Prieto • Edited

oops... typos... ¯_(ツ)_/¯

Thanks!

Collapse
 
sargtier1 profile image
Salvatore Argentieri

baller tutorial

Collapse
 
kris10cabrera profile image
Kristen Cabrera

@aprietof is typescript necessary to use storybook with NextJS?