ProNextJS
    Loading
    lesson

    Setting up Storybook with Next.js

    Jack HerringtonJack Herrington

    NOTE: To get Tailwind to work in your Storybook previews you'll need to import your globals.css into preview.ts

    // .storybook/preview.ts
    import "../src/app/globals.css"
    

    Storybook is a great way to demo and test your components in isolation, separate from your main application. This makes it a valuable tool for working with designers and product managers, letting you focus on the UI and functionality of individual components.

    Creating a Next.js Project

    To get started, let's create a new Next.js project using the create-next-app command:

    pnpm dlx create-next-app@latest storybook-with-nextjs --use-pnpm
    

    Select the options for TypeScript, ESLint, Tailwind CSS, and the app router when prompted.

    Next, we'll install Storybook and set it up in our project:

    npx storybook@latest init
    

    Storybook will detect that we're using a Next.js project and configure itself accordingly. When installation is complete, Storybook will automatically launch in your browser.

    Navigating Storybook

    Storybook has a sidebar with the components you've added, like the example button. You can navigate through these components, change their props, and see how they behave in different scenarios.

    the button story

    Project Structure

    Inside of the src directory, Storybook adds a stories folder with example components like the button. The button component itself is implemented in Button.tsx, and its stories are defined in Button.stories.ts.

    The Button.stories.ts file has a meta block that specifies metadata for the component, like its title, location in the navigation bar, and the component itself. It also has an argTypes section that defines the available props for the button and how they should appear in the Storybook UI.

    // inside Button.stories.ts
    
    const meta = {
      title: 'Example/Button',
      component: Button,
      parameters: {
        layout: 'centered',
      },
      tags: ['autodocs'],
      argTypes: {
        backgroundColor: { control: 'color' },
      }
    }
    

    After the meta block, you'll see individual stories for the button component. Each story shows a different use case or variation of the component with specific props:

    export const Primary: Story = {
      args: {
        primary: true,
        label: 'Button',
      },
    };
    
    export const Secondary: Story = {
      args: {
        label: 'Button',
      },
    };
    
    export const Large: Story = {
      args: {
        size: 'large',
        label: 'Button',
      },
    };
    

    Integrating a Custom Button Component

    Let's bring the button component into our app.

    First move the Button.tsx and Button.stories.ts files from the stories directory to the app directory, then remove the stories directory.

    Now, let's add our own button component to Storybook. We'll move the existing Button and Button.stories.tsx files from the stories directory into our app directory.

    Open the demo Button.tsx file and replace the existing code with this new button that uses Tailwind CSS for styling:

    export default function Button({ label }: { label: string }) {
      return (
        <button className="px-5 py-2 bg-blue-800 text-white text-2xl">
          {label}
        </button>
      );
    }
    

    This code defines a simple button component using Tailwind CSS classes for styling.

    Next, open the Button.stories.tsx file and update it like this:

    import type { Meta, StoryObj } from '@storybook/react'
    import Button from './Button'
    
    const meta = {
      title: 'Example/Button',
      component: Button,
      parameters: {
        layout: 'centered',
      },
      tags: ['autodocs'],
      argTypes: {
        backgroundColor: { control: 'color' },
      }
    } satisfies Meta<typeof Button>
    
    export default meta
    type Story = StoryObj<typeof meta>
    
    export const Primary: Story = {
      args: {
        label: 'Button',
      },
    }
    

    This code defines the meta information for our button component and includes a single story named "Primary" that renders the button with the label "Button".

    Running Storybook

    With our button component integrated, we can now run Storybook again:

    pnpm storybook
    

    There is also a build-storybook script that has been added to the package.json file. This script generates a static version of Storybook that you can deploy own its own.

    Storybook is running

    You should now see our custom button component in the Storybook UI, with the Tailwind CSS styling. You can interact with the component, change its label, and explore its behavior in isolation.

    Next Steps

    There's a lot more that Storybook can do beyond the example here. Check out the Storybook docs to learn more about its features and how to make the most of it in your projects.

    We'll be revisiting Storybook later when we look at integrating it into monorepos and shared design systems.

    Transcript