From e616c831714ad7fd3a4b7e14519d6bb9cf1d99a2 Mon Sep 17 00:00:00 2001 From: Steve Dodier-Lazaro Date: Mon, 10 Nov 2025 16:15:10 +0100 Subject: [PATCH 01/12] Rework Get Started page CTA positioning and copy --- docs/index.mdx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/index.mdx b/docs/index.mdx index 574da0d6086b..baf27c444962 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -3,15 +3,11 @@ title: Get started with Storybook hideRendererSelector: true --- -Welcome to Storybook's documentation ✦ Learn how to get started with Storybook in your project. Then, explore Storybook's main concepts and discover additional resources to help you grow and maintain your Storybook. - -## What is Storybook? - Storybook is a frontend workshop for building UI components and pages in isolation. It helps you develop and share hard-to-reach states and edge cases without needing to run your whole app. Thousands of teams use it for UI development, testing, and documentation. It's open source and free. ## Install Storybook -Storybook is a standalone tool that runs alongside your app. It's a zero-config environment that works with any modern frontend framework. You can install Storybook into an existing project or create a new one from scratch. +Run this command to install Storybook into an existing project or create a new one from scratch: From af9b028f7a9d7e19a0fb814adf05bed249a06a4c Mon Sep 17 00:00:00 2001 From: Steve Dodier-Lazaro Date: Fri, 14 Nov 2025 10:53:28 +0100 Subject: [PATCH 02/12] Make create command codeblock a 'new users' variant --- docs/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.mdx b/docs/index.mdx index baf27c444962..6c1b33ea4d59 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -9,7 +9,7 @@ Storybook is a frontend workshop for building UI components and pages in isolati Run this command to install Storybook into an existing project or create a new one from scratch: - + Want to know more about installing Storybook? Check out the [installation guide](./get-started/install.mdx). From b0f2dd08b1e4e15a457cdae0f24cecb0c236d05c Mon Sep 17 00:00:00 2001 From: Steve Dodier-Lazaro Date: Mon, 24 Nov 2025 15:25:51 +0100 Subject: [PATCH 03/12] Docs: Rewrite frameworks to focus on new users --- docs/get-started/frameworks/angular.mdx | 206 ++++++-------- docs/get-started/frameworks/index.mdx | 11 +- docs/get-started/frameworks/nextjs-vite.mdx | 254 +++++++++--------- docs/get-started/frameworks/nextjs.mdx | 183 ++++++------- docs/get-started/frameworks/preact-vite.mdx | 40 +-- .../frameworks/react-native-web-vite.mdx | 126 ++++----- docs/get-started/frameworks/react-vite.mdx | 47 ++-- .../get-started/frameworks/react-webpack5.mdx | 65 ++--- docs/get-started/frameworks/svelte-vite.mdx | 69 +++-- docs/get-started/frameworks/sveltekit.mdx | 117 ++++---- docs/get-started/frameworks/vue3-vite.mdx | 89 +++--- .../frameworks/web-components-vite.mdx | 33 +-- 12 files changed, 570 insertions(+), 670 deletions(-) diff --git a/docs/get-started/frameworks/angular.mdx b/docs/get-started/frameworks/angular.mdx index 79e5dac188c2..b3af6d068d6d 100644 --- a/docs/get-started/frameworks/angular.mdx +++ b/docs/get-started/frameworks/angular.mdx @@ -6,102 +6,22 @@ sidebar: title: Angular --- -Storybook for Angular is a [framework](../../contribute/framework.mdx) that makes it easy to develop and test UI components in isolation for [Angular](https://angular.io/) applications. It includes: +Storybook for Angular is a [framework](../../contribute/framework.mdx) that makes it easy to develop and test UI components in isolation for [Angular](https://angular.io/) applications. It uses Angular builders and integrates with [Compodoc](https://compodoc.app/) to provide automatic documentation generation. -* 🧱 Uses Angular builders -* πŸŽ›οΈ Compodoc integration -* πŸ’« and more! +## Install -## Requirements +To install Storybook in an existing Angular project, run this command in your project's root directory: -* Angular β‰₯ 18.0 \< 21.0 -* Webpack β‰₯ 5.0 + -## Getting started +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). -### In a project without Storybook +Storybook is compatible with Angular β‰₯ 18.0 \< 21.0, and Webpack 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to better integrate Storybook with your Angular project. -Follow the prompts after running this command in your Angular project's root directory: - -{/* prettier-ignore-start */} - - - -{/* prettier-ignore-end */} - -[More on getting started with Storybook.](../install.mdx) - -### In a project with Storybook - -This framework is designed to work with Storybook 7+. If you’re not already using v7, upgrade with this command: - -{/* prettier-ignore-start */} - - - -{/* prettier-ignore-end */} - -#### Automatic migration - -When running the `upgrade` command above, you should get a prompt asking you to migrate to `@storybook/angular`, which should handle everything for you. In case that auto-migration does not work for your project, refer to the manual migration below. - -#### Manual migration - -First, install the framework: - -{/* prettier-ignore-start */} - - - -{/* prettier-ignore-end */} - -Then, update your `.storybook/main.js|ts` to change the framework property: - -{/* prettier-ignore-start */} - - - -{/* prettier-ignore-end */} - -Finally, update your `angular.json` to include the Storybook builder: - -```jsonc title="angular.json" -{ - "projects": { - "your-project": { - "architect": { - "storybook": { - "builder": "@storybook/angular:start-storybook", - "options": { - // The path to the storybook config directory - "configDir": ".storybook", - // The build target of your project - "browserTarget": "your-project:build", - // The port you want to start Storybook on - "port": 6006 - // More options available, documented here: - // https://github.com/storybookjs/storybook/tree/next/code/frameworks/angular/src/builders/start-storybook/schema.json - } - }, - "build-storybook": { - "builder": "@storybook/angular:build-storybook", - "options": { - "configDir": ".storybook", - "browserTarget": "your-project:build", - "outputDir": "dist/storybook/your-project" - // More options available, documented here: - // https://github.com/storybookjs/storybook/tree/next/code/frameworks/angular/src/builders/build-storybook/schema.json - } - } - } - } - } -} -``` ## Run Storybook -To run Storybook for a particular project, please run the following: +To run Storybook for a particular project, run the following: ```sh ng run :storybook @@ -115,15 +35,19 @@ ng run :build-storybook You will find the output in the configured `outputDir` (default is `dist/storybook/`). -## Setup Compodoc +## Configure + +To make the most out of Storybook in your Angular project, you can set up Compodoc integration and Storybook [decorators](/docs/writing-stories/decorators/) based on your project needs. + +### Compodoc You can include JSDoc comments above components, directives, and other parts of your Angular code to include documentation for those elements. Compodoc uses these comments to [generate documentation](../../writing-docs/autodocs.mdx) for your application. In Storybook, it is useful to add explanatory comments above `@Inputs` and `@Outputs`, since these are the main elements that Storybook displays in its user interface. The `@Inputs` and `@Outputs` are elements you can interact with in Storybook, such as [controls](../../essentials/controls.mdx). -### Automatic setup +#### Automatic setup When installing Storybook via `npx storybook@latest init`, you can set up Compodoc automatically. -### Manual setup +#### Manual setup If you have already installed Storybook, you can set up Compodoc manually. @@ -187,7 +111,7 @@ const preview: Preview = {}; export default preview; ``` -## `applicationConfig` decorator +### Application-wide providers If your component relies on application-wide providers, like the ones defined by [`BrowserAnimationsModule`](https://angular.dev/api/platform-browser/animations/BrowserAnimationsModule) or any other modules that use the forRoot pattern to provide a [`ModuleWithProviders`](https://angular.dev/api/core/ModuleWithProviders), you can apply the `applicationConfig` [decorator](../../writing-stories/decorators.mdx) to all stories for that component. This will provide them with the [bootstrapApplication function](https://angular.io/guide/standalone-components#configuring-dependency-injection), used to bootstrap the component in Storybook. @@ -230,7 +154,7 @@ export const WithCustomApplicationProvider: Story = { } ``` -## `moduleMetadata` decorator +### Angular dependencies If your component has dependencies on other Angular directives and modules, these can be supplied using the `moduleMetadata` [decorator](../../writing-stories/decorators.mdx) either for all stories of a component or for individual stories. @@ -270,66 +194,104 @@ export const WithCustomProvider: Story = { }; ``` + ## FAQ -### How do I migrate to an Angular Storybook builder? +### How do I manually install the Angular framework? -The Storybook [Angular builder](https://angular.io/guide/glossary#builder) is a way to run Storybook in an Angular workspace. It is a drop-in replacement for running `storybook dev` and `storybook build` directly. +The easiest way to install the Angular framework is to run the upgrade command, but you can also set it up manually. First, install the framework: -You can run `npx storybook@latest automigrate` to try letting Storybook detect and automatically fix your configuration. Otherwise, you can follow the next steps to adjust your configuration manually. +{/* prettier-ignore-start */} -#### Do you have only one Angular project in your workspace? + -First, go to your `angular.json` and add `storybook` and `build-storybook` entries in your project's `architect` section, as shown [above](#manual-setup). +{/* prettier-ignore-end */} -Second, adjust your `package.json` script section. Usually, it will look like this: +Then, update your `.storybook/main.js|ts` to change the framework property: -```jsonc title="package.json" -{ - "scripts": { - "storybook": "start-storybook -p 6006", // or `storybook dev -p 6006` - "build-storybook": "build-storybook" // or `storybook build` - } -} -``` +{/* prettier-ignore-start */} + + + +{/* prettier-ignore-end */} -Now, you can run Storybook with `ng run :storybook` and build it with `ng run :build-storybook`. Adjust the scripts in your `package.json` accordingly. +Finally, update your `angular.json` to include the Storybook builder: -```json title="package.json" +```jsonc title="angular.json" { - "scripts": { - "storybook": "ng run :storybook", - "build-storybook": "ng run :build-storybook" + "projects": { + "your-project": { + "architect": { + "storybook": { + "builder": "@storybook/angular:start-storybook", + "options": { + // The path to the storybook config directory + "configDir": ".storybook", + // The build target of your project + "browserTarget": "your-project:build", + // The port you want to start Storybook on + "port": 6006 + // More options available, documented here: + // https://github.com/storybookjs/storybook/tree/next/code/frameworks/angular/src/builders/start-storybook/schema.json + } + }, + "build-storybook": { + "builder": "@storybook/angular:build-storybook", + "options": { + "configDir": ".storybook", + "browserTarget": "your-project:build", + "outputDir": "dist/storybook/your-project" + // More options available, documented here: + // https://github.com/storybookjs/storybook/tree/next/code/frameworks/angular/src/builders/build-storybook/schema.json + } + } + } + } } } ``` - Also, `compodoc` is now built into `@storybook/angular`; you don't have to call it explicitly. If we're running `compodoc` in your `package.json` scripts like this: +### How do I migrate to an Angular Storybook builder? -```json title="package.json" +The Storybook [Angular builder](https://angular.io/guide/glossary#builder) is a way to run Storybook in an Angular workspace. It is a drop-in replacement for running `storybook dev` and `storybook build` directly. + +You can run `npx storybook@latest automigrate` to let Storybook detect and automatically fix your configuration. Otherwise, you can follow the next steps to adjust your configuration manually. + +#### With a single project in your Angular workspace + +Go to your `angular.json` and add `storybook` and `build-storybook` entries in your project's `architect` section, as shown [above](#manual-setup). + +Then, adjust your `package.json` script section, to replace the existing Storybook scripts with the Angular CLI commands: + +```diff title="package.json" { "scripts": { - "docs:json": "compodoc -p tsconfig.json -e json -d ./documentation", - "storybook": "npm run docs:json && start-storybook -p 6006", - "build-storybook": "npm run docs:json && build-storybook" +- "storybook": "start-storybook -p 6006", // or `storybook dev -p 6006` +- "build-storybook": "build-storybook" // or `storybook build` ++ "storybook": "ng run :storybook", - "build-storybook": "ng run :build-storybook" +- "docs:json": "compodoc -p tsconfig.json -e json -d ./documentation", +- "storybook": "npm run docs:json && start-storybook -p 6006", +- "build-storybook": "npm run docs:json && build-storybook" ++ "storybook": "ng run \ No newline at end of file + +## Supported frameworks + + + +## Community-maintained frameworks + +Storybook includes an active community that supports additional frameworks and libraries. These community-maintained frameworks are actively developed and maintained by community contributors. + + \ No newline at end of file diff --git a/docs/get-started/frameworks/nextjs-vite.mdx b/docs/get-started/frameworks/nextjs-vite.mdx index 2d6f8073c518..03f4bdb1dd51 100644 --- a/docs/get-started/frameworks/nextjs-vite.mdx +++ b/docs/get-started/frameworks/nextjs-vite.mdx @@ -6,137 +6,67 @@ sidebar: title: Next.js (Vite) --- -Storybook for Next.js (Vite) is the **recommended** [framework](../../contribute/framework.mdx) for developing and testing UI components in isolation for [Next.js](https://nextjs.org/) applications. It uses [Vite](https://vitejs.dev/) for faster builds and better performance. It includes: +Storybook for Next.js (Vite) is the **recommended** [framework](../../contribute/framework.mdx) for developing and testing UI components in isolation for [Next.js](https://nextjs.org/) applications. It uses [Vite](https://vitejs.dev/) for faster builds, better performance and [Storybook Testing](https://storybook.js.org/docs/writing-tests) support. -* πŸ”€ Routing -* πŸ–Ό Image optimization -* ‡️ Absolute imports -* 🎨 Styling -* ⚑ Vite-powered builds -* πŸ’« and more! +## Install -This Vite-based framework offers several advantages over the Webpack-based [`@storybook/nextjs`](./nextjs.mdx) framework: +To install Storybook in an existing Next.js project, run this command in your project's root directory: -* ⚑ **Faster builds** - Vite's build system is significantly faster than Webpack -* πŸ”§ **Modern tooling** - Uses the latest build tools and optimizations -* πŸ§ͺ **Better test support** - Full support for the [Vitest addon](../../writing-tests/integrations/vitest-addon/index.mdx) and other testing features -* πŸ“¦ **Simpler configuration** - No need for Babel or complex Webpack configurations -* 🎯 **Better development experience** - Faster HMR (Hot Module Replacement) and dev server startup - -## Requirements - -* Next.js β‰₯ 14.1 - -## Getting started - -### In a project without Storybook - -When you run `storybook init` in your Next.js project, Storybook will automatically detect your project and select the `@storybook/nextjs-vite` framework **unless** your project has custom Webpack or Babel configurations that may be incompatible with Vite. - -Follow the prompts after running this command in your Next.js project's root directory: - -{/* prettier-ignore-start */} - - - -{/* prettier-ignore-end */} - -[More on getting started with Storybook.](../install.mdx) - - - -If your project has a custom `webpack.config.js` or `.babelrc` file, `storybook init` will prompt you to choose between: - -- **`@storybook/nextjs-vite`** (recommended) - Faster, more modern, supports latest testing features -- **`@storybook/nextjs`** (Webpack 5) - Better compatibility with custom Webpack/Babel configurations - -Choose `nextjs-vite` if you're willing to migrate your custom configurations to Vite. Choose `nextjs` (Webpack 5) if you need to keep your existing Webpack/Babel setup. - - - -### In a project with Storybook - -This framework is designed to work with Storybook 10+. If you're not already using v10, upgrade with this command: - -{/* prettier-ignore-start */} - - - -{/* prettier-ignore-end */} - -#### Automatic migration - -When running the `upgrade` command above, you should get a prompt asking you to migrate to `@storybook/nextjs-vite`, which should handle everything for you. In case that auto-migration does not work for your project, refer to the manual migration below. + -You can also use the [`nextjs-to-nextjs-vite` automigration](#migrating-from-webpack) to migrate from the Webpack-based `@storybook/nextjs` framework to this Vite-based framework. +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). -#### Manual migration +Storybook is compatible with Next.js β‰₯ 14.1 with Vite β‰₯ 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to [configure Storybook](#configure) with your Next.js project. -First, install the framework: -{/* prettier-ignore-start */} +## Choose between Vite and Webpack - +This Vite-based framework offers several advantages over the Webpack-based [`@storybook/nextjs`](./nextjs.mdx) framework, and is the recommended option: -{/* prettier-ignore-end */} +* ⚑ **Faster builds** - Vite's build system is significantly faster than Webpack +* πŸ”§ **Modern tooling** - Uses the latest build tools and optimizations +* πŸ§ͺ **Better test support** - Full support for the [Vitest addon](../../writing-tests/integrations/vitest-addon/index.mdx) and other testing features +* πŸ“¦ **Simpler configuration** - No need for Babel or complex Webpack configurations +* 🎯 **Better development experience** - Faster Hot Module Replacement and dev server startup -Then, update your `.storybook/main.js|ts` to change the framework property: +Storybook will automatically detect your project and select the `nextjs-vite` framework **unless** your project has custom Webpack or Babel configurations. If you have custom configurations, Storybook will ask you which framework to install. -{/* prettier-ignore-start */} +Choose `nextjs-vite` if you're willing to migrate existing Babel or Webpack configurations to Vite. Choose `nextjs` (Webpack 5) if you need to keep your existing Webpack/Babel setup. - -{/* prettier-ignore-end */} +## Run Storybook - +To run Storybook for a particular project, run the following: -If your Storybook configuration contains custom Webpack operations in [`webpackFinal`](../../api/main-config/main-config-webpack-final.mdx), you will likely need to create equivalents in [`viteFinal`](../../api/main-config/main-config-vite-final.mdx). + -For more information, see the [Vite builder documentation](../../builders/vite.mdx#migrating-from-webpack). +To build Storybook, run: - + -Finally, if you were using Storybook plugins to integrate with Next.js, those are no longer necessary when using this framework and can be removed: - -{/* prettier-ignore-start */} - - - -{/* prettier-ignore-end */} +You will find the output in the configured `outputDir` (default is `storybook-static`). -#### Migrating from Webpack -Storybook provides a migration tool for migrating to this framework from the Webpack-based Next.js framework, `@storybook/nextjs`. To migrate, run this command: -```bash -npx storybook automigrate nextjs-to-nextjs-vite -``` -This automigration tool performs the following actions: +## Configure -1. Updates `package.json` files to replace `@storybook/nextjs` with `@storybook/nextjs-vite` -2. Updates `.storybook/main.js|ts` to change the framework property -3. Scans and updates import statements in your story files and configuration files +Storybook for Next.js with Vite supports many Next.js features including: - +* πŸ–Ό [Image optimization](#nextjss-image-component) +* πŸ”€ [Font optimization](#nextjs-font-optimization) +* πŸ”€ [Routing and navigation](#nextjs-routing) +* 🌐 [`next/head`](#nextjs-head) +* ‡️ [Absolute imports](#imports) +* 🎨 [Styling](#styling) +* 🎭 [Module mocking](#mocking-modules) +* ☁️ [React Server Component (experimental)](#react-server-components-rsc) -If your project has custom Webpack configurations in `.storybook/main.js|ts` (via `webpackFinal`), you'll need to migrate those to Vite configuration (via `viteFinal`) after running this automigration. See the [Vite builder documentation](../builders/vite.mdx#migrating-from-webpack) for more information. - - - -## Run the Setup Wizard - -If all goes well, you should see a setup wizard that will help you get started with Storybook introducing you to the main concepts and features, including how the UI is organized, how to write your first story, and how to test your components' response to various inputs utilizing [controls](../../essentials/controls.mdx). - -![Storybook onboarding](../../_assets/get-started/example-onboarding-wizard.png) - -If you skipped the wizard, you can always run it again by adding the `?path=/onboarding` query parameter to the URL of your Storybook instance, provided that the example stories are still available. - -## Next.js's Image component +### Next.js's Image component This framework allows you to use Next.js's [next/image](https://nextjs.org/docs/pages/api-reference/components/image) with no configuration. -### Local images +#### Local images [Local images](https://nextjs.org/docs/pages/building-your-application/optimizing/images#local-images) are supported. @@ -162,7 +92,7 @@ function Home() { } ``` -### Remote images +#### Remote images [Remote images](https://nextjs.org/docs/pages/building-your-application/optimizing/images#remote-images) are also supported. @@ -180,15 +110,15 @@ export default function Home() { } ``` -## Next.js font optimization +### Next.js font optimization [next/font](https://nextjs.org/docs/pages/building-your-application/optimizing/fonts) is partially supported in Storybook. The packages `next/font/google` and `next/font/local` are supported. -### `next/font/google` +#### `next/font/google` You don't have to do anything. `next/font/google` is supported out of the box. -### `next/font/local` +#### `next/font/local` For local fonts you have to define the [src](https://nextjs.org/docs/pages/building-your-application/optimizing/fonts#local-fonts) property. The path is relative to the directory where the font loader function is called. @@ -203,7 +133,7 @@ const localRubikStorm = localFont({ src: './fonts/RubikStorm-Regular.ttf' }); The Vite-based framework automatically handles font path mapping, so you don't need to configure `staticDirs` for fonts like you would with the Webpack-based framework. -### Not supported features of `next/font` +#### Not supported features of `next/font` The following features are not supported (yet). Support for these features might be planned for the future: @@ -213,7 +143,7 @@ The following features are not supported (yet). Support for these features might * [preload](https://nextjs.org/docs/pages/api-reference/components/font#preload) option gets ignored. Storybook handles Font loading its own way. * [display](https://nextjs.org/docs/pages/api-reference/components/font#display) option gets ignored. All fonts are loaded with display set to "block" to make Storybook load the font properly. -### Mocking fonts during testing +#### Mocking fonts during testing Occasionally fetching fonts from Google may fail as part of your Storybook build step. It is highly recommended to mock these requests, as those failures can cause your pipeline to fail as well. Next.js [supports mocking fonts](https://github.com/vercel/next.js/blob/725ddc7371f80cca273779d37f961c3e20356f95/packages/font/src/google/fetch-css-from-google-fonts.ts#L36) via a JavaScript module located where the env var `NEXT_FONT_GOOGLE_MOCKED_RESPONSES` references. @@ -257,7 +187,7 @@ module.exports = { }; ``` -## Next.js routing +### Next.js routing [Next.js's router](https://nextjs.org/docs/pages/building-your-application/routing) is automatically stubbed for you so that when the router is interacted with, all of its interactions are automatically logged to the [Actions panel](../../essentials/actions.mdx). @@ -267,7 +197,7 @@ You should only use `next/router` in the `pages` directory. In the `app` directo -### Overriding defaults +#### Overriding defaults Per-story overrides can be done by adding a `nextjs.router` property onto the story [parameters](../../writing-stories/parameters.mdx). The framework will shallowly merge whatever you put here into the router. @@ -283,7 +213,7 @@ These overrides can also be applied to [all stories for a component](../../api/p -### Default router +#### Default router The default values on the stubbed router are as follows (see [globals](../../essentials/toolbars-and-globals.mdx#globals) for more details on how globals work). @@ -332,7 +262,7 @@ const preview: Preview = { }; ``` -## Next.js navigation +### Next.js navigation @@ -340,7 +270,7 @@ Please note that [`next/navigation`](https://nextjs.org/docs/app/building-your-a -### Set `nextjs.appDirectory` to `true` +#### Set `nextjs.appDirectory` to `true` If your story imports components that use `next/navigation`, you need to set the parameter `nextjs.appDirectory` to `true` in for that component's stories: @@ -358,7 +288,7 @@ If your Next.js project uses the `app` directory for every page (in other words, {/* prettier-ignore-end */} -### Overriding defaults +#### Overriding defaults Per-story overrides can be done by adding a `nextjs.navigation` property onto the story [parameters](../../writing-stories/parameters.mdx). The framework will shallowly merge whatever you put here into the router. @@ -374,7 +304,7 @@ These overrides can also be applied to [all stories for a component](../../api/p -### `useSelectedLayoutSegment`, `useSelectedLayoutSegments`, and `useParams` hooks +#### `useSelectedLayoutSegment`, `useSelectedLayoutSegments`, and `useParams` hooks The `useSelectedLayoutSegment`, `useSelectedLayoutSegments`, and `useParams` hooks are supported in Storybook. You have to set the `nextjs.navigation.segments` parameter to return the segments or the params you want to use. @@ -426,7 +356,7 @@ These overrides can also be applied to [a single story](../../api/parameters.mdx The default value of `nextjs.navigation.segments` is `[]` if not set. -### Default navigation context +#### Default navigation context The default values on the stubbed navigation context are as follows: @@ -466,11 +396,13 @@ const preview: Preview = { }; ``` -## Next.js Head +### Next.js Head [`next/head`](https://nextjs.org/docs/pages/api-reference/components/head) is supported out of the box. You can use it in your stories like you would in your Next.js application. Please keep in mind, that the Head `children` are placed into the head element of the iframe that Storybook uses to render your stories. -## Sass/Scss +### Styling + +#### Sass/Scss [Global Sass/Scss stylesheets](https://nextjs.org/docs/pages/building-your-application/styling/sass) are supported without any additional configuration as well. Just import them into [`.storybook/preview.js|ts`](../../configure/index.mdx#configure-story-rendering) @@ -491,7 +423,7 @@ export default { }; ``` -## CSS/Sass/Scss Modules +#### CSS/Sass/Scss Modules [CSS modules](https://nextjs.org/docs/pages/building-your-application/styling/css-modules) work as expected. @@ -511,13 +443,14 @@ export function Button() { } ``` -## PostCSS +#### PostCSS Next.js lets you [customize PostCSS config](https://nextjs.org/docs/pages/building-your-application/configuring/post-css). Thus this framework will automatically handle your PostCSS config for you. This allows for cool things like zero-config Tailwind! (See [Next.js' example](https://github.com/vercel/next.js/tree/canary/packages/create-next-app/templates/default-tw)) -## Absolute imports +### Imports +#### Absolute imports [Absolute imports](https://nextjs.org/docs/pages/building-your-application/configuring/absolute-imports-and-module-aliases#absolute-imports) from the root directory are supported. @@ -551,7 +484,7 @@ Absolute imports **cannot** be mocked in stories/tests. See the [Mocking modules -## Module aliases +#### Module aliases [Module aliases](https://nextjs.org/docs/app/building-your-application/configuring/absolute-imports-and-module-aliases#module-aliases) are also supported. @@ -571,7 +504,7 @@ export default function HomePage() { } ``` -## Subpath imports +#### Subpath imports As an alternative to [module aliases](#module-aliases), you can use [subpath imports](https://nodejs.org/api/packages.html#subpath-imports) to import modules. This follows Node package standards and has benefits when [mocking modules](#mocking-modules). @@ -607,11 +540,11 @@ export default function HomePage() { } ``` -## Mocking modules +### Mocking modules Components often depend on modules that are imported into the component file. These can be from external packages or internal to your project. When rendering those components in Storybook or testing them, you may want to [mock those modules](../../writing-stories/mocking-data-and-modules/mocking-modules.mdx) to control and assert their behavior. -### Built-in mocked modules +#### Built-in mocked modules This framework provides mocks for many of Next.js' internal modules: @@ -620,11 +553,11 @@ This framework provides mocks for many of Next.js' internal modules: 3. [`@storybook/nextjs-vite/navigation.mock`](#storybooknextjs-vitenavigationmock) 4. [`@storybook/nextjs-vite/router.mock`](#storybooknextjs-viteroutermock) -### Mocking other modules +#### Mocking other modules To mock other modules, use [automocking](../../writing-stories/mocking-data-and-modules/mocking-modules.mdx#automocking) or one of the [alternative methods](../../writing-stories/mocking-data-and-modules/mocking-modules.mdx#alternative-methods) documented in the mocking modules guide. -## Runtime config +### Runtime config Next.js allows for [Runtime Configuration](https://nextjs.org/docs/pages/api-reference/next-config-js/runtime-configuration) which lets you import a handy `getConfig` function to get certain configuration defined in your `next.config.js` file at runtime. @@ -658,13 +591,13 @@ Calls to `getConfig` would return the following object when called within Storyb } ``` -## Custom Vite configuration +### Custom Vite configuration You can customize the [Vite configuration](../../builders/vite.mdx#configuration) used by Storybook in your `.storybook/main.js|ts` file. By default, Storybook's configuration extends the Vite configuration used by your project, but you can configure it to not do so. Not all Vite modifications are copy/paste-able between `next.config.js` and `.storybook/main.js|ts`. It is recommended to do your research on how to properly make your modification to Storybook's Vite config and on how [Vite works](https://vitejs.dev/guide/). -## Typescript +### Typescript Storybook handles most [Typescript](https://www.typescriptlang.org/) configurations, but this framework adds additional support for Next.js's support for [Absolute Imports and Module path aliases](https://nextjs.org/docs/pages/building-your-application/configuring/absolute-imports-and-module-aliases). In short, it takes into account your `tsconfig.json`'s [baseUrl](https://www.typescriptlang.org/tsconfig#baseUrl) and [paths](https://www.typescriptlang.org/tsconfig#paths). Thus, a `tsconfig.json` like the one below would work out of the box. @@ -679,7 +612,7 @@ Storybook handles most [Typescript](https://www.typescriptlang.org/) configurati } ``` -## React Server Components (RSC) +### React Server Components (RSC) (⚠️ **Experimental**) @@ -711,6 +644,65 @@ In the future we will provide better mocking support in Storybook and support fo ## FAQ + +### How do I migrate from the `nextjs` (Webpack 5) addon? + +#### Automatic migration + +Storybook provides a migration tool for migrating to this framework from the Webpack-based Next.js framework, [`@storybook/nextjs`](./nextjs.mdx). To migrate, run this command: + +```bash +npx storybook automigrate nextjs-to-nextjs-vite +``` + +This automigration tool performs the following actions: + +1. Updates `package.json` files to replace `@storybook/nextjs` with `@storybook/nextjs-vite` +2. Updates `.storybook/main.js|ts` to change the framework property +3. Scans and updates import statements in your story files and configuration files + + + +If your project has custom Webpack configurations in `.storybook/main.js|ts` (via `webpackFinal`), you'll need to migrate those to Vite configuration (via `viteFinal`) after running this automigration. See the [Vite builder documentation](../builders/vite.mdx#migrating-from-webpack) for more information. + + + +#### Manual migration + +First, install the framework: + +{/* prettier-ignore-start */} + + + +{/* prettier-ignore-end */} + +Then, update your `.storybook/main.js|ts` to change the framework property: + +{/* prettier-ignore-start */} + + + +{/* prettier-ignore-end */} + + + +If your Storybook configuration contains custom Webpack operations in [`webpackFinal`](../../api/main-config/main-config-webpack-final.mdx), you will likely need to create equivalents in [`viteFinal`](../../api/main-config/main-config-vite-final.mdx). + +For more information, see the [Vite builder documentation](../../builders/vite.mdx#migrating-from-webpack). + + + +Finally, if you were using Storybook plugins to integrate with Next.js, those are no longer necessary when using this framework and can be removed: + +{/* prettier-ignore-start */} + + + +{/* prettier-ignore-end */} + + + ### Stories for pages/components which fetch data Next.js pages can fetch data directly within server components in the `app` directory, which often include module imports that only run in a node environment. This does not (currently) work within Storybook, because if you import from a Next.js page file containing those node module imports in your stories, your Storybook's Vite build will crash because those modules will not run in a browser. To get around this, you can extract the component in your page file into a separate file and import that pure component in your stories. Or, if that's not feasible for some reason, you can [configure Vite to handle those modules](https://vitejs.dev/config/dep-optimization-options.html#optimizedeps-exclude) in your Storybook's [`viteFinal` configuration](../../builders/vite.mdx#configuration). diff --git a/docs/get-started/frameworks/nextjs.mdx b/docs/get-started/frameworks/nextjs.mdx index 01e583d9b668..cff371e8aef4 100644 --- a/docs/get-started/frameworks/nextjs.mdx +++ b/docs/get-started/frameworks/nextjs.mdx @@ -6,14 +6,8 @@ sidebar: title: Next.js (Webpack) --- -Storybook for Next.js (Webpack) is a [framework](../../contribute/framework.mdx) that makes it easy to develop and test UI components in isolation for [Next.js](https://nextjs.org/) applications using Webpack 5. It includes: +Storybook for Next.js (Webpack) is a [framework](../../contribute/framework.mdx) that makes it easy to develop and test UI components in isolation for [Next.js](https://nextjs.org/) applications using [Webpack 5](https://webpack.js.org/). -* πŸ”€ Routing -* πŸ–Ό Image optimization -* ‡️ Absolute imports -* 🎨 Styling -* πŸŽ› Webpack & Babel config -* πŸ’« and more! @@ -23,99 +17,65 @@ Use this Webpack-based framework (`@storybook/nextjs`) only if: - Your project has custom Webpack configurations that are incompatible with Vite - Your project has custom Babel configurations that require Webpack - You need specific Webpack features not available in Vite - -## Requirements - -* Next.js β‰₯ 14.1 +## Install -## Getting started +To install Storybook in an existing Next.js project, run this command in your project's root directory: -### In a project without Storybook + -When you run `storybook init` in your Next.js project, Storybook will automatically detect your project and select the [`@storybook/nextjs-vite`](./nextjs-vite.mdx) framework (which we recommend) unless your project has custom Webpack or Babel configurations that may be incompatible with Vite. +The command will prompt you to choose between this framework and [`@storybook/nextjs-vite`](./nextjs-vite.mdx). We recommend the Vite-based framework ([learn why](./nextjs-vite.mdx#choose-between-vite-and-webpack)). +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). -
-If your project has custom Webpack/Babel configurations +Storybook is compatible with Next.js β‰₯ 14.1 with Webpack 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to [configure Storybook](#configure) with your Next.js project. -If `storybook init` detects a custom Webpack configuration in your Next.js config file or `.babelrc` file, it will prompt you to choose between: -- **`@storybook/nextjs-vite`** (recommended) - Faster, more modern, supports latest testing features, but may be incompatible with your custom Webpack/Babel config -- **`@storybook/nextjs`** (Webpack 5) - Better compatibility with custom Webpack/Babel configurations -Choose `@storybook/nextjs` (Webpack 5) if you need to keep your existing Webpack/Babel setup and cannot migrate to Vite. +## Run Storybook -
+To run Storybook for a particular project, run the following: -Follow the prompts after running this command in your Next.js project's root directory: - -{/* prettier-ignore-start */} + - +To build Storybook, run: -{/* prettier-ignore-end */} + -[More on getting started with Storybook.](../install.mdx) +You will find the output in the configured `outputDir` (default is `storybook-static`). -### In a project with Storybook -This framework is designed to work with Storybook 7+. If you’re not already using v7, upgrade with this command: -{/* prettier-ignore-start */} - +## Configure -{/* prettier-ignore-end */} +Storybook for Next.js with Vite supports many Next.js features including: -#### Automatic migration +* πŸ–Ό [Image optimization](#nextjss-image-component) +* πŸ”€ [Font optimization](#nextjs-font-optimization) +* πŸ”€ [Routing and navigation](#nextjs-routing) +* 🌐 [`next/head`](#nextjs-head) +* ‡️ [Absolute imports](#imports) +* 🎨 [Styling](#styling) +* 🎭 [Module mocking](#mocking-modules) +* ☁️ [React Server Component (experimental)](#react-server-components-rsc) -When running the `upgrade` command above, you should get a prompt asking you to migrate to `@storybook/nextjs`, which should handle everything for you. In case that auto-migration does not work for your project, refer to the manual migration below. -#### Manual migration -First, install the framework: -{/* prettier-ignore-start */} - - - -{/* prettier-ignore-end */} - -Then, update your `.storybook/main.js|ts` to change the framework property: - -{/* prettier-ignore-start */} - - - -{/* prettier-ignore-end */} - -Finally, if you were using Storybook plugins to integrate with Next.js, those are no longer necessary when using this framework and can be removed: - -{/* prettier-ignore-start */} - - - -{/* prettier-ignore-end */} -#### Migrating to Vite -Please refer to the [migration instructions for `@storybook/nextjs-vite`](./nextjs-vite.mdx#migrating-from-webpack). -## Run the Setup Wizard -If all goes well, you should see a setup wizard that will help you get started with Storybook introducing you to the main concepts and features, including how the UI is organized, how to write your first story, and how to test your components' response to various inputs utilizing [controls](../../essentials/controls.mdx). -![Storybook onboarding](../../_assets/get-started/example-onboarding-wizard.png) -If you skipped the wizard, you can always run it again by adding the `?path=/onboarding` query parameter to the URL of your Storybook instance, provided that the example stories are still available. -## Next.js's Image component +### Next.js's Image component This framework allows you to use Next.js's [next/image](https://nextjs.org/docs/pages/api-reference/components/image) with no configuration. -### Local images +#### Local images [Local images](https://nextjs.org/docs/pages/building-your-application/optimizing/images#local-images) are supported. @@ -141,7 +101,7 @@ function Home() { } ``` -### Remote images +#### Remote images [Remote images](https://nextjs.org/docs/pages/building-your-application/optimizing/images#remote-images) are also supported. @@ -159,15 +119,15 @@ export default function Home() { } ``` -## Next.js font optimization +### Next.js font optimization [next/font](https://nextjs.org/docs/pages/building-your-application/optimizing/fonts) is partially supported in Storybook. The packages `next/font/google` and `next/font/local` are supported. -### `next/font/google` +#### `next/font/google` You don't have to do anything. `next/font/google` is supported out of the box. -### `next/font/local` +#### `next/font/local` For local fonts you have to define the [src](https://nextjs.org/docs/pages/building-your-application/optimizing/fonts#local-fonts) property. The path is relative to the directory where the font loader function is called. @@ -180,7 +140,7 @@ import localFont from 'next/font/local'; const localRubikStorm = localFont({ src: './fonts/RubikStorm-Regular.ttf' }); ``` -#### `staticDir` mapping +##### `staticDir` mapping You have to tell Storybook where the `fonts` directory is located, via the [`staticDirs` configuration](../../api/main-config/main-config-static-dirs.mdx#with-configuration-objects). The `from` value is relative to the `.storybook` directory. The `to` value is relative to the execution context of Storybook. Very likely it is the root of your project. @@ -190,7 +150,7 @@ You have to tell Storybook where the `fonts` directory is located, via the [`sta {/* prettier-ignore-end */} -### Not supported features of `next/font` +#### Not supported features of `next/font` The following features are not supported (yet). Support for these features might be planned for the future: @@ -200,7 +160,7 @@ The following features are not supported (yet). Support for these features might * [preload](https://nextjs.org/docs/pages/api-reference/components/font#preload) option gets ignored. Storybook handles Font loading its own way. * [display](https://nextjs.org/docs/pages/api-reference/components/font#display) option gets ignored. All fonts are loaded with display set to "block" to make Storybook load the font properly. -### Mocking fonts during testing +#### Mocking fonts during testing Occasionally fetching fonts from Google may fail as part of your Storybook build step. It is highly recommended to mock these requests, as those failures can cause your pipeline to fail as well. Next.js [supports mocking fonts](https://github.com/vercel/next.js/blob/725ddc7371f80cca273779d37f961c3e20356f95/packages/font/src/google/fetch-css-from-google-fonts.ts#L36) via a JavaScript module located where the env var `NEXT_FONT_GOOGLE_MOCKED_RESPONSES` references. @@ -244,7 +204,7 @@ module.exports = { }; ``` -## Next.js routing +### Next.js routing [Next.js's router](https://nextjs.org/docs/pages/building-your-application/routing) is automatically stubbed for you so that when the router is interacted with, all of its interactions are automatically logged to the [Actions panel](../../essentials/actions.mdx). @@ -252,7 +212,7 @@ module.exports = { You should only use `next/router` in the `pages` directory. In the `app` directory, it is necessary to use `next/navigation`. -### Overriding defaults +#### Overriding defaults Per-story overrides can be done by adding a `nextjs.router` property onto the story [parameters](../../writing-stories/parameters.mdx). The framework will shallowly merge whatever you put here into the router. @@ -266,7 +226,7 @@ Per-story overrides can be done by adding a `nextjs.router` property onto the st These overrides can also be applied to [all stories for a component](../../api/parameters.mdx#meta-parameters) or [all stories in your project](../../api/parameters.mdx#project-parameters). Standard [parameter inheritance](../../api/parameters.mdx#parameter-inheritance) rules apply. -### Default router +#### Default router The default values on the stubbed router are as follows (see [globals](../../essentials/toolbars-and-globals.mdx#globals) for more details on how globals work). @@ -315,13 +275,13 @@ const preview: Preview = { }; ``` -## Next.js navigation +### Next.js navigation Please note that [`next/navigation`](https://nextjs.org/docs/app/building-your-application/routing) can only be used in components/pages in the `app` directory. -### Set `nextjs.appDirectory` to `true` +#### Set `nextjs.appDirectory` to `true` If your story imports components that use `next/navigation`, you need to set the parameter `nextjs.appDirectory` to `true` in for that component's stories: @@ -339,7 +299,7 @@ If your Next.js project uses the `app` directory for every page (in other words, {/* prettier-ignore-end */} -### Overriding defaults +#### Overriding defaults Per-story overrides can be done by adding a `nextjs.navigation` property onto the story [parameters](../../writing-stories/parameters.mdx). The framework will shallowly merge whatever you put here into the router. @@ -353,7 +313,7 @@ Per-story overrides can be done by adding a `nextjs.navigation` property onto th These overrides can also be applied to [all stories for a component](../../api/parameters.mdx#meta-parameters) or [all stories in your project](../../api/parameters.mdx#project-parameters). Standard [parameter inheritance](../../api/parameters.mdx#parameter-inheritance) rules apply. -### `useSelectedLayoutSegment`, `useSelectedLayoutSegments`, and `useParams` hooks +#### `useSelectedLayoutSegment`, `useSelectedLayoutSegments`, and `useParams` hooks The `useSelectedLayoutSegment`, `useSelectedLayoutSegments`, and `useParams` hooks are supported in Storybook. You have to set the `nextjs.navigation.segments` parameter to return the segments or the params you want to use. @@ -403,7 +363,7 @@ export default function ParamsBasedComponent() { The default value of `nextjs.navigation.segments` is `[]` if not set. -### Default navigation context +#### Default navigation context The default values on the stubbed navigation context are as follows: @@ -443,11 +403,13 @@ const preview: Preview = { }; ``` -## Next.js Head +### Next.js Head [`next/head`](https://nextjs.org/docs/pages/api-reference/components/head) is supported out of the box. You can use it in your stories like you would in your Next.js application. Please keep in mind, that the Head `children` are placed into the head element of the iframe that Storybook uses to render your stories. -## Sass/Scss +### Styling + +#### Sass/Scss [Global Sass/Scss stylesheets](https://nextjs.org/docs/pages/building-your-application/styling/sass) are supported without any additional configuration as well. Just import them into [`.storybook/preview.js|ts`](../../configure/index.mdx#configure-story-rendering) @@ -468,7 +430,7 @@ export default { }; ``` -## CSS/Sass/Scss Modules +#### CSS/Sass/Scss Modules [CSS modules](https://nextjs.org/docs/pages/building-your-application/styling/css-modules) work as expected. @@ -488,7 +450,7 @@ export function Button() { } ``` -## Styled JSX +#### Styled JSX The built in CSS-in-JS solution for Next.js is [styled-jsx](https://nextjs.org/docs/pages/building-your-application/styling/css-in-js), and this framework supports that out of the box too, zero config. @@ -542,13 +504,14 @@ You can use your own babel config too. This is an example of how you can customi } ``` -## PostCSS +#### PostCSS Next.js lets you [customize PostCSS config](https://nextjs.org/docs/pages/building-your-application/configuring/post-css). Thus this framework will automatically handle your PostCSS config for you. This allows for cool things like zero-config Tailwind! (See [Next.js' example](https://github.com/vercel/next.js/tree/canary/packages/create-next-app/templates/default-tw)) -## Absolute imports +### Imports +#### Absolute imports [Absolute imports](https://nextjs.org/docs/pages/building-your-application/configuring/absolute-imports-and-module-aliases#absolute-imports) from the root directory are supported. @@ -580,7 +543,7 @@ import 'styles/globals.scss'; Absolute imports **cannot** be mocked in stories/tests. See the [Mocking modules](#mocking-modules) section for more information. -## Module aliases +#### Module aliases [Module aliases](https://nextjs.org/docs/app/building-your-application/configuring/absolute-imports-and-module-aliases#module-aliases) are also supported. @@ -600,7 +563,7 @@ export default function HomePage() { } ``` -## Subpath imports +#### Subpath imports As an alternative to [module aliases](#module-aliases), you can use [subpath imports](https://nodejs.org/api/packages.html#subpath-imports) to import modules. This follows Node package standards and has benefits when [mocking modules](#mocking-modules). @@ -634,11 +597,11 @@ export default function HomePage() { } ``` -## Mocking modules +### Mocking modules Components often depend on modules that are imported into the component file. These can be from external packages or internal to your project. When rendering those components in Storybook or testing them, you may want to [mock those modules](../../writing-stories/mocking-data-and-modules/mocking-modules.mdx) to control and assert their behavior. -### Built-in mocked modules +#### Built-in mocked modules This framework provides mocks for many of Next.js' internal modules: @@ -647,11 +610,11 @@ This framework provides mocks for many of Next.js' internal modules: 3. [`@storybook/nextjs/navigation.mock`](#storybooknextjsnavigationmock) 4. [`@storybook/nextjs/router.mock`](#storybooknextjsroutermock) -### Mocking other modules +#### Mocking other modules To mock other modules, use [automocking](../../writing-stories/mocking-data-and-modules/mocking-modules.mdx#automocking) or one of the [alternative methods](../../writing-stories/mocking-data-and-modules/mocking-modules.mdx#alternative-methods) documented in the mocking modules guide. -## Runtime config +### Runtime config Next.js allows for [Runtime Configuration](https://nextjs.org/docs/pages/api-reference/next-config-js/runtime-configuration) which lets you import a handy `getConfig` function to get certain configuration defined in your `next.config.js` file at runtime. @@ -685,7 +648,7 @@ Calls to `getConfig` would return the following object when called within Storyb } ``` -## Custom Webpack config +### Custom Webpack config Next.js comes with a lot of things for free out of the box like Sass support, but sometimes you add [custom Webpack config modifications to Next.js](https://nextjs.org/docs/pages/api-reference/next-config-js/webpack). This framework takes care of most of the Webpack modifications you would want to add. If Next.js supports a feature out of the box, then that feature will work out of the box in Storybook. If Next.js doesn't support something out of the box, but makes it easy to configure, then this framework will do the same for that thing for Storybook. @@ -701,7 +664,7 @@ Below is an example of how to add SVGR support to Storybook with this framework. {/* prettier-ignore-end */} -## Typescript +### Typescript Storybook handles most [Typescript](https://www.typescriptlang.org/) configurations, but this framework adds additional support for Next.js's support for [Absolute Imports and Module path aliases](https://nextjs.org/docs/pages/building-your-application/configuring/absolute-imports-and-module-aliases). In short, it takes into account your `tsconfig.json`'s [baseUrl](https://www.typescriptlang.org/tsconfig#baseUrl) and [paths](https://www.typescriptlang.org/tsconfig#paths). Thus, a `tsconfig.json` like the one below would work out of the box. @@ -716,7 +679,7 @@ Storybook handles most [Typescript](https://www.typescriptlang.org/) configurati } ``` -## React Server Components (RSC) +### React Server Components (RSC) (⚠️ **Experimental**) @@ -765,6 +728,36 @@ This is because those versions of Yarn have different package resolution rules t ## FAQ +### How do I manually install the Next.js framework? + +First, install the framework: + +{/* prettier-ignore-start */} + + + +{/* prettier-ignore-end */} + +Then, update your `.storybook/main.js|ts` to change the framework property: + +{/* prettier-ignore-start */} + + + +{/* prettier-ignore-end */} + +Finally, if you were using Storybook plugins to integrate with Next.js, those are no longer necessary when using this framework and can be removed: + +{/* prettier-ignore-start */} + + + +{/* prettier-ignore-end */} + +### How do I migrate to the Next.js Vite framework? + +Please refer to the [migration instructions for `@storybook/nextjs-vite`](./nextjs-vite.mdx#how-do-i-migrate-from-the-nextjs-webpack-5-addon). + ### Stories for pages/components which fetch data Next.js pages can fetch data directly within server components in the `app` directory, which often include module imports that only run in a node environment. This does not (currently) work within Storybook, because if you import from a Next.js page file containing those node module imports in your stories, your Storybook's Webpack will crash because those modules will not run in a browser. To get around this, you can extract the component in your page file into a separate file and import that pure component in your stories. Or, if that's not feasible for some reason, you can [polyfill those modules](https://webpack.js.org/configuration/node/) in your Storybook's [`webpackFinal` configuration](../../builders/webpack.mdx#extending-storybooks-webpack-config). diff --git a/docs/get-started/frameworks/preact-vite.mdx b/docs/get-started/frameworks/preact-vite.mdx index 0446cb48d8d0..7926b069e2bf 100644 --- a/docs/get-started/frameworks/preact-vite.mdx +++ b/docs/get-started/frameworks/preact-vite.mdx @@ -6,46 +6,34 @@ sidebar: title: Preact (Vite) --- -Storybook for Preact & Vite is a [framework](../../contribute/framework.mdx) that makes it easy to develop and test UI components in isolation for [Preact](https://preactjs.com/) applications built with [Vite](https://vitejs.dev/). It includes: +Storybook for Preact & Vite is a [framework](../../contribute/framework.mdx) that makes it easy to develop and test UI components in isolation for [Preact](https://preactjs.com/) applications built with [Vite](https://vitejs.dev/). -* 🏎️ Pre-bundled for performance -* πŸͺ„ Zero config -* πŸ’« and more! +## Install -## Requirements +To install Storybook in an existing Preact project, run this command in your project's root directory: -* Preact 8.x || 10.x -* Vite β‰₯ 5.0 + -## Getting started +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). -### In a project without Storybook +Storybook is compatible with Preact 8.x or 10.x, and Vite β‰₯ 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to better integrate Storybook with your Preact project. -Follow the prompts after running this command in your Preact project's root directory: -{/* prettier-ignore-start */} - - - -{/* prettier-ignore-end */} +## Run Storybook -[More on getting started with Storybook.](../install.mdx) +To run Storybook for a particular project, run the following: -### In a project with Storybook + -This framework is designed to work with Storybook 7+. If you’re not already using v7, upgrade with this command: +To build Storybook, run: -{/* prettier-ignore-start */} - - - -{/* prettier-ignore-end */} + -#### Automatic migration +You will find the output in the configured `outputDir` (default is `storybook-static`). -When running the `upgrade` command above, you should get a prompt asking you to migrate to `@storybook/preact-vite`, which should handle everything for you. In case that auto-migration does not work for your project, refer to the manual migration below. -#### Manual migration +## FAQ +### How do I manually install the Preact framework? First, install the framework: diff --git a/docs/get-started/frameworks/react-native-web-vite.mdx b/docs/get-started/frameworks/react-native-web-vite.mdx index 8d1acd47b1ca..a4e456392cd1 100644 --- a/docs/get-started/frameworks/react-native-web-vite.mdx +++ b/docs/get-started/frameworks/react-native-web-vite.mdx @@ -6,101 +6,40 @@ sidebar: title: React Native Web --- -Storybook for React Native Web is a [framework](../../contribute/framework.mdx) that makes it easy to develop and test UI components in isolation for [React Native](https://reactnative.dev/) applications. It uses [Vite](https://vitejs.dev/) to build your components for web browsers. The framework includes: - -* βš›οΈ React Native components -* πŸ§‘β€πŸ’» Shareable on the web -* πŸͺ„ Zero config -* πŸ’« and more! +Storybook for React Native Web is a [framework](../../contribute/framework.mdx) that makes it easy to develop and test UI components in isolation for [React Native](https://reactnative.dev/). It uses [Vite](https://vitejs.dev/) to build your components for web browsers. In addition to React Native Web, Storybook supports on-device [React Native](https://github.com/storybookjs/react-native) development. If you're unsure what's right for you, read our [comparison](#react-native-vs-react-native-web). -## Requirements - -* React-Native β‰₯ 0.72 -* React-Native-Web β‰₯ 0.19 -* Vite β‰₯ 5.0 - -## Getting started - -### In a project without Storybook - -When you run `storybook init` in your React Native project, Storybook will detect your project and present you with a prompt to choose which type of Storybook you want to install: - -**React Native options:** - -- **"React Native"**: Storybook on your device/simulator - - High-fidelity, runs in your actual React Native application - - Limited feature set compared to web version - - Best for projects that rely on native modules or device-specific features - -- **"React Native Web"**: Storybook on web for docs, test, and sharing - - Feature-rich web-based Storybook - - Full support for documentation, testing, and accessibility features - - Best for projects that want web-based sharing and testing - -- **"Both"**: Add both native and web Storybooks - - Installs and configures both environments - - Allows you to run Storybook for both native and web in the same project - - Best for projects that want both native fidelity and web features - -Follow the prompts after running this command in your React Native project's root directory: - -{/* prettier-ignore-start */} - - - -{/* prettier-ignore-end */} - -[More on getting started with Storybook.](../install.mdx) - -### In a project with Storybook `addon-react-native-web` - -The [React Native Web addon](https://github.com/storybookjs/addon-react-native-web) was a Webpack-based precursor to the React Native Web Vite framework (i.e., `@storybook/react-native-web-vite`). If you're using the addon, you should migrate to the framework, which is faster, more stable, maintained, and better documented. To do so, follow the steps below. - -Run the following command to upgrade Storybook to the latest version: -{/* prettier-ignore-start */} - -{/* prettier-ignore-end */} - - This framework is designed to work with Storybook 8.5 and above for the best experience. We won't be able to provide support if you're using an older Storybook version. - +## Install -Install the framework and its peer dependencies: +To install Storybook in an existing React project, run this command in your project's root directory: -{/* prettier-ignore-start */} + - +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). -{/* prettier-ignore-end */} +Storybook is compatible with React Native β‰₯ 0.72, [React Native Web](https://necolas.github.io/react-native-web/) β‰₯ 0.19, and Vite β‰₯ 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to better integrate Storybook with your React project. -Update your `.storybook/main.js|ts` to change the framework property and remove the `@storybook/addon-react-native-web` addon: -{/* prettier-ignore-start */} +## Run Storybook - - -{/* prettier-ignore-end */} - -Finally, remove the addon and similar packages (i.e., `@storybook/react-webpack5` and `@storybook/addon-react-native-web`) from your project. +To run Storybook for a particular project, run the following: -### In a project with Storybook `react-native` + -[Storybook for React Native](https://github.com/storybookjs/react-native) is a framework that runs in a simulator or on your mobile device. It's possible to run React Native Web alongside React Native, but we are still working on a seamless integration. In the meantime, we recommend running one or the other. If you need help figuring out what's right for you, read our [comparison](#react-native-vs-react-native-web). +To build Storybook, run: -## Run the Setup Wizard + -If all goes well, you should see a setup wizard that will help you get started with Storybook. The wizard will introduce you to the main concepts and features, including how the UI is organized, how to write your first story, and how to test your components' response to various inputs utilizing [controls](../../essentials/controls.mdx). +You will find the output in the configured `outputDir` (default is `storybook-static`). -![Storybook onboarding](../../_assets/get-started/example-onboarding-wizard.png) -If you skipped the wizard, you can always run it again by adding the `?path=/onboarding` query parameter to the URL of your Storybook instance, provided that the example stories are still available. ## React Native vs React Native Web @@ -133,7 +72,8 @@ So, which option is right for you? **Both.** It’s also possible to use both options together. This increases Storybook’s install footprint but is a good option if you want native fidelity in addition to all of the web features. Learn more below. -## Using both React Native and React Native Web + +### Using both React Native and React Native Web The easiest way to use React Native and React Native Web is to select the **"Both"** option when installing Storybook. This will install and create configurations for both environments, allowing you to run Storybook for both in the same project. @@ -148,6 +88,44 @@ After installation, you'll see instructions for both environments: However, you can install them separately if one version is installed. You can add a React Native Web Storybook alongside an existing React Native Storybook by running the install command and selecting "React Native Web" in the setup wizard, and vice versa. + +## FAQ + +### How do I migrate from the React Native Web addon? + +The [React Native Web addon](https://github.com/storybookjs/addon-react-native-web) was a Webpack-based precursor to the React Native Web Vite framework (i.e., `@storybook/react-native-web-vite`). If you're using the addon, you should migrate to the framework, which is faster, more stable, maintained, and better documented. To do so, follow the steps below. + +Run the following command to upgrade Storybook to the latest version: + +{/* prettier-ignore-start */} + + + +{/* prettier-ignore-end */} + + + This framework is designed to work with Storybook 8.5 and above for the best experience. We won't be able to provide support if you're using an older Storybook version. + + +Install the framework and its peer dependencies: + +{/* prettier-ignore-start */} + + + +{/* prettier-ignore-end */} + +Update your `.storybook/main.js|ts` to change the framework property and remove the `@storybook/addon-react-native-web` addon: + +{/* prettier-ignore-start */} + + + +{/* prettier-ignore-end */} + +Finally, remove the addon and similar packages (i.e., `@storybook/react-webpack5` and `@storybook/addon-react-native-web`) from your project. + + ## API ### Options diff --git a/docs/get-started/frameworks/react-vite.mdx b/docs/get-started/frameworks/react-vite.mdx index 0f57a8115432..3835b0071e69 100644 --- a/docs/get-started/frameworks/react-vite.mdx +++ b/docs/get-started/frameworks/react-vite.mdx @@ -6,34 +6,36 @@ sidebar: title: React (Vite) --- -Storybook for React & Vite is a [framework](../../contribute/framework.mdx) that makes it easy to develop and test UI components in isolation for [React](https://react.dev/) applications built with [Vite](https://vitejs.dev/). It includes: +Storybook for React & Vite is a [framework](../../contribute/framework.mdx) that makes it easy to develop and test UI components in isolation for [React](https://react.dev/) applications built with [Vite](https://vitejs.dev/). -* 🏎️ Pre-bundled for performance -* πŸͺ„ Zero config -* πŸ’« and more! +## Install -## Requirements +To install Storybook in an existing React project, run this command in your project's root directory: -* React β‰₯ 16.8 -* Vite β‰₯ 5.0 + -## Getting started +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). -### In a project without Storybook +Storybook is compatible with React β‰₯ 16.8, and Vite β‰₯ 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to better integrate Storybook with your React project. -Follow the prompts after running this command in your React project's root directory: -{/* prettier-ignore-start */} +## Run Storybook - +To run Storybook for a particular project, run the following: -{/* prettier-ignore-end */} + + +To build Storybook, run: + + + +You will find the output in the configured `outputDir` (default is `storybook-static`). -[More on getting started with Storybook.](../install.mdx) -### In a project with Storybook +## FAQ +### How do I migrate from the React Webpack framework? -This framework is designed to work with Storybook 7+. If you’re not already using v7, upgrade with this command: +The `upgrade` command should prompt you to migrate to `@storybook/react-vite` when you run it: {/* prettier-ignore-start */} @@ -41,11 +43,9 @@ This framework is designed to work with Storybook 7+. If you’re not already us {/* prettier-ignore-end */} -#### Automatic migration +In case that auto-migration does not work for your project, refer to the manual installation instructions below. -When running the `upgrade` command above, you should get a prompt asking you to migrate to `@storybook/react-vite`, which should handle everything for you. In case that auto-migration does not work for your project, refer to the manual migration below. - -#### Manual migration +### How do I manually install the React framework? First, install the framework: @@ -63,13 +63,6 @@ Then, update your `.storybook/main.js|ts` to change the framework property: {/* prettier-ignore-end */} -## Run the Setup Wizard - -If all goes well, you should see a setup wizard that will help you get started with Storybook introducing you to the main concepts and features, including how the UI is organized, how to write your first story, and how to test your components' response to various inputs utilizing [controls](../../essentials/controls.mdx). - -![Storybook onboarding](../../_assets/get-started/example-onboarding-wizard.png) - -If you skipped the wizard, you can always run it again by adding the `?path=/onboarding` query parameter to the URL of your Storybook instance, provided that the example stories are still available. ## API diff --git a/docs/get-started/frameworks/react-webpack5.mdx b/docs/get-started/frameworks/react-webpack5.mdx index 90c9792f5f5a..51ecd509186b 100644 --- a/docs/get-started/frameworks/react-webpack5.mdx +++ b/docs/get-started/frameworks/react-webpack5.mdx @@ -8,40 +8,53 @@ sidebar: Storybook for React & Webpack is a [framework](../../contribute/framework.mdx) that makes it easy to develop and test UI components in isolation for [React](https://react.dev/) applications built with [Webpack](https://webpack.js.org/). -## Requirements + -* React β‰₯ 16.8 -* Webpack β‰₯ 5.0 +**We recommend using [`@storybook/react-vite`](./react-vite.mdx)** for most React projects. The Vite-based framework is faster, more modern, and offers better support for testing features. -## Getting started +Use this Webpack-based framework (`@storybook/react-webpack5`) only if you need specific Webpack features not available in Vite. + -### In a project without Storybook +## Install -Follow the prompts after running this command in your React project's root directory: +To install Storybook in an existing React project, run this command in your project's root directory: -{/* prettier-ignore-start */} + - +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). -{/* prettier-ignore-end */} +Storybook is compatible with React β‰₯ 16.8, and Webpack β‰₯ 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to better integrate Storybook with your React project. -[More on getting started with Storybook.](../install.mdx) -### In a project with Storybook +## Run Storybook -This framework is designed to work with Storybook 7+. If you’re not already using v7, upgrade with this command: +To run Storybook for a particular project, run the following: -{/* prettier-ignore-start */} + - +To build Storybook, run: -{/* prettier-ignore-end */} + + +You will find the output in the configured `outputDir` (default is `storybook-static`). + + +## Configure + +### Create React App (CRA) + +Support for [Create React App](https://create-react-app.dev/) is handled by [`@storybook/preset-create-react-app`](https://github.com/storybookjs/presets/tree/master/packages/preset-create-react-app). + +This preset enables support for all CRA features, including Sass/SCSS and TypeScript. + +### Manually initialized apps + +If you're working on an app that was initialized manually (i.e., without the use of CRA), ensure that your app has [react-dom](https://www.npmjs.com/package/react-dom) included as a dependency. Failing to do so can lead to unforeseen issues with Storybook and your project. -#### Automatic migration -When running the `upgrade` command above, you should get a prompt asking you to migrate to `@storybook/react-webpack5`, which should handle everything for you. In case that auto-migration does not work for your project, refer to the manual migration below. +## FAQ -#### Manual migration +### How do I manually install the React Webpack framework? First, install the framework: @@ -81,21 +94,9 @@ Finally, update your `.storybook/main.js|ts` to change the framework property: {/* prettier-ignore-end */} -## Run the Setup Wizard - -If all goes well, you should see a setup wizard that will help you get started with Storybook introducing you to the main concepts and features, including how the UI is organized, how to write your first story, and how to test your components' response to various inputs utilizing [controls](../../essentials/controls.mdx). - -![Storybook onboarding](../../_assets/get-started/example-onboarding-wizard.png) - -If you skipped the wizard, you can always run it again by adding the `?path=/onboarding` query parameter to the URL of your Storybook instance, provided that the example stories are still available. +### How do I migrate to the React Vite framework? -## Create React App (CRA) - -Support for [Create React App](https://create-react-app.dev/) is handled by [`@storybook/preset-create-react-app`](https://github.com/storybookjs/presets/tree/master/packages/preset-create-react-app). - -This preset enables support for all CRA features, including Sass/SCSS and TypeScript. - -If you're working on an app that was initialized manually (i.e., without the use of CRA), ensure that your app has [react-dom](https://www.npmjs.com/package/react-dom) included as a dependency. Failing to do so can lead to unforeseen issues with Storybook and your project. +Please refer to the [migration instructions for `@storybook/react-vite`](./react-vite.mdx#how-do-i-migrate-from-the-react-webpack-framework). ## API diff --git a/docs/get-started/frameworks/svelte-vite.mdx b/docs/get-started/frameworks/svelte-vite.mdx index d02e46d9feae..687c03acab09 100644 --- a/docs/get-started/frameworks/svelte-vite.mdx +++ b/docs/get-started/frameworks/svelte-vite.mdx @@ -8,56 +8,30 @@ sidebar: Storybook for Svelte & Vite is a [framework](../../contribute/framework.mdx) that makes it easy to develop and test UI components in isolation for applications using [Svelte](https://svelte.dev/) built with [Vite](https://vitejs.dev/). -## Requirements -* Svelte β‰₯ 5.0 -* Vite β‰₯ 5.0 +## Install -## Getting started +To install Storybook in an existing Svelte project, run this command in your project's root directory: -### In a project without Storybook + -Follow the prompts after running this command in your Svelte project's root directory: +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). -{/* prettier-ignore-start */} - - - -{/* prettier-ignore-end */} +Storybook is compatible with Svelte β‰₯ 5, and Vite β‰₯ 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to better integrate Storybook with your Svelte project. -[More on getting started with Storybook.](../install.mdx) -### In a project with Storybook +## Run Storybook -This framework is designed to work with Storybook 7+. If you’re not already using v7, upgrade with this command: +To run Storybook for a particular project, run the following: -{/* prettier-ignore-start */} + - +To build Storybook, run: -{/* prettier-ignore-end */} - -#### Automatic migration - -When running the `upgrade` command above, you should get a prompt asking you to migrate to `@storybook/svelte-vite`, which should handle everything for you. In case that auto-migration does not work for your project, refer to the manual migration below. - -#### Manual migration - -First, install the framework: - -{/* prettier-ignore-start */} - - - -{/* prettier-ignore-end */} - -Then, update your `.storybook/main.js|ts` to change the framework property: - -{/* prettier-ignore-start */} + - +You will find the output in the configured `outputDir` (default is `storybook-static`). -{/* prettier-ignore-end */} ## Writing native Svelte stories @@ -175,6 +149,27 @@ If you enabled automatic documentation generation with the `autodocs` story prop {/* prettier-ignore-end */} + +## FAQ +### How do I manually install the Svelte framework? + +First, install the framework: + +{/* prettier-ignore-start */} + + + +{/* prettier-ignore-end */} + +Then, update your `.storybook/main.js|ts` to change the framework property: + +{/* prettier-ignore-start */} + + + +{/* prettier-ignore-end */} + + ## API ### Options diff --git a/docs/get-started/frameworks/sveltekit.mdx b/docs/get-started/frameworks/sveltekit.mdx index 47c459b16b4a..94a638b5ec0f 100644 --- a/docs/get-started/frameworks/sveltekit.mdx +++ b/docs/get-started/frameworks/sveltekit.mdx @@ -6,70 +6,37 @@ sidebar: title: SvelteKit --- -Storybook for SvelteKit is a [framework](../../contribute/framework.mdx) that makes it easy to develop and test UI components in isolation for [SvelteKit](https://kit.svelte.dev/) applications. It includes: +Storybook for SvelteKit is a [framework](../../contribute/framework.mdx) that makes it easy to develop and test UI components in isolation for [SvelteKit](https://kit.svelte.dev/) applications. -* πŸͺ„ Zero config -* 🧩 Easily mock many SvelteKit modules -* πŸ”— Automatic link handling -* πŸ’« and more! +## Install -## Requirements +To install Storybook in an existing SvelteKit project, run this command in your project's root directory: -* SvelteKit β‰₯ 1.0 + -## Getting started +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). -### In a project without Storybook +Storybook is compatible with SvelteKit β‰₯ 1.0, and Vite β‰₯ 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to better integrate Storybook with your SvelteKit project. -Follow the prompts after running this command in your Sveltekit project's root directory: -{/* prettier-ignore-start */} - - - -{/* prettier-ignore-end */} - -[More on getting started with Storybook.](../install.mdx) - -### In a project with Storybook - -This framework is designed to work with Storybook 7+. If you’re not already using v7, upgrade with this command: - -{/* prettier-ignore-start */} - - - -{/* prettier-ignore-end */} - -#### Automatic migration - -When running the `upgrade` command above, you should get a prompt asking you to migrate to `@storybook/sveltekit`, which should handle everything for you. In case that auto-migration does not work for your project, refer to the manual migration below. - -#### Manual migration - -First, install the framework: - -{/* prettier-ignore-start */} +## Run Storybook - +To run Storybook for a particular project, run the following: -{/* prettier-ignore-end */} + -Then, update your `.storybook/main.js|ts` to change the framework property: +To build Storybook, run: -{/* prettier-ignore-start */} + - +You will find the output in the configured `outputDir` (default is `storybook-static`). -{/* prettier-ignore-end */} -Finally, these packages are now either obsolete or part of `@storybook/sveltekit`, so you no longer need to depend on them directly. You can remove them (`npm uninstall`, `yarn remove`, `pnpm remove`) from your project: +## Configure -* `@storybook/svelte-vite` -* `storybook-builder-vite` -* `@storybook/builder-vite` +This section covers SvelteKit support and configuration options. -## Supported features +### Supported features All Svelte language features are supported out of the box, as the Storybook framework uses the Svelte compiler directly. However, SvelteKit has some [Kit-specific modules](https://kit.svelte.dev/docs/modules) that aren't supported. Here's a breakdown of what will and will not work within Storybook: @@ -90,7 +57,7 @@ However, SvelteKit has some [Kit-specific modules](https://kit.svelte.dev/docs/m | [`$env/static/private`](https://svelte.dev/docs/kit/$env-static-private) | β›” Not supported | This is a server-side feature, and Storybook renders all components on the client. | | [`$service-worker`](https://svelte.dev/docs/kit/$service-worker) | β›” Not supported | This is a service worker feature, which does not apply to Storybook. | -## How to mock +### How to mock To mock a SvelteKit import you can define it within `parameters.sveltekit_experimental`: @@ -102,7 +69,7 @@ To mock a SvelteKit import you can define it within `parameters.sveltekit_experi The [available parameters](#parameters) are documented in the API section, below. -### Mocking links +#### Mocking links The default link-handling behavior (e.g., when clicking an `` element) is to log an action to the [Actions panel](../../essentials/actions.mdx). @@ -232,6 +199,44 @@ If you enabled automatic documentation generation with the `autodocs` story prop {/* prettier-ignore-end */} +## FAQ + +### How do I manually install the SvelteKit framework? + +First, install the framework: + +{/* prettier-ignore-start */} + + + +{/* prettier-ignore-end */} + +Then, update your `.storybook/main.js|ts` to change the framework property: + +{/* prettier-ignore-start */} + + + +{/* prettier-ignore-end */} + +Finally, these packages are now either obsolete or part of `@storybook/sveltekit`, so you no longer need to depend on them directly. You can remove them (`npm uninstall`, `yarn remove`, `pnpm remove`) from your project: + +* `@storybook/svelte-vite` +* `storybook-builder-vite` +* `@storybook/builder-vite` + + +### Error when starting Storybook + +When starting Storybook after upgrading to v7.0, it may quit with the following error: + +```sh +ERR! SyntaxError: Identifier '__esbuild_register_import_meta_url__' has already been declared +``` + +This can occur when manually upgrading from 6.5 to 7.0. To resolve it, you'll need to remove the `svelteOptions` property in `.storybook/main.js`, as that is not supported (and no longer necessary) in Storybook 7+ with SvelteKit. + + ## API ### Parameters @@ -381,15 +386,3 @@ Enables or disables automatic documentation generation for component properties. #### When to disable docgen Disabling docgen can improve build performance for large projects, but [argTypes won't be inferred automatically](../../api/arg-types.mdx#automatic-argtype-inference), which will prevent features like [Controls](../../essentials/controls.mdx) and [docs](../../writing-docs/autodocs.mdx) from working as expected. To use those features, you will need to [define `argTypes` manually](../../api/arg-types.mdx#manually-specifying-argtypes). - -## Troubleshooting - -### Error when starting Storybook - -When starting Storybook after upgrading to v7.0, it may quit with the following error: - -```sh -ERR! SyntaxError: Identifier '__esbuild_register_import_meta_url__' has already been declared -``` - -This can occur when manually upgrading from 6.5 to 7.0. To resolve it, you'll need to remove the `svelteOptions` property in `.storybook/main.js`, as that is not supported (and no longer necessary) in Storybook 7+ with SvelteKit. diff --git a/docs/get-started/frameworks/vue3-vite.mdx b/docs/get-started/frameworks/vue3-vite.mdx index 85e864bfcc0e..82f8e4307f00 100644 --- a/docs/get-started/frameworks/vue3-vite.mdx +++ b/docs/get-started/frameworks/vue3-vite.mdx @@ -6,65 +6,45 @@ sidebar: title: Vue (Vite) --- -Storybook for Vue & Vite is a [framework](../../contribute/framework.mdx) that makes it easy to develop and test UI components in isolation for [Vue](https://vuejs.org/) applications built with [Vite](https://vitejs.dev/). It includes: +Storybook for Vue & Vite is a [framework](../../contribute/framework.mdx) that makes it easy to develop and test UI components in isolation for [Vue](https://vuejs.org/) applications built with [Vite](https://vitejs.dev/). -* 🏎️ Pre-bundled for performance -* πŸͺ„ Zero config -* 🧠 Comprehensive docgen -* πŸ’« and more! +## Install -## Requirements +To install Storybook in an existing Vue project, run this command in your project's root directory: -* Vue β‰₯ 3 -* Vite β‰₯ 5.0 + -## Getting started +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). -### In a project without Storybook +Storybook is compatible with Vue β‰₯ 3, and Vite β‰₯ 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to better integrate Storybook with your Vue project. -Follow the prompts after running this command in your Vue project's root directory: +## Run Storybook -{/* prettier-ignore-start */} +To run Storybook for a particular project, run the following: - + -{/* prettier-ignore-end */} +To build Storybook, run: -[More on getting started with Storybook.](../install.mdx) + -### In a project with Storybook +You will find the output in the configured `outputDir` (default is `storybook-static`). -This framework is designed to work with Storybook 7+. If you’re not already using v7, upgrade with this command: -{/* prettier-ignore-start */} - -{/* prettier-ignore-end */} -#### Automatic migration -When running the `upgrade` command above, you should get a prompt asking you to migrate to `@storybook/vue3-vite`, which should handle everything for you. In case that auto-migration does not work for your project, refer to the manual migration below. -#### Manual migration -First, install the framework: -{/* prettier-ignore-start */} - -{/* prettier-ignore-end */} +## Configure -Then, update your `.storybook/main.js|ts` to change the framework property: +Storybook for Vue 3 with Vite is designed to work out of the box with minimal configuration. This section covers configuration options for the framework. -{/* prettier-ignore-start */} - - - -{/* prettier-ignore-end */} - -## Extending the Vue application +### Extending the Vue application Storybook creates a [Vue 3 application](https://vuejs.org/api/application.html#application-api) for your component preview. When using global custom components (`app.component`), directives (`app.directive`), extensions (`app.use`), or other application methods, you will need to configure those in the `./storybook/preview.js|ts` file. @@ -82,7 +62,7 @@ setup((app) => { }); ``` -## Using `vue-component-meta` +### Using `vue-component-meta` `vue-component-meta` is only available in Storybook β‰₯ 8. It is currently an opt-in, but it will become the default in a future version of Storybook. @@ -109,13 +89,13 @@ export default config; `vue-component-meta` comes with many benefits and enables more documentation features, such as: -### Support for multiple component types +#### Support for multiple component types `vue-component-meta` supports all types of Vue components (including SFC, functional, composition/options API components) from `.vue`, `.ts`, `.tsx`, `.js`, and `.jsx` files. It also supports both default and named component exports. -### Prop description and JSDoc tag annotations +#### Prop description and JSDoc tag annotations To describe a prop, including tags, you can use JSDoc comments in your component's props definition: @@ -142,7 +122,7 @@ The props definition above will generate the following controls: ![Controls generated from props](../../_assets/get-started/vue-component-meta-prop-types-controls.png) -### Events types extraction +#### Events types extraction To provide a type for an emitted event, you can use TypeScript types (including JSDoc comments) in your component's `defineEmits` call: @@ -167,7 +147,7 @@ Which will generate the following controls: ![Controls generated from events](../../_assets/get-started/vue-component-meta-event-types-controls.png) -### Slots types extraction +#### Slots types extraction The slot types are automatically extracted from your component definition and displayed in the controls panel. @@ -204,7 +184,7 @@ The definition above will generate the following controls: ![Controls generated from slots](../../_assets/get-started/vue-component-meta-slot-types-controls.png) -### Exposed properties and methods +#### Exposed properties and methods The properties and methods exposed by your component are automatically extracted and displayed in the [Controls](../../essentials/controls.mdx) panel. @@ -228,7 +208,7 @@ The definition above will generate the following controls: ![Controls generated from exposed properties and methods](../../_assets/get-started/vue-component-meta-exposed-types-controls.png) -### Override the default configuration +#### Override the default configuration If you're working with a project that relies on [`tsconfig references`](https://www.typescriptlang.org/docs/handbook/project-references.html) to link to other existing configuration files (e.g., `tsconfig.app.json`, `tsconfig.node.json`), we recommend that you update your [`.storybook/main.js|ts`](../../configure/index.mdx) configuration file and add the following: @@ -256,7 +236,27 @@ export default config; Otherwise, you might face missing component types/descriptions or unresolvable import aliases like `@/some/import`. -## Troubleshooting + + +## FAQ + +### How do I manually install the Vue framework? + +First, install the framework: + +{/* prettier-ignore-start */} + + + +{/* prettier-ignore-end */} + +Then, update your `.storybook/main.js|ts` to change the framework property: + +{/* prettier-ignore-start */} + + + +{/* prettier-ignore-end */} ### Storybook doesn't work with my Vue 2 project @@ -268,6 +268,9 @@ Otherwise, you might face missing component types/descriptions or unresolvable i {/* prettier-ignore-end */} + + + ## API ### Options diff --git a/docs/get-started/frameworks/web-components-vite.mdx b/docs/get-started/frameworks/web-components-vite.mdx index 91705283d339..ab9621c4456f 100644 --- a/docs/get-started/frameworks/web-components-vite.mdx +++ b/docs/get-started/frameworks/web-components-vite.mdx @@ -8,39 +8,32 @@ sidebar: Storybook for Web components & Vite is a [framework](../../contribute/framework.mdx) that makes it easy to develop and test UI components in isolation for applications using [Web components](https://www.webcomponents.org/introduction) built with [Vite](https://vitejs.dev/). -## Requirements -* Vite β‰₯ 5.0 +## Install -## Getting started +To install Storybook in an existing project, run this command in your project's root directory: -### In a project without Storybook + -Follow the prompts after running this command in your Web components project's root directory: +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). -{/* prettier-ignore-start */} - - +Storybook is compatible with Vite β‰₯ 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to better integrate Storybook with your project. -{/* prettier-ignore-end */} +## Run Storybook -[More on getting started with Storybook.](../install.mdx) +To run Storybook for a particular project, run the following: -### In a project with Storybook + -This framework is designed to work with Storybook 7+. If you’re not already using v7, upgrade with this command: +To build Storybook, run: -{/* prettier-ignore-start */} - - - -{/* prettier-ignore-end */} + -#### Automatic migration +You will find the output in the configured `outputDir` (default is `storybook-static`). -When running the `upgrade` command above, you should get a prompt asking you to migrate to `@storybook/web-components-vite`, which should handle everything for you. In case that auto-migration does not work for your project, refer to the manual migration below. -#### Manual migration +## FAQ +### How do I manually install the Web Components framework? First, install the framework: From a9ea6de068447b0dd65f747c272c917c6d90c477 Mon Sep 17 00:00:00 2001 From: Steve Dodier-Lazaro Date: Tue, 25 Nov 2025 13:29:00 +0100 Subject: [PATCH 04/12] Update docs/get-started/frameworks/react-native-web-vite.mdx Co-authored-by: Michael Shilman --- docs/get-started/frameworks/react-native-web-vite.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/get-started/frameworks/react-native-web-vite.mdx b/docs/get-started/frameworks/react-native-web-vite.mdx index a4e456392cd1..e88474000611 100644 --- a/docs/get-started/frameworks/react-native-web-vite.mdx +++ b/docs/get-started/frameworks/react-native-web-vite.mdx @@ -18,7 +18,7 @@ Storybook for React Native Web is a [framework](../../contribute/framework.mdx) ## Install -To install Storybook in an existing React project, run this command in your project's root directory: +To install Storybook in an existing React Native project, run this command in your project's root directory: From 6a2a2d985373aef91c079fc33bf81d29a259e8f6 Mon Sep 17 00:00:00 2001 From: Steve Dodier-Lazaro Date: Tue, 25 Nov 2025 13:45:32 +0100 Subject: [PATCH 05/12] Docs: Remove FAQ item relating to Storybook 6 --- docs/get-started/frameworks/sveltekit.mdx | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/docs/get-started/frameworks/sveltekit.mdx b/docs/get-started/frameworks/sveltekit.mdx index 94a638b5ec0f..43611c74ef12 100644 --- a/docs/get-started/frameworks/sveltekit.mdx +++ b/docs/get-started/frameworks/sveltekit.mdx @@ -226,17 +226,6 @@ Finally, these packages are now either obsolete or part of `@storybook/sveltekit * `@storybook/builder-vite` -### Error when starting Storybook - -When starting Storybook after upgrading to v7.0, it may quit with the following error: - -```sh -ERR! SyntaxError: Identifier '__esbuild_register_import_meta_url__' has already been declared -``` - -This can occur when manually upgrading from 6.5 to 7.0. To resolve it, you'll need to remove the `svelteOptions` property in `.storybook/main.js`, as that is not supported (and no longer necessary) in Storybook 7+ with SvelteKit. - - ## API ### Parameters From 97cd4400c8475af6de13bc57b53e42a5f588037c Mon Sep 17 00:00:00 2001 From: Steve Dodier-Lazaro Date: Wed, 26 Nov 2025 10:35:02 +0100 Subject: [PATCH 06/12] Docs: Make version compat more visible in framework docs --- docs/get-started/frameworks/angular.mdx | 17 +++++++++++---- docs/get-started/frameworks/nextjs-vite.mdx | 14 +++++++++++-- docs/get-started/frameworks/nextjs.mdx | 13 ++++++++++-- docs/get-started/frameworks/preact-vite.mdx | 16 +++++++++++--- .../frameworks/react-native-web-vite.mdx | 21 ++++++++++++++++--- docs/get-started/frameworks/react-vite.mdx | 15 +++++++++++-- .../get-started/frameworks/react-webpack5.mdx | 16 +++++++++++--- docs/get-started/frameworks/svelte-vite.mdx | 16 +++++++++++--- docs/get-started/frameworks/sveltekit.mdx | 16 +++++++++++--- docs/get-started/frameworks/vue3-vite.mdx | 16 +++++++++++--- .../frameworks/web-components-vite.mdx | 11 ++++++++-- 11 files changed, 141 insertions(+), 30 deletions(-) diff --git a/docs/get-started/frameworks/angular.mdx b/docs/get-started/frameworks/angular.mdx index b3af6d068d6d..4cb781c0e66f 100644 --- a/docs/get-started/frameworks/angular.mdx +++ b/docs/get-started/frameworks/angular.mdx @@ -14,10 +14,19 @@ To install Storybook in an existing Angular project, run this command in your pr -You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). - -Storybook is compatible with Angular β‰₯ 18.0 \< 21.0, and Webpack 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to better integrate Storybook with your Angular project. - +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). For more control over the installation process, refer to the [installation guide](/docs/install/). + +### Compatible versions + + ## Run Storybook diff --git a/docs/get-started/frameworks/nextjs-vite.mdx b/docs/get-started/frameworks/nextjs-vite.mdx index 03f4bdb1dd51..982d3e3b4eb7 100644 --- a/docs/get-started/frameworks/nextjs-vite.mdx +++ b/docs/get-started/frameworks/nextjs-vite.mdx @@ -14,10 +14,20 @@ To install Storybook in an existing Next.js project, run this command in your pr -You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). For more control over the installation process, refer to the [installation guide](/docs/install/). -Storybook is compatible with Next.js β‰₯ 14.1 with Vite β‰₯ 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to [configure Storybook](#configure) with your Next.js project. +### Compatible versions + + ## Choose between Vite and Webpack diff --git a/docs/get-started/frameworks/nextjs.mdx b/docs/get-started/frameworks/nextjs.mdx index cff371e8aef4..5740d33007e1 100644 --- a/docs/get-started/frameworks/nextjs.mdx +++ b/docs/get-started/frameworks/nextjs.mdx @@ -27,11 +27,20 @@ To install Storybook in an existing Next.js project, run this command in your pr The command will prompt you to choose between this framework and [`@storybook/nextjs-vite`](./nextjs-vite.mdx). We recommend the Vite-based framework ([learn why](./nextjs-vite.mdx#choose-between-vite-and-webpack)). -You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). For more control over the installation process, refer to the [installation guide](/docs/install/). -Storybook is compatible with Next.js β‰₯ 14.1 with Webpack 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to [configure Storybook](#configure) with your Next.js project. +### Compatible versions + ## Run Storybook diff --git a/docs/get-started/frameworks/preact-vite.mdx b/docs/get-started/frameworks/preact-vite.mdx index 7926b069e2bf..d9eb01cbde5b 100644 --- a/docs/get-started/frameworks/preact-vite.mdx +++ b/docs/get-started/frameworks/preact-vite.mdx @@ -14,9 +14,19 @@ To install Storybook in an existing Preact project, run this command in your pro -You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). - -Storybook is compatible with Preact 8.x or 10.x, and Vite β‰₯ 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to better integrate Storybook with your Preact project. +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). For more control over the installation process, refer to the [installation guide](/docs/install/). + +### Compatible versions + + ## Run Storybook diff --git a/docs/get-started/frameworks/react-native-web-vite.mdx b/docs/get-started/frameworks/react-native-web-vite.mdx index e88474000611..62a200d31211 100644 --- a/docs/get-started/frameworks/react-native-web-vite.mdx +++ b/docs/get-started/frameworks/react-native-web-vite.mdx @@ -22,9 +22,24 @@ To install Storybook in an existing React Native project, run this command in yo -You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). - -Storybook is compatible with React Native β‰₯ 0.72, [React Native Web](https://necolas.github.io/react-native-web/) β‰₯ 0.19, and Vite β‰₯ 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to better integrate Storybook with your React project. +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). For more control over the installation process, refer to the [installation guide](/docs/install/). + + +### Compatible versions + + ## Run Storybook diff --git a/docs/get-started/frameworks/react-vite.mdx b/docs/get-started/frameworks/react-vite.mdx index 3835b0071e69..654d7751833b 100644 --- a/docs/get-started/frameworks/react-vite.mdx +++ b/docs/get-started/frameworks/react-vite.mdx @@ -14,9 +14,20 @@ To install Storybook in an existing React project, run this command in your proj -You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). For more control over the installation process, refer to the [installation guide](/docs/install/). -Storybook is compatible with React β‰₯ 16.8, and Vite β‰₯ 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to better integrate Storybook with your React project. + +### Compatible versions + + ## Run Storybook diff --git a/docs/get-started/frameworks/react-webpack5.mdx b/docs/get-started/frameworks/react-webpack5.mdx index 51ecd509186b..f66dbdc8e28b 100644 --- a/docs/get-started/frameworks/react-webpack5.mdx +++ b/docs/get-started/frameworks/react-webpack5.mdx @@ -21,9 +21,19 @@ To install Storybook in an existing React project, run this command in your proj -You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). - -Storybook is compatible with React β‰₯ 16.8, and Webpack β‰₯ 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to better integrate Storybook with your React project. +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). For more control over the installation process, refer to the [installation guide](/docs/install/). + +### Compatible versions + + ## Run Storybook diff --git a/docs/get-started/frameworks/svelte-vite.mdx b/docs/get-started/frameworks/svelte-vite.mdx index 687c03acab09..80194f1b6cbe 100644 --- a/docs/get-started/frameworks/svelte-vite.mdx +++ b/docs/get-started/frameworks/svelte-vite.mdx @@ -15,9 +15,19 @@ To install Storybook in an existing Svelte project, run this command in your pro -You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). - -Storybook is compatible with Svelte β‰₯ 5, and Vite β‰₯ 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to better integrate Storybook with your Svelte project. +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). For more control over the installation process, refer to the [installation guide](/docs/install/). + +### Compatible versions + + ## Run Storybook diff --git a/docs/get-started/frameworks/sveltekit.mdx b/docs/get-started/frameworks/sveltekit.mdx index 43611c74ef12..4231e62c2a07 100644 --- a/docs/get-started/frameworks/sveltekit.mdx +++ b/docs/get-started/frameworks/sveltekit.mdx @@ -14,9 +14,19 @@ To install Storybook in an existing SvelteKit project, run this command in your -You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). - -Storybook is compatible with SvelteKit β‰₯ 1.0, and Vite β‰₯ 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to better integrate Storybook with your SvelteKit project. +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). For more control over the installation process, refer to the [installation guide](/docs/install/). + +### Compatible versions + + ## Run Storybook diff --git a/docs/get-started/frameworks/vue3-vite.mdx b/docs/get-started/frameworks/vue3-vite.mdx index 82f8e4307f00..ff95e0b60d49 100644 --- a/docs/get-started/frameworks/vue3-vite.mdx +++ b/docs/get-started/frameworks/vue3-vite.mdx @@ -14,9 +14,19 @@ To install Storybook in an existing Vue project, run this command in your projec -You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). - -Storybook is compatible with Vue β‰₯ 3, and Vite β‰₯ 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to better integrate Storybook with your Vue project. +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). For more control over the installation process, refer to the [installation guide](/docs/install/). + +### Compatible versions + + ## Run Storybook diff --git a/docs/get-started/frameworks/web-components-vite.mdx b/docs/get-started/frameworks/web-components-vite.mdx index ab9621c4456f..a88ddd769b59 100644 --- a/docs/get-started/frameworks/web-components-vite.mdx +++ b/docs/get-started/frameworks/web-components-vite.mdx @@ -15,9 +15,16 @@ To install Storybook in an existing project, run this command in your project's -You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). +You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). For more control over the installation process, refer to the [installation guide](/docs/install/). + +### Compatible versions + + -Storybook is compatible with Vite β‰₯ 5. For more control over the installation process, refer to the [installation guide](/docs/install/). Keep reading to learn how to better integrate Storybook with your project. ## Run Storybook From c1794fcf2290af995c4a68e993339e4cda4f0dac Mon Sep 17 00:00:00 2001 From: Steve Dodier-Lazaro Date: Wed, 26 Nov 2025 18:18:56 +0100 Subject: [PATCH 07/12] Docs: Change requirements headings --- docs/get-started/frameworks/angular.mdx | 2 +- docs/get-started/frameworks/nextjs-vite.mdx | 2 +- docs/get-started/frameworks/nextjs.mdx | 2 +- docs/get-started/frameworks/preact-vite.mdx | 2 +- docs/get-started/frameworks/react-native-web-vite.mdx | 2 +- docs/get-started/frameworks/react-vite.mdx | 2 +- docs/get-started/frameworks/react-webpack5.mdx | 2 +- docs/get-started/frameworks/svelte-vite.mdx | 2 +- docs/get-started/frameworks/sveltekit.mdx | 2 +- docs/get-started/frameworks/vue3-vite.mdx | 2 +- docs/get-started/frameworks/web-components-vite.mdx | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/get-started/frameworks/angular.mdx b/docs/get-started/frameworks/angular.mdx index 4cb781c0e66f..a25d38bd46f8 100644 --- a/docs/get-started/frameworks/angular.mdx +++ b/docs/get-started/frameworks/angular.mdx @@ -16,7 +16,7 @@ To install Storybook in an existing Angular project, run this command in your pr You can then get started [writing stories](/docs/get-started/whats-a-story/), [running tests](/docs/writing-tests/) and [documenting your components](/docs/writing-docs/). For more control over the installation process, refer to the [installation guide](/docs/install/). -### Compatible versions +### Requirements Date: Tue, 2 Dec 2025 09:44:18 +0100 Subject: [PATCH 08/12] remove `nxCloudAccessToken`-field from `nx.json` as discussed with Kasper --- code/nx.json | 1 - 1 file changed, 1 deletion(-) diff --git a/code/nx.json b/code/nx.json index d7dac46f7f19..4c6135c6599a 100644 --- a/code/nx.json +++ b/code/nx.json @@ -1,7 +1,6 @@ { "$schema": "./node_modules/nx/schemas/nx-schema.json", "extends": "nx/presets/npm.json", - "nxCloudAccessToken": "NGVmYTkxMmItYzY3OS00MjkxLTk1ZDktZDFmYTFmNmVlNGY4fHJlYWQ=", "defaultBase": "next", "parallel": 8, "tui": { From 704cfae3c3c05722c758b738baf8d9338d8f0e88 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Sat, 29 Nov 2025 19:10:57 +0100 Subject: [PATCH 09/12] Merge pull request #33229 from storybookjs/valentin/add-init-step-playwright-telemetry Telemetry: Add playwright-prompt (cherry picked from commit 8db6c43d3c815f4c2a4443cdce95b7a5da26af18) --- code/core/src/cli/AddonVitestService.ts | 17 ++++- code/core/src/node-logger/tasks.test.ts | 75 +++++++++++++++++++ code/core/src/node-logger/tasks.ts | 10 ++- .../AddonConfigurationCommand.test.ts | 36 +++------ .../src/commands/AddonConfigurationCommand.ts | 31 +++++--- .../src/services/TelemetryService.ts | 12 ++- 6 files changed, 134 insertions(+), 47 deletions(-) create mode 100644 code/core/src/node-logger/tasks.test.ts diff --git a/code/core/src/cli/AddonVitestService.ts b/code/core/src/cli/AddonVitestService.ts index ae2218306a47..b4c2a8e64c5f 100644 --- a/code/core/src/cli/AddonVitestService.ts +++ b/code/core/src/cli/AddonVitestService.ts @@ -114,12 +114,16 @@ export class AddonVitestService { * @param options - Installation options * @returns Array of error messages if installation fails */ - async installPlaywright(options: { yes?: boolean } = {}): Promise<{ errors: string[] }> { + async installPlaywright( + options: { yes?: boolean } = {} + ): Promise<{ errors: string[]; result: 'installed' | 'skipped' | 'aborted' | 'failed' }> { const errors: string[] = []; const playwrightCommand = ['playwright', 'install', 'chromium', '--with-deps']; const playwrightCommandString = this.packageManager.getPackageCommand(playwrightCommand); + let result: 'installed' | 'skipped' | 'aborted' | 'failed'; + try { const shouldBeInstalled = options.yes ? true @@ -135,7 +139,7 @@ export class AddonVitestService { })(); if (shouldBeInstalled) { - await prompt.executeTaskWithSpinner( + const processAborted = await prompt.executeTaskWithSpinner( (signal) => this.packageManager.runPackageCommand({ args: playwrightCommand, @@ -150,10 +154,17 @@ export class AddonVitestService { abortable: true, } ); + if (processAborted) { + result = 'aborted'; + } else { + result = 'installed'; + } } else { logger.warn('Playwright installation skipped'); + result = 'skipped'; } } catch (e) { + result = 'failed'; ErrorCollector.addError(e); if (e instanceof Error) { errors.push(e.stack ?? e.message); @@ -162,7 +173,7 @@ export class AddonVitestService { } } - return { errors }; + return { errors, result }; } /** diff --git a/code/core/src/node-logger/tasks.test.ts b/code/core/src/node-logger/tasks.test.ts new file mode 100644 index 000000000000..fd546e46d2dc --- /dev/null +++ b/code/core/src/node-logger/tasks.test.ts @@ -0,0 +1,75 @@ +import { describe, expect, it, vi } from 'vitest'; + +// eslint-disable-next-line depend/ban-dependencies +import type { ExecaChildProcess } from 'execa'; + +import { executeTaskWithSpinner } from './tasks'; + +// Create a minimal fake ExecaChildProcess +const makeChild = (onStart?: (cp: Partial) => void): ExecaChildProcess => { + const listeners: Record = {}; + const stdout = { + on: vi.fn((event: string, cb: (data: Buffer) => void) => { + listeners[event] ||= []; + listeners[event].push(cb); + }), + } as any; + + const cp: Partial = { + stdout: stdout as any, + then: undefined as any, + catch: undefined as any, + finally: undefined as any, + }; + + const promise = Promise.resolve() as any; + Object.setPrototypeOf(cp, promise); + (cp as any).then = promise.then.bind(promise); + (cp as any).catch = promise.catch.bind(promise); + (cp as any).finally = promise.finally.bind(promise); + + onStart?.(cp); + return cp as ExecaChildProcess; +}; + +describe('executeTaskWithSpinner', () => { + it('returns "aborted" when the child process rejects with an abort error', async () => { + const outcome = await executeTaskWithSpinner(() => makeChild(), { + id: 'test', + intro: 'Intro', + error: 'Error', + success: 'Success', + abortable: true, + }); + + // Non-abort path returns undefined + expect(outcome).toBeUndefined(); + + // Simulate an aborted child process by rejecting with an abort-like error message + const outcome2 = await executeTaskWithSpinner( + () => { + const err = new Error('The operation was aborted'); + const p = Promise.reject(err); + // Avoid unhandled rejection warnings + p.catch(() => {}); + const cp: any = makeChild(); + // Make the thenable reject + const rejected = p as any; + Object.setPrototypeOf(cp, rejected); + cp.then = rejected.then.bind(rejected); + cp.catch = rejected.catch.bind(rejected); + cp.finally = rejected.finally.bind(rejected); + return cp; + }, + { + id: 'test2', + intro: 'Intro', + error: 'Error', + success: 'Success', + abortable: true, + } + ); + + expect(outcome2).toBe('aborted'); + }); +}); diff --git a/code/core/src/node-logger/tasks.ts b/code/core/src/node-logger/tasks.ts index de9ed3192521..ae63d2997fed 100644 --- a/code/core/src/node-logger/tasks.ts +++ b/code/core/src/node-logger/tasks.ts @@ -61,7 +61,7 @@ export const executeTask = async ( success, abortable = false, }: { intro: string; error: string; success: string; abortable?: boolean } -) => { +): Promise<'aborted' | void> => { logTracker.addLog('info', intro); log(intro); @@ -99,7 +99,7 @@ export const executeTask = async ( if (isAborted) { logTracker.addLog('info', `${intro} aborted`); log(CLI_COLORS.error(`${intro} aborted`)); - return; + return 'aborted'; } const errorMessage = err instanceof Error ? (err.stack ?? err.message) : String(err); logTracker.addLog('error', error, { error: errorMessage }); @@ -108,6 +108,7 @@ export const executeTask = async ( } finally { cleanup?.(); } + return undefined; }; export const executeTaskWithSpinner = async ( @@ -119,7 +120,7 @@ export const executeTaskWithSpinner = async ( success, abortable = false, }: { id: string; intro: string; error: string; success: string; abortable?: boolean } -) => { +): Promise<'aborted' | void> => { logTracker.addLog('info', intro); let abortController: AbortController | undefined; @@ -159,7 +160,7 @@ export const executeTaskWithSpinner = async ( if (isAborted) { logTracker.addLog('info', `${intro} aborted`); task.cancel(CLI_COLORS.warning(`${intro} aborted`)); - return; + return 'aborted'; } const errorMessage = err instanceof Error ? (err.stack ?? err.message) : String(err); logTracker.addLog('error', error, { error: errorMessage }); @@ -168,4 +169,5 @@ export const executeTaskWithSpinner = async ( } finally { cleanup?.(); } + return undefined; }; diff --git a/code/lib/create-storybook/src/commands/AddonConfigurationCommand.test.ts b/code/lib/create-storybook/src/commands/AddonConfigurationCommand.test.ts index 113a073b91f1..e4ad291db47d 100644 --- a/code/lib/create-storybook/src/commands/AddonConfigurationCommand.test.ts +++ b/code/lib/create-storybook/src/commands/AddonConfigurationCommand.test.ts @@ -7,9 +7,10 @@ import { AddonConfigurationCommand } from './AddonConfigurationCommand'; vi.mock('storybook/internal/node-logger', { spy: true }); -vi.mock('storybook/internal/cli', () => ({ +vi.mock('storybook/internal/cli', async (actualImport) => ({ + ...(await actualImport()), AddonVitestService: vi.fn().mockImplementation(() => ({ - installPlaywright: vi.fn().mockResolvedValue([]), + installPlaywright: vi.fn().mockResolvedValue({ errors: [] }), })), })); @@ -42,11 +43,14 @@ describe('AddonConfigurationCommand', () => { const { AddonVitestService } = await import('storybook/internal/cli'); mockAddonVitestService = vi.mocked(AddonVitestService as any); const mockInstance = { - installPlaywright: vi.fn().mockResolvedValue([]), + installPlaywright: vi.fn().mockResolvedValue({ errors: [] }), }; - mockAddonVitestService.mockImplementation(() => mockInstance); + mockAddonVitestService.mockImplementation(() => mockInstance as any); - command = new AddonConfigurationCommand(mockPackageManager); + command = new AddonConfigurationCommand(mockPackageManager, { + yes: true, + disableTelemetry: true, + } as any); mockTask = { success: vi.fn(), @@ -64,16 +68,11 @@ describe('AddonConfigurationCommand', () => { describe('execute', () => { it('should skip configuration when no addons are provided', async () => { const addons: string[] = []; - const options = { - packageManager: PackageManagerName.NPM, - features: [], - }; const result = await command.execute({ dependencyInstallationResult: { status: 'success' }, addons, configDir: '.storybook', - options, }); expect(result.status).toBe('success'); @@ -83,17 +82,11 @@ describe('AddonConfigurationCommand', () => { it('should configure test addons when test feature is enabled', async () => { const addons = ['@storybook/addon-a11y', '@storybook/addon-vitest']; - const options = { - packageManager: PackageManagerName.NPM, - features: [], - yes: true, - }; const result = await command.execute({ dependencyInstallationResult: { status: 'success' }, addons, configDir: '.storybook', - options, }); expect(result.status).toBe('success'); @@ -105,10 +98,6 @@ describe('AddonConfigurationCommand', () => { it('should handle configuration errors gracefully', async () => { const addons = ['@storybook/addon-a11y', '@storybook/addon-vitest']; - const options = { - packageManager: PackageManagerName.NPM, - features: [], - }; const error = new Error('Configuration failed'); mockPostinstallAddon.mockRejectedValue(error); @@ -117,7 +106,6 @@ describe('AddonConfigurationCommand', () => { dependencyInstallationResult: { status: 'success' }, addons, configDir: '.storybook', - options, }); expect(result.status).toBe('failed'); @@ -128,17 +116,11 @@ describe('AddonConfigurationCommand', () => { it('should complete successfully with valid configuration', async () => { const addons = ['@storybook/addon-a11y', '@storybook/addon-vitest']; - const options = { - packageManager: PackageManagerName.NPM, - features: [], - yes: true, - }; const result = await command.execute({ dependencyInstallationResult: { status: 'success' }, addons, configDir: '.storybook', - options, }); expect(result.status).toBe('success'); diff --git a/code/lib/create-storybook/src/commands/AddonConfigurationCommand.ts b/code/lib/create-storybook/src/commands/AddonConfigurationCommand.ts index 09c83de32ba4..fced261362fd 100644 --- a/code/lib/create-storybook/src/commands/AddonConfigurationCommand.ts +++ b/code/lib/create-storybook/src/commands/AddonConfigurationCommand.ts @@ -6,6 +6,7 @@ import { ErrorCollector } from 'storybook/internal/telemetry'; import { dedent } from 'ts-dedent'; import type { CommandOptions } from '../generators/types'; +import { TelemetryService } from '../services'; const ADDON_INSTALLATION_INSTRUCTIONS = { '@storybook/addon-vitest': @@ -14,7 +15,6 @@ const ADDON_INSTALLATION_INSTRUCTIONS = { type ExecuteAddonConfigurationParams = { addons: string[]; - options: CommandOptions; configDir?: string; dependencyInstallationResult: { status: 'success' | 'failed' }; }; @@ -35,18 +35,19 @@ export type ExecuteAddonConfigurationResult = { export class AddonConfigurationCommand { constructor( readonly packageManager: JsPackageManager, - private readonly addonVitestService = new AddonVitestService(packageManager) + private readonly commandOptions: CommandOptions, + private readonly addonVitestService = new AddonVitestService(packageManager), + private readonly telemetryService = new TelemetryService(commandOptions.disableTelemetry) ) {} /** Execute addon configuration */ async execute({ - options, addons, configDir, dependencyInstallationResult, }: ExecuteAddonConfigurationParams): Promise { const areDependenciesInstalled = - dependencyInstallationResult.status === 'success' && !options.skipInstall; + dependencyInstallationResult.status === 'success' && !this.commandOptions.skipInstall; if (!areDependenciesInstalled && this.getAddonsWithInstructions(addons).length > 0) { this.logManualAddonInstructions(addons); @@ -58,12 +59,14 @@ export class AddonConfigurationCommand { } try { - const { hasFailures, addonResults } = await this.configureAddons(configDir, addons, options); + const { hasFailures, addonResults } = await this.configureAddons(configDir, addons); if (addonResults.has('@storybook/addon-vitest')) { - await this.addonVitestService.installPlaywright({ - yes: options.yes, + const { result } = await this.addonVitestService.installPlaywright({ + yes: this.commandOptions.yes, }); + // Map outcome to telemetry decision + await this.telemetryService.trackPlaywrightPromptDecision(result); } return { status: hasFailures ? 'failed' : 'success' }; @@ -103,7 +106,7 @@ export class AddonConfigurationCommand { } /** Configure test addons (a11y and vitest) */ - private async configureAddons(configDir: string, addons: string[], options: CommandOptions) { + private async configureAddons(configDir: string, addons: string[]) { // Import postinstallAddon from cli-storybook package const { postinstallAddon } = await import('../../../cli-storybook/src/postinstallAddon'); @@ -123,7 +126,7 @@ export class AddonConfigurationCommand { await postinstallAddon(addon, { packageManager: this.packageManager.type, configDir, - yes: options.yes, + yes: this.commandOptions.yes, skipInstall: true, skipDependencyManagement: true, logger, @@ -161,7 +164,11 @@ export class AddonConfigurationCommand { export const executeAddonConfiguration = ({ packageManager, - ...options -}: ExecuteAddonConfigurationParams & { packageManager: JsPackageManager }) => { - return new AddonConfigurationCommand(packageManager).execute(options); + options, + ...rest +}: ExecuteAddonConfigurationParams & { + packageManager: JsPackageManager; + options: CommandOptions; +}) => { + return new AddonConfigurationCommand(packageManager, options).execute(rest); }; diff --git a/code/lib/create-storybook/src/services/TelemetryService.ts b/code/lib/create-storybook/src/services/TelemetryService.ts index 4d395e6cb33d..6c33af841159 100644 --- a/code/lib/create-storybook/src/services/TelemetryService.ts +++ b/code/lib/create-storybook/src/services/TelemetryService.ts @@ -18,7 +18,7 @@ export class TelemetryService { /** Track a new user check step */ async trackNewUserCheck(newUser: boolean): Promise { - this.runTelemetryIfEnabled('init-step', { + await this.runTelemetryIfEnabled('init-step', { step: 'new-user-check', newUser, }); @@ -32,6 +32,16 @@ export class TelemetryService { }); } + /** Track Playwright prompt decision (install | skip | aborted) */ + async trackPlaywrightPromptDecision( + result: 'installed' | 'skipped' | 'aborted' | 'failed' + ): Promise { + await this.runTelemetryIfEnabled('init-step', { + step: 'playwright-install', + result, + }); + } + /** Track the main init event with all metadata */ async trackInit(data: { projectType: ProjectType; From e9ffbe50cbb22216f73a7526a7d466ac1d2a6501 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Sat, 29 Nov 2025 19:12:11 +0100 Subject: [PATCH 10/12] Merge pull request #33218 from storybookjs/minor-ui-fixes Core: Minor UI fixes (cherry picked from commit c6ff2fb0c34a864a9f0b2161319e92cfa75bfa16) --- .../src/components/components/Popover/PopoverProvider.tsx | 6 +----- .../src/components/components/tooltip/TooltipProvider.tsx | 2 +- .../core/src/manager/components/sidebar/TagsFilterPanel.tsx | 3 ++- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/code/core/src/components/components/Popover/PopoverProvider.tsx b/code/core/src/components/components/Popover/PopoverProvider.tsx index 807cc79d1fb1..7b78a6d31923 100644 --- a/code/core/src/components/components/Popover/PopoverProvider.tsx +++ b/code/core/src/components/components/Popover/PopoverProvider.tsx @@ -87,11 +87,7 @@ export const PopoverProvider = ({ {...props} > {children} - + {tooltip} diff --git a/code/core/src/manager/components/sidebar/TagsFilterPanel.tsx b/code/core/src/manager/components/sidebar/TagsFilterPanel.tsx index f6f15599a6e8..38ec700e1c8c 100644 --- a/code/core/src/manager/components/sidebar/TagsFilterPanel.tsx +++ b/code/core/src/manager/components/sidebar/TagsFilterPanel.tsx @@ -105,7 +105,7 @@ export const TagsFilterPanel = ({ id: `filter-${type}-${id}`, content: ( - + {isExcluded ? : isIncluded ? null : icon} From 907cdfc01e3b0f1e1d912fd81da5078fbd2196c3 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Mon, 1 Dec 2025 16:05:27 +0100 Subject: [PATCH 11/12] Merge pull request #33212 from storybookjs/valentin/angular-loglevel-logfile-handling Angular: Honor --loglevel and --logfile in dev/build (cherry picked from commit 7782cf771350a03da7dde1ea51f79372289c653b) --- code/core/src/bin/core.ts | 12 +++++++---- code/core/src/core-server/withTelemetry.ts | 2 -- code/core/src/node-logger/index.ts | 2 ++ code/core/src/types/modules/core-common.ts | 4 +++- code/frameworks/angular/build-schema.json | 6 +++++- .../src/builders/build-storybook/index.ts | 15 +++++++++++++- .../src/builders/start-storybook/index.ts | 20 ++++++++++++++++++- code/frameworks/angular/start-schema.json | 6 +++++- code/lib/cli-storybook/src/bin/run.ts | 12 +++++++---- code/lib/cli-storybook/src/upgrade.ts | 2 ++ code/lib/create-storybook/src/bin/run.ts | 4 +++- .../src/commands/FinalizationCommand.ts | 6 ++++-- 12 files changed, 73 insertions(+), 18 deletions(-) diff --git a/code/core/src/bin/core.ts b/code/core/src/bin/core.ts index ee757dfd7356..280e1888efe2 100644 --- a/code/core/src/bin/core.ts +++ b/code/core/src/bin/core.ts @@ -27,8 +27,10 @@ addToGlobalContext('cliVersion', version); */ const handleCommandFailure = async (logFilePath: string | boolean): Promise => { - const logFile = await logTracker.writeToFile(logFilePath); - logger.log(`Debug logs are written to: ${logFile}`); + try { + const logFile = await logTracker.writeToFile(logFilePath); + logger.log(`Debug logs are written to: ${logFile}`); + } catch {} logger.outro('Storybook exited with an error'); process.exit(1); }; @@ -66,8 +68,10 @@ const command = (name: string) => }) .hook('postAction', async (command) => { if (logTracker.shouldWriteLogsToFile) { - const logFile = await logTracker.writeToFile(command.getOptionValue('logfile')); - logger.outro(`Debug logs are written to: ${logFile}`); + try { + const logFile = await logTracker.writeToFile(command.getOptionValue('logfile')); + logger.outro(`Debug logs are written to: ${logFile}`); + } catch {} } }); diff --git a/code/core/src/core-server/withTelemetry.ts b/code/core/src/core-server/withTelemetry.ts index 2e0ce5726da8..c0d6deb37815 100644 --- a/code/core/src/core-server/withTelemetry.ts +++ b/code/core/src/core-server/withTelemetry.ts @@ -9,8 +9,6 @@ import { import type { EventType } from 'storybook/internal/telemetry'; import type { CLIOptions } from 'storybook/internal/types'; -import { dedent } from 'ts-dedent'; - import { StorybookError } from '../storybook-error'; type TelemetryOptions = { diff --git a/code/core/src/node-logger/index.ts b/code/core/src/node-logger/index.ts index 0184a017c2e9..ae2de0410ed1 100644 --- a/code/core/src/node-logger/index.ts +++ b/code/core/src/node-logger/index.ts @@ -11,6 +11,8 @@ export { protectUrls, createHyperlink } from './wrap-utils'; export { CLI_COLORS } from './logger/colors'; export { ConsoleLogger, StyledConsoleLogger } from './logger/console'; +export type { LogLevel } from './logger/logger'; + // The default is stderr, which can cause some tools (like rush.js) to think // there are issues with the build: https://github.com/storybookjs/storybook/issues/14621 npmLog.stream = process.stdout; diff --git a/code/core/src/types/modules/core-common.ts b/code/core/src/types/modules/core-common.ts index 3523f60f7f0c..b8f347124a4d 100644 --- a/code/core/src/types/modules/core-common.ts +++ b/code/core/src/types/modules/core-common.ts @@ -2,6 +2,7 @@ import type { FileSystemCache } from 'storybook/internal/common'; import { type StoryIndexGenerator } from 'storybook/internal/core-server'; import { type CsfFile } from 'storybook/internal/csf-tools'; +import type { LogLevel } from 'storybook/internal/node-logger'; import type { Server as HttpServer, IncomingMessage, ServerResponse } from 'http'; import type { Server as NetServer } from 'net'; @@ -173,7 +174,8 @@ export interface CLIBaseOptions { disableTelemetry?: boolean; enableCrashReports?: boolean; configDir?: string; - loglevel?: string; + loglevel?: LogLevel; + logfile?: string | boolean; quiet?: boolean; } diff --git a/code/frameworks/angular/build-schema.json b/code/frameworks/angular/build-schema.json index 9753db540f2d..d3963edc7215 100644 --- a/code/frameworks/angular/build-schema.json +++ b/code/frameworks/angular/build-schema.json @@ -32,7 +32,11 @@ "loglevel": { "type": "string", "description": "Controls level of logging during build. Can be one of: [silly, verbose, info (default), warn, error, silent].", - "pattern": "(silly|verbose|info|warn|silent)" + "pattern": "(trace|debug|info|warn|error|silent)" + }, + "logfile": { + "type": "string", + "description": "If provided, the log output will be written to the specified file path." }, "debugWebpack": { "type": "boolean", diff --git a/code/frameworks/angular/src/builders/build-storybook/index.ts b/code/frameworks/angular/src/builders/build-storybook/index.ts index 191f93a16e31..2f34d7bc3aba 100644 --- a/code/frameworks/angular/src/builders/build-storybook/index.ts +++ b/code/frameworks/angular/src/builders/build-storybook/index.ts @@ -4,7 +4,7 @@ import { getEnvConfig, getProjectRoot, versions } from 'storybook/internal/commo import { buildStaticStandalone, withTelemetry } from 'storybook/internal/core-server'; import { addToGlobalContext } from 'storybook/internal/telemetry'; import type { CLIOptions } from 'storybook/internal/types'; -import { logger } from 'storybook/internal/node-logger'; +import { logger, logTracker } from 'storybook/internal/node-logger'; import type { BuilderContext, @@ -60,6 +60,7 @@ export type StorybookBuilderOptions = JsonObject & { | 'statsJson' | 'disableTelemetry' | 'debugWebpack' + | 'logfile' | 'previewUrl' >; @@ -71,6 +72,14 @@ const commandBuilder: BuilderHandlerFn = async ( options, context ): Promise => { + // Apply logger configuration from builder options + if (options.loglevel) { + logger.setLogLevel(options.loglevel); + } + if (options.logfile) { + logTracker.enableLogWriting(); + } + logger.intro('Building Storybook'); const { tsConfig } = await setup(options, context); @@ -147,6 +156,10 @@ const commandBuilder: BuilderHandlerFn = async ( }; await runInstance({ ...standaloneOptions, mode: 'static' }); + if (logTracker.shouldWriteLogsToFile) { + const logFile = await logTracker.writeToFile(options.logfile as any); + logger.info(`Debug logs are written to: ${logFile}`); + } logger.outro('Storybook build completed successfully'); return { success: true } as BuilderOutput; }; diff --git a/code/frameworks/angular/src/builders/start-storybook/index.ts b/code/frameworks/angular/src/builders/start-storybook/index.ts index 9562ab66ba0c..977dd4cc717f 100644 --- a/code/frameworks/angular/src/builders/start-storybook/index.ts +++ b/code/frameworks/angular/src/builders/start-storybook/index.ts @@ -4,7 +4,7 @@ import { getEnvConfig, getProjectRoot, versions } from 'storybook/internal/commo import { buildDevStandalone, withTelemetry } from 'storybook/internal/core-server'; import { addToGlobalContext } from 'storybook/internal/telemetry'; import type { CLIOptions } from 'storybook/internal/types'; -import { logger } from 'storybook/internal/node-logger'; +import { logger, logTracker } from 'storybook/internal/node-logger'; import type { BuilderContext, @@ -65,6 +65,7 @@ export type StorybookBuilderOptions = JsonObject & { | 'open' | 'docs' | 'debugWebpack' + | 'logfile' | 'webpackStatsJson' | 'statsJson' | 'loglevel' @@ -80,6 +81,14 @@ const commandBuilder: BuilderHandlerFn = ( return new Observable((observer) => { (async () => { try { + // Apply logger configuration from builder options + if (options.loglevel) { + logger.setLogLevel(options.loglevel); + } + if (options.logfile) { + logTracker.enableLogWriting(); + } + logger.intro('Starting Storybook'); const { tsConfig } = await setup(options, context); @@ -187,6 +196,15 @@ const commandBuilder: BuilderHandlerFn = ( // so the dev server continues running. Architect will keep subscribing // until the Observable completes, which allows watch mode to work. } catch (error) { + // Write logs to file on failure when enabled + try { + if (logTracker.shouldWriteLogsToFile) { + try { + const logFile = await logTracker.writeToFile(options.logfile as any); + logger.outro(`Debug logs are written to: ${logFile}`); + } catch {} + } + } catch {} observer.error(error); } })(); diff --git a/code/frameworks/angular/start-schema.json b/code/frameworks/angular/start-schema.json index 84d6bd80861b..ac81c01d6ab0 100644 --- a/code/frameworks/angular/start-schema.json +++ b/code/frameworks/angular/start-schema.json @@ -148,7 +148,11 @@ "loglevel": { "type": "string", "description": "Controls level of logging during build. Can be one of: [silly, verbose, info (default), warn, error, silent].", - "pattern": "(silly|verbose|info|warn|silent)" + "pattern": "(trace|debug|info|warn|error|silent)" + }, + "logfile": { + "type": "string", + "description": "If provided, the log output will be written to the specified file path." }, "sourceMap": { "type": ["boolean", "object"], diff --git a/code/lib/cli-storybook/src/bin/run.ts b/code/lib/cli-storybook/src/bin/run.ts index f0cb4dc9591f..cab65aa2eedf 100644 --- a/code/lib/cli-storybook/src/bin/run.ts +++ b/code/lib/cli-storybook/src/bin/run.ts @@ -36,8 +36,10 @@ const handleCommandFailure = logger.error(String(error)); } - const logFile = await logTracker.writeToFile(logFilePath); - logger.log(`Debug logs are written to: ${logFile}`); + try { + const logFile = await logTracker.writeToFile(logFilePath); + logger.log(`Debug logs are written to: ${logFile}`); + } catch {} logger.outro(''); process.exit(1); }; @@ -79,8 +81,10 @@ const command = (name: string) => }) .hook('postAction', async (command) => { if (logTracker.shouldWriteLogsToFile) { - const logFile = await logTracker.writeToFile(command.getOptionValue('logfile')); - logger.log(`Debug logs are written to: ${logFile}`); + try { + const logFile = await logTracker.writeToFile(command.getOptionValue('logfile')); + logger.log(`Debug logs are written to: ${logFile}`); + } catch {} logger.outro(CLI_COLORS.success('Done!')); } }); diff --git a/code/lib/cli-storybook/src/upgrade.ts b/code/lib/cli-storybook/src/upgrade.ts index 74a9c5d4e404..914f96193620 100644 --- a/code/lib/cli-storybook/src/upgrade.ts +++ b/code/lib/cli-storybook/src/upgrade.ts @@ -7,6 +7,7 @@ import { logger, prompt, } from 'storybook/internal/node-logger'; +import type { LogLevel } from 'storybook/internal/node-logger'; import { UpgradeStorybookToLowerVersionError, UpgradeStorybookUnknownCurrentVersionError, @@ -123,6 +124,7 @@ export type UpgradeOptions = { configDir?: string[]; fixId?: string; skipInstall?: boolean; + loglevel?: LogLevel; logfile?: string | boolean; }; diff --git a/code/lib/create-storybook/src/bin/run.ts b/code/lib/create-storybook/src/bin/run.ts index 977ce2adbeba..322c6370987b 100644 --- a/code/lib/create-storybook/src/bin/run.ts +++ b/code/lib/create-storybook/src/bin/run.ts @@ -104,7 +104,9 @@ const createStorybookProgram = program }) .hook('postAction', async (command) => { if (logTracker.shouldWriteLogsToFile) { - await logTracker.writeToFile(command.getOptionValue('logfile')); + try { + await logTracker.writeToFile(command.getOptionValue('logfile')); + } catch {} } }); diff --git a/code/lib/create-storybook/src/commands/FinalizationCommand.ts b/code/lib/create-storybook/src/commands/FinalizationCommand.ts index 7d3f3aac832c..887851ada2f6 100644 --- a/code/lib/create-storybook/src/commands/FinalizationCommand.ts +++ b/code/lib/create-storybook/src/commands/FinalizationCommand.ts @@ -68,8 +68,10 @@ export class FinalizationCommand { ); this.printNextSteps(storybookCommand); - const logFile = await logTracker.writeToFile(this.logfile); - logger.warn(`Debug logs are written to: ${logFile}`); + try { + const logFile = await logTracker.writeToFile(this.logfile); + logger.warn(`Debug logs are written to: ${logFile}`); + } catch {} } /** Print success message with feature summary */ From 5cad6100628bdcd3e154ceb0ec02979f81909c46 Mon Sep 17 00:00:00 2001 From: storybook-bot <32066757+storybook-bot@users.noreply.github.com> Date: Tue, 2 Dec 2025 08:56:44 +0000 Subject: [PATCH 12/12] Write changelog for 10.1.3 [skip ci] --- CHANGELOG.md | 6 ++++++ code/package.json | 3 ++- docs/versions/latest.json | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6c4897afc1d..9e043a28f046 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 10.1.3 + +- Angular: Honor --loglevel and --logfile in dev/build - [#33212](https://github.com/storybookjs/storybook/pull/33212), thanks @valentinpalkovic! +- Core: Minor UI fixes - [#33218](https://github.com/storybookjs/storybook/pull/33218), thanks @ghengeveld! +- Telemetry: Add playwright-prompt - [#33229](https://github.com/storybookjs/storybook/pull/33229), thanks @valentinpalkovic! + ## 10.1.2 - Checklist: Fix how state changes are reported and drop some completion restrictions - [#33217](https://github.com/storybookjs/storybook/pull/33217), thanks @ghengeveld! diff --git a/code/package.json b/code/package.json index 2ff6d7e1d313..de63316b9de2 100644 --- a/code/package.json +++ b/code/package.json @@ -286,5 +286,6 @@ "Dependency Upgrades" ] ] - } + }, + "deferredNextVersion": "10.1.3" } diff --git a/docs/versions/latest.json b/docs/versions/latest.json index c94791175ebf..9459127b304b 100644 --- a/docs/versions/latest.json +++ b/docs/versions/latest.json @@ -1 +1 @@ -{"version":"10.1.2","info":{"plain":"- Checklist: Fix how state changes are reported and drop some completion restrictions - [#33217](https://github.com/storybookjs/storybook/pull/33217), thanks @ghengeveld!"}} \ No newline at end of file +{"version":"10.1.3","info":{"plain":"- Angular: Honor --loglevel and --logfile in dev/build - [#33212](https://github.com/storybookjs/storybook/pull/33212), thanks @valentinpalkovic!\n- Core: Minor UI fixes - [#33218](https://github.com/storybookjs/storybook/pull/33218), thanks @ghengeveld!\n- Telemetry: Add playwright-prompt - [#33229](https://github.com/storybookjs/storybook/pull/33229), thanks @valentinpalkovic!"}} \ No newline at end of file