Next.js Tales: Navigating Development with Storybook Integration

Sai Kumar Nekkanti
6 min readMar 1, 2024

--

Introduction:

I know I am late to follow up with my previous article, “Exploring Beyond Create React App: Choosing the Right Framework for Your Project.” But hey, better late than never, right? I wanted to ensure that when I did dive in, I covered the most important aspects and shed light on best practices for a typical Next.js project.

Paul Rudd Saying Hey, look at us

In this article, we’re going to delve into a crucial aspect of Next.js development — integrating Storybook. But before we get into the nitty-gritty, let’s take a moment to appreciate the journey we’ve been on. From exploring different frameworks to choosing the perfect fit for your project, it’s been quite an adventure.

Now, as we venture into the realm of Next.js, it’s essential to equip ourselves with the tools and practices that will set us up for success. And that’s where Storybook comes into play. It’s not just about showcasing components; it’s about streamlining development, enhancing collaboration, and ensuring code quality.

So, If you’re prepared to dive into Storybook integration with Next.js, let’s get going. We’ll cover the essentials, explore best practices, and arm ourselves with the knowledge to tackle Next.js projects like pros. Let’s get started!

Setting Up Storybook in Next.js:

Before diving into Storybook integration, ensure you have set up your Next.js application. If not, follow these steps:

Create a Next.js App: Use the following command to create a new Next.js app with specific configurations:npx create-next-app@latest

  • When prompted, select the desired options such as Tailwind CSS, TypeScript, aliases, app routes, and ESLint. Follow the default prompts for the rest of the configuration.
Screenshot of the set up prompts

Once your Next.js app is set up, proceed with integrating Storybook:

Integrating Storybook: Execute the following command within your Next.js project directory:npx storybook@latest init

This command initializes Storybook in your project. Choose the default options provided during the initialization process.

With these steps completed, Storybook should now be integrated into your Next.js project, ready for use. You can proceed to write stories for your components and explore the benefits of using Storybook in your development workflow

Writing Stories for Components

Now that we have our Button and Card components set up, it’s time to create stories for them within Storybook. Stories serve as visual representations of your components in different states and configurations, allowing for easier development, testing, and collaboration. You can find the source code for the Button and Card components here. Stay tuned for my next article, where we’ll explore how to organize your code and components efficiently, ensuring scalability and maintainability in your Next.js project.

// Button.stories.tsx
import Button from "../components/Button/Button";
import type { Meta, StoryObj } from "@storybook/react";

const meta = {
title: "Components/Button",
component: Button,
parameters: {
layout: "centered", // Center the component in the Canvas
},
tags: ["autodocs"], // Autogenerate documentation
argTypes: {
onClick: { action: "clicked" }, // Log clicks in Storybook
variant: {
options: ["primary", "secondary"],
control: { type: "radio" },
},
},
};

export default meta;

type Story = StoryObj<typeof meta>;

export const Primary: Story = {
args: {
variant: "primary",
children: "Primary Button",
},
};

export const Secondary: Story = {
args: {
...Primary.args,
variant: "secondary",
children: "Secondary Button",
},
};

In the provided code:

  • The metaobject defines metadata for the Button component within Storybook. It includes the title of the story, the component being described, and additional parameters such as layout settings and tags.
  • The argTypes property within meta captures the onClick event emitted by the button and provides a control for users to switch between button variants using radio buttons.
  • By using ...Primary.args, the args from the Primary story are reused for subsequent stories, ensuring consistency and reducing redundancy in story definitions.
  • Including the tags: ["autodocs"] within the meta object serves a specific purpose related to documentation generation. When set to "autodocs", Storybook automatically generates documentation for the component based on its PropTypes or TypeScript definitions.

Card Stories:

// Card.stories.tsx
import Card from "../components/Card/Card";
import type { Meta, StoryObj } from "@storybook/react";
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = {
title: "Components/Card",
component: Card,
parameters: {
// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout
layout: "centered",
},
// This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
tags: ["autodocs"],
argTypes: {
className: {
control: "text",
},
},
} satisfies Meta<typeof Card>;

export default meta;
type Story = StoryObj<typeof meta>;
export const VariantOne: Story = {
args: {
title: "Cat Card Title",
description: "Cat Card Description",
imageUrl:
"https://as2.ftcdn.net/v2/jpg/04/91/61/71/1000_F_491617156_xYzmSVi3eTvOjGR7gVBCF2vvNf24AmGS.jpg",
},
};

export const VariantTwo: Story = {
args: {
title: "Dog Card ",
description: "Dog Card Description xD",
imageUrl:
"https://as2.ftcdn.net/v2/jpg/05/08/37/21/1000_F_508372195_H9K3KIdsqlVMDgPd0ENTa8TUXuq9L9jF.jpg",
},
};

With these stories in place, you can now visualize and interact with your Button and Card components directly within Storybook. This makes it easier to iterate on your designs, test different configurations, and ensure consistency across your application.

Organize Your Stories

It’s a good practice to keep your stories organized within a dedicated folder. Create a stories folder within your src directory and place your story files inside it. Here's an example project tree structure:

your-nextjs-project/
├── .storybook/
│ └── preview.ts (Ensure global SCSS import for Tailwind CSS)
├── src/
│ ├── components/
│ │ ├── Button/
│ │ │ ├── Button.tsx
│ │ │ └── Button.test.tsx
│ │ └── Card/
│ │ ├── Card.tsx
│ │ └── Card.test.tsx
│ └── stories/
│ │ ├── Button.stories.tsx
│ │ └── Card.stories.tsx
├── ...

Global SCSS Import for Tailwind CSS: Ensure that Tailwind CSS styles are applied to your components within Storybook. You can achieve this by importing the global SCSS file in the preview.ts file located in the .storybook folder. Here's an example of how you can do it:

import type { Preview } from "@storybook/react";
import "../src/app/globals.css";

const preview: Preview = {
parameters: {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
};

export default preview;

Note: For in-depth details about organizing your code and incorporating unit tests, I recommend checking out the repository linked here. This repository provides comprehensive information and guidelines for maintaining a well-structured codebase and implementing unit tests effectively.

Furthermore, stay tuned for my upcoming article where I’ll delve into setting up a scalable Next.js project with proper code organization, testing strategies, and more. I’m committed to continually updating the repository with best practices and refinements, aiming to make it a reliable starter boilerplate for Next.js and Storybook projects. Your feedback and contributions are always appreciated as we strive to maintain high standards and provide valuable resources for developers.

Conclusion

Integrating Storybook with Next.js offers a plethora of benefits for developers, enhancing component development and collaboration in your projects. By visually representing components in different states and configurations, Storybook streamlines development workflows, facilitates testing, and fosters better collaboration among team members.

However, the journey doesn’t end here. For more detailed insights into organizing your code and implementing unit tests effectively, I recommend exploring the repository linked here. This resource provides valuable guidelines and best practices to ensure a well-structured codebase and robust testing strategies.

Additionally, stay tuned for my upcoming article, where I’ll dive deeper into setting up scalable Next.js projects with proper code organization, testing methodologies, and more. I’m committed to continuously updating the repository with refined practices, aiming to provide a reliable starter boilerplate for Next.js and Storybook projects.

Your feedback and contributions are essential in this endeavor. Together, let’s elevate the standards of Next.js development and empower developers with valuable resources for success.

--

--