Logo

dev-resources.site

for different kinds of informations.

Integrating Storybook into an existing next.js project

Published at
12/18/2024
Categories
storybook
nextjs
frontend
Author
layssadev
Categories
3 categories in total
storybook
open
nextjs
open
frontend
open
Author
9 person written this
layssadev
open
Integrating Storybook into an existing next.js project

In this article, you'll learn how to integrate Storybook into an existing Next.js project, including support for different themes.

Introduction

Storybook is an open-source tool that allows developers to build, test, and document UI components in isolation.

Install storybook
To get started, initialize Storybook in your project:

npx storybook@latest init
Enter fullscreen mode Exit fullscreen mode

Configure Your Project
Below is an example configuration for integrating Storybook with a Next.js project:

main.ts

// main.ts

import type { StorybookConfig } from '@storybook/nextjs'

import { join, dirname } from 'path'

function getAbsolutePath(value: string): any {
  return dirname(require.resolve(join(value, 'package.json')))
}

const config: StorybookConfig = {
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  addons: [
    getAbsolutePath('@storybook/addon-onboarding'),
    getAbsolutePath('@storybook/addon-essentials'),
    getAbsolutePath('@chromatic-com/storybook'),
    getAbsolutePath('@storybook/addon-interactions'),
  ],
  framework: {
    name: '@storybook/nextjs',
    options: {},
  },
  staticDirs: ['../public'],
}

export default config

Enter fullscreen mode Exit fullscreen mode

preview.ts

// preview.ts

import { Preview } from '@storybook/react'
import { themesNames } from '../src/theme'

// Contexts providers
import { withThemeProvider } from './themeProvider'

import { RouterContext } from 'next/dist/shared/lib/router-context.shared-runtime'

export const globalTypes = {
  parameters: {
    nextRouter: {
      Provider: RouterContext.Provider,
    },
  },
  theme: {
    name: 'Theme',
    description: 'Global theme for components',
    defaultValue: 'defaultTheme',
    toolbar: {
      icon: 'paintbrush',
      items: themesNames,
      showName: true,
    },
  }
}

const preview: Preview = {
  decorators: [withThemeProvider],
}

export default preview

Enter fullscreen mode Exit fullscreen mode

Note: When configuring Storybook with custom providers, such as themes or global contexts, it’s essential to mock these contexts properly.

Context Providers Setup

themeProvider.tsx

// themeProvider.tsx

import React from 'react'
import { ThemeProvider } from 'styled-components'
import { Decorator } from '@storybook/react'
import { QueryClient, QueryClientProvider } from 'react-query'
import { AppRouterContext } from 'next/dist/shared/lib/app-router-context.shared-runtime'
import { GlobalStyle } from '../src/styles/Global.styles'

const queryClient = new QueryClient()

const themes = {
  // ... all project themes
  // 'projectName' : { ...settings}
}

// Contexts providers
export const withThemeProvider: Decorator = (Story, context) => {
  const selectedTheme = context.globals.theme ?? 'defaultTheme'

  return (
    <QueryClientProvider client={queryClient}>
      <AppRouterContext.Provider
        // Overriding nextjs router functions
        value={{
          push: async () => true,
          replace: async () => true,
          back: () => {},
          prefetch: async () => {},
          forward: () => {},
          refresh: () => {},
        }}
      >
        <ThemeProvider theme={themes[selectedTheme]}>
          <GlobalStyle />
          <Story />
        </ThemeProvider>
      </AppRouterContext.Provider>
    </QueryClientProvider>
  )
}

Enter fullscreen mode Exit fullscreen mode

Example: Button Component

1. Create the Component

Create a new folder for the component at /src/components/button. Inside this folder, add the following file:

/src/components/button/index.tsx

// index.tsx

export default function Button({children, onClick, disabled}){
  return <button onClick={onClick} disabled={disabled}>{children}</button>
}
Enter fullscreen mode Exit fullscreen mode

2. Add Stories

In the same folder, create a file named Button.stories.ts to define the stories for the Button component.

You can use diferents files [js|jsx|mjs|ts|tsx].

/src/components/button/Button.stories.ts

// Button.stories.ts

import type { Meta, StoryObj } from '@storybook/react'
import { fn } from '@storybook/test'

import Button from './'

const meta = {
  title: 'UI/Primary Button',
  component: Button,
  parameters: {
    layout: 'centered',
  },
  tags: ['autodocs'],
  argTypes: {},
  args: { onClick: fn() },
} satisfies Meta<typeof Button>

export default meta
type Story = StoryObj<typeof meta>

export const Primary: Story = {
  args: {
    children: 'Button',
    disabled: false,
  },
  parameters: {
    nextjs: {
      appDirectory: true,
    },
  },
}

export const Disabled: Story = {
  args: {
    children: 'Button Disabled',
    disabled: true,
  },
  parameters: {
    nextjs: {
      appDirectory: true,
    },
  },
}

Enter fullscreen mode Exit fullscreen mode

Run and Build Storybook

To build and run your Storybook environment, use the following commands:

Build Storybook:

  npm run build-storybook
Enter fullscreen mode Exit fullscreen mode

Run Storybook:

  npm run storybook
Enter fullscreen mode Exit fullscreen mode

Finally, you can view Storybook's UI by opening it in your browser. After running npm run storybook, Storybook will be accessible at:

http://localhost:6006
Enter fullscreen mode Exit fullscreen mode

This interface allows you to browse, test, and document your components interactively. Enjoy exploring your UI components with Storybook! 🎉

You should see something like this:
Image description

storybook Article's
30 articles in total
Favicon
Integrate Storybook with VueJS
Favicon
Run Storybook with NX Expo and React Native Paper
Favicon
Storybook for UI Components: Build, Test, and Document Your React Components in Isolation
Favicon
Integrating Storybook into an existing next.js project
Favicon
How to customize storybook (custom theme and layout option)?
Favicon
How to add custom fonts and viewports in storybook?
Favicon
Made AI-Powered Interactive Storybook Generator with Next.js, Gemini and Elevenlabs ️‍🔥
Favicon
Storybook: The Workshop for Modern Frontends
Favicon
SanS-UI v0.0.1 Quick Start!
Favicon
SanS-UI Released v0.0.1
Favicon
Using Storybook with Angular and Vite 🎨
Favicon
Documentation of components in React with TypeScript using Storybook
Favicon
Documentação de componentes em React com Typescript usando Storybook
Favicon
Tutorial de utilização Storybook
Favicon
Component Driven Development with Storybook React Native
Favicon
Storybook: Stories for Smart Components
Favicon
Tutorial de instalação do Storybook com Tailwind
Favicon
đź“š How to Handle Multiple MSW Handlers in Storybook Stories
Favicon
Beginner Guide to React Storybook
Favicon
Comparing Vue Component Documentation tools
Favicon
How to stop Storybook opening a new webpage on start (automatically with zsh)
Favicon
Manual setup for a minimal Storybook
Favicon
Setup Your Universal App with React Native, Expo Router, Tamagui, and Storybook
Favicon
Configuring Storybook in Your Nuxt Project
Favicon
Documentando seus componentes no Storybook
Favicon
Build component library using Storybook
Favicon
Integrating Storybook with PrimeNG and TailwindCSS in an Nx Workspace
Favicon
Storybook setup: Virtual Screen Reader with Web Components
Favicon
Simple setup: Virtual Screen Reader in Storybook
Favicon
Using fonts in Storybook for Next.JS and Tailwind Projects

Featured ones: