diff --git a/code/frameworks/nextjs/README.md b/code/frameworks/nextjs/README.md
index 23f637900ac3..94158fce5b02 100644
--- a/code/frameworks/nextjs/README.md
+++ b/code/frameworks/nextjs/README.md
@@ -1,1059 +1,10 @@
-# Storybook for Next.js
+# Storybook for Next.js
-## Table of Contents
-
-- [Supported Features](#supported-features)
-- [Requirements](#requirements)
-- [Getting Started](#getting-started)
- - [In a project without Storybook](#in-a-project-without-storybook)
- - [In a project with Storybook](#in-a-project-with-storybook)
- - [Automatic migration](#automatic-migration)
- - [Manual migration](#manual-migration)
-- [Documentation](#documentation)
- - [Options](#options)
- - [Next.js's Image Component](#nextjss-image-component)
- - [Local Images](#local-images)
- - [Remote Images](#remote-images)
- - [Next.js Font Optimization](#nextjs-font-optimization)
- - [next/font/google](#nextfontgoogle)
- - [next/font/local](#nextfontlocal)
- - [Not supported features of next/font](#not-supported-features-of-nextfont)
- - [Mocking fonts during testing](#mocking-fonts-during-testing)
- - [Next.js Routing](#nextjs-routing)
- - [Overriding defaults](#overriding-defaults)
- - [Global Defaults](#global-defaults)
- - [Default Router](#default-router)
- - [Actions Integration Caveats](#actions-integration-caveats)
- - [Next.js Navigation](#nextjs-navigation)
- - [Set `nextjs.appDirectory` to `true`](#set-nextjsappdirectory-to-true)
- - [Overriding defaults](#overriding-defaults-1)
- - [Global Defaults](#global-defaults-1)
- - [`useSelectedLayoutSegment` `useSelectedLayoutSegments` and `useParams` hook](#useselectedlayoutsegment-useselectedlayoutsegments-and-useparams-hook)
- - [Default Navigation Context](#default-navigation-context)
- - [Actions Integration Caveats](#actions-integration-caveats-1)
- - [Next.js Head](#nextjs-head)
- - [Sass/Scss](#sassscss)
- - [Css/Sass/Scss Modules](#csssassscss-modules)
- - [Styled JSX](#styled-jsx)
- - [Postcss](#postcss)
- - [Absolute Imports](#absolute-imports)
- - [Runtime Config](#runtime-config)
- - [Custom Webpack Config](#custom-webpack-config)
- - [Typescript](#typescript)
- - [Experimental React Server Components (RSC)](#experimental-react-server-components-rsc)
- - [Notes for Yarn v2 and v3 users](#notes-for-yarn-v2-and-v3-users)
- - [FAQ](#faq)
- - [Stories for pages/components which fetch data](#stories-for-pagescomponents-which-fetch-data)
- - [Statically imported images won't load](#statically-imported-images-wont-load)
- - [Module not found: Error: Can't resolve `package name`](#module-not-found-error-cant-resolve-package-name)
- - [What if I'm using the Vite builder?](#what-if-im-using-the-vite-builder)
-- [Acknowledgements](#acknowledgements)
-
-## Supported Features
-
-π [Next.js's Image Component](#nextjss-image-component)
-
-π [Next.js Font Optimization](#nextjs-font-optimization)
-
-π [Next.js Routing (next/router)](#nextjs-routing)
-
-π [Next.js Head (next/head)](#nextjs-head)
-
-π [Next.js Navigation (next/navigation)](#nextjs-navigation)
-
-π [Sass/Scss](#sassscss)
-
-π [Css/Sass/Scss Modules](#csssassscss-modules)
-
-π [Styled JSX](#styled-jsx)
-
-π [Postcss](#postcss)
-
-π [Absolute Imports](#absolute-imports)
-
-π [Runtime Config](#runtime-config)
-
-π [Custom Webpack Config](#custom-webpack-config)
-
-π [Typescript](#typescript) (already supported out of the box by Storybook)
-
-## Requirements
-
-- [Next.js](https://nextjs.org/) >= 12.x
-- [Storybook](https://storybook.js.org/) >= 7.x
-
-## Getting Started
-
-### In a project without Storybook
-
-Follow the prompts after running this command in your Next.js project's root directory:
-
-```bash
-npx storybook@latest init
-```
-
-[More on getting started with Storybook](https://storybook.js.org/docs/react/get-started/install)
-
-### 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:
-
-```bash
-npx storybook@latest upgrade
-```
-
-#### Automatic migration
-
-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
-
-Install the framework:
-
-```bash
-yarn add --dev @storybook/nextjs
-```
-
-Update your `main.js` to change the framework property:
-
-```js
-// .storybook/main.js
-export default {
- // ...
- framework: {
- // name: '@storybook/react-webpack5', // Remove this
- name: '@storybook/nextjs', // Add this
- },
-};
-```
-
-If you were using Storybook plugins to integrate with Next.js, those are no longer necessary when using this framework and can be removed:
-
-```js
-// .storybook/main.js
-export default {
- // ...
- addons: [
- // ...
- // These can both be removed
- // 'storybook-addon-next',
- // 'storybook-addon-next-router',
- ],
-};
-```
-
-## Documentation
-
-### Options
-
-You can be pass an options object for additional configuration if needed.
-
-For example:
-
-```js
-// .storybook/main.js
-import * as path from 'path';
-
-export default {
- // ...
- framework: {
- name: '@storybook/nextjs',
- options: {
- image: {
- loading: 'eager',
- },
- nextConfigPath: path.resolve(__dirname, '../next.config.js'),
- },
- },
-};
-```
-
-- `image`: Props to pass to every instance of `next/image`
-- `nextConfigPath`: The absolute path to the `next.config.js`
-
-### Next.js's Image Component
-
-[next/image](https://nextjs.org/docs/api-reference/next/image) is [notoriously difficult](https://github.com/vercel/next.js/issues/18393) to get working with Storybook. This framework allows you to use Next.js's `Image` component with no configuration!
-
-#### Local Images
-
-[Local images](https://nextjs.org/docs/basic-features/image-optimization#local-images) work just fine! Keep in mind that this feature was [only added in Next.js v11](https://nextjs.org/blog/next-11#automatic-size-detection-local-images).
-
-```js
-import Image from 'next/image';
-import profilePic from '../public/me.png';
-
-function Home() {
- return (
- <>
-
My Homepage
-
-
Welcome to my homepage!
- >
- );
-}
-```
-
-#### Remote Images
-
-[Remote images](https://nextjs.org/docs/basic-features/image-optimization#remote-images) also work just fine!
-
-```js
-import Image from 'next/image';
-
-export default function Home() {
- return (
- <>
-
My Homepage
-
-
Welcome to my homepage!
- >
- );
-}
-```
-
-### Next.js Font Optimization
-
-[next/font](https://nextjs.org/docs/basic-features/font-optimization) is partially supported in Storybook. The packages `next/font/google` and `next/font/local` are supported.
-
-#### next/font/google
-
-You don't have to do anything. `next/font/google` is supported out of the box.
-
-#### next/font/local
-
-For local fonts you have to define the [src](https://nextjs.org/docs/api-reference/next/font#src) property.
-The path is relative to the directory where the font loader function is called.
-
-If the following component defines your localFont like this:
-
-```js
-// src/components/MyComponent.js
-import localFont from 'next/font/local';
-
-const localRubikStorm = localFont({ src: './fonts/RubikStorm-Regular.ttf' });
-```
-
-You have to tell Storybook where the `fonts` directory is located. 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.
-
-```js
-// .storybook/main.js
-export default {
- ...
- "staticDirs": [
- {
- from: '../src/components/fonts',
- to: 'src/components/fonts'
- }
- ],
-}
-```
-
-#### Not supported features of next/font
-
-The following features are not supported (yet). Support for these features might be planned for the future:
-
-- [Support font loaders configuration in next.config.js](https://nextjs.org/docs/basic-features/font-optimization#specifying-a-subset)
-- [fallback](https://nextjs.org/docs/api-reference/next/font#fallback) option
-- [adjustFontFallback](https://nextjs.org/docs/api-reference/next/font#adjustfontfallback) option
-- [preload](https://nextjs.org/docs/api-reference/next/font#preload) option gets ignored. Storybook handles Font loading its own way.
-- [display](https://nextjs.org/docs/api-reference/next/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
-
-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.
-
-For example, using [GitHub Actions](https://www.chromatic.com/docs/github-actions):
-
-```shell
- - uses: chromaui/action@v1
- env:
- #π the location of mocked fonts to use
- NEXT_FONT_GOOGLE_MOCKED_RESPONSES: ${{ github.workspace }}/mocked-google-fonts.js
- with:
- projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
- token: ${{ secrets.GITHUB_TOKEN }}
-```
-
-Your mocked fonts will look something like this:
-
-```js
-// mocked-google-fonts.js
-//π Mocked responses of google fonts with the URL as the key
-module.exports = {
- 'https://fonts.googleapis.com/css?family=Inter:wght@400;500;600;800&display=block': `
- /* cyrillic-ext */
- @font-face {
- font-family: 'Inter';
- font-style: normal;
- font-weight: 400;
- font-display: block;
- src: url(https://fonts.gstatic.com/s/inter/v12/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZJhiJ-Ek-_EeAmM.woff2) format('woff2');
- unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
- }
- /* more font declarations go here */
- /* latin */
- @font-face {
- font-family: 'Inter';
- font-style: normal;
- font-weight: 400;
- font-display: block;
- src: url(https://fonts.gstatic.com/s/inter/v12/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZ9hiJ-Ek-_EeA.woff2) format('woff2');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
- }`,
-};
-```
-
-### Next.js Routing
-
-[Next.js's router](https://nextjs.org/docs/routing/introduction) is automatically stubbed for you so that when the router is interacted with, all of its interactions are automatically logged to the Actions ctions panel if you have the [Storybook actions addon](https://storybook.js.org/docs/react/essentials/actions).
-
-> When using Next.js 13+, you should only use `next/router` in the `pages` directory. In the `app` directory, it is necessary to use `next/navigation`.
-
-#### Overriding defaults
-
-Per-story overrides can be done by adding a `nextjs.router` property onto the story [parameters](https://storybook.js.org/docs/react/writing-stories/parameters). The framework will shallowly merge whatever you put here into the router.
-
-```js
-// SomeComponentThatUsesTheRouter.stories.js
-import SomeComponentThatUsesTheRouter from './SomeComponentThatUsesTheRouter';
-
-export default {
- component: SomeComponentThatUsesTheRouter,
-};
-
-// If you have the actions addon,
-// you can interact with the links and see the route change events there
-export const Example = {
- parameters: {
- nextjs: {
- router: {
- pathname: '/profile/[id]',
- asPath: '/profile/1',
- query: {
- id: '1',
- },
- },
- },
- },
-};
-```
-
-#### Global Defaults
-
-Global defaults can be set in [preview.js](https://storybook.js.org/docs/react/configure/#configure-story-rendering) and will be shallowly merged with the default router.
-
-```js
-// .storybook/preview.js
-
-export const parameters = {
- nextjs: {
- router: {
- pathname: '/some-default-path',
- asPath: '/some-default-path',
- query: {},
- },
- },
-};
-```
-
-#### Default Router
-
-The default values on the stubbed router are as follows (see [globals](https://storybook.js.org/docs/react/essentials/toolbars-and-globals#globals) for more details on how globals work)
-
-```ts
-const defaultRouter = {
- push(...args) {
- action('nextRouter.push')(...args);
- return Promise.resolve(true);
- },
- replace(...args) {
- action('nextRouter.replace')(...args);
- return Promise.resolve(true);
- },
- reload(...args) {
- action('nextRouter.reload')(...args);
- },
- back(...args) {
- action('nextRouter.back')(...args);
- },
- forward() {
- action('nextRouter.forward')();
- },
- prefetch(...args) {
- action('nextRouter.prefetch')(...args);
- return Promise.resolve();
- },
- beforePopState(...args) {
- action('nextRouter.beforePopState')(...args);
- },
- events: {
- on(...args) {
- action('nextRouter.events.on')(...args);
- },
- off(...args) {
- action('nextRouter.events.off')(...args);
- },
- emit(...args) {
- action('nextRouter.events.emit')(...args);
- },
- },
- // The locale should be configured [globally](https://storybook.js.org/docs/react/essentials/toolbars-and-globals#globals)
- locale: globals?.locale,
- asPath: '/',
- basePath: '/',
- isFallback: false,
- isLocaleDomain: false,
- isReady: true,
- isPreview: false,
- route: '/',
- pathname: '/',
- query: {},
-};
-```
-
-#### Actions Integration Caveats
-
-If you override a function, you lose the automatic actions integration and have to build it out yourself.
-
-```js
-// .storybook/preview.js
-
-export const parameters = {
- nextjs: {
- router: {
- push() {
- // The default implementation that logs the action into the Actions panel is lost
- },
- },
- },
-};
-```
-
-Doing this yourself looks something like this (make sure you install the `@storybook/addon-actions` package):
-
-```js
-// .storybook/preview.js
-import { action } from '@storybook/addon-actions';
-
-export const parameters = {
- nextjs: {
- router: {
- push(...args) {
- // Custom logic can go here
- // This logs to the Actions panel
- action('nextRouter.push')(...args);
- // Return whatever you want here
- return Promise.resolve(true);
- },
- },
- },
-};
-```
-
-### Next.js Navigation
-
-> Please note that [next/navigation](https://beta.nextjs.org/docs/upgrade-guide#step-5-migrating-routing-hooks) can only be used in components/pages in the `app` directory of Next.js 13+.
-
-#### 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 your Story:
-
-```js
-// SomeComponentThatUsesTheRouter.stories.js
-import SomeComponentThatUsesTheNavigation from './SomeComponentThatUsesTheNavigation';
-
-export default {
- component: SomeComponentThatUsesTheNavigation,
-};
-
-export const Example = {
- parameters: {
- nextjs: {
- appDirectory: true,
- },
- },
-},
-```
-
-If your Next.js project uses the `app` directory for every page (in other words, it does not have a `pages` directory), you can set the parameter `nextjs.appDirectory` to `true` in the [preview.js](https://storybook.js.org/docs/react/configure/#configure-story-rendering) file to apply it to all stories.
-
-```js
-// .storybook/preview.js
-
-export const parameters = {
- nextjs: {
- appDirectory: true,
- },
-};
-```
-
-The parameter `nextjs.appDirectory` defaults to `false` if not set.
-
-#### Overriding defaults
-
-Per-story overrides can be done by adding a `nextjs.navigation` property onto the story [parameters](https://storybook.js.org/docs/react/writing-stories/parameters). The framework will shallowly merge whatever you put here into the router.
-
-```js
-// SomeComponentThatUsesTheNavigation.stories.js
-import SomeComponentThatUsesTheNavigation from './SomeComponentThatUsesTheNavigation';
-
-export default {
- component: SomeComponentThatUsesTheNavigation,
-};
-
-// If you have the actions addon,
-// you can interact with the links and see the route change events there
-export const Example = {
- parameters: {
- nextjs: {
- appDirectory: true,
- navigation: {
- pathname: '/profile',
- query: {
- user: '1',
- },
- },
- },
- },
-};
-```
-
-#### Global Defaults
-
-Global defaults can be set in [preview.js](https://storybook.js.org/docs/react/configure/#configure-story-rendering) and will be shallowly merged with the default router.
-
-```js
-// .storybook/preview.js
-
-export const parameters = {
- nextjs: {
- appDirectory: true,
- navigation: {
- pathname: '/some-default-path',
- },
- },
-};
-```
-
-#### `useSelectedLayoutSegment` `useSelectedLayoutSegments` and `useParams` hook
-
-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.
-
-```js
-// SomeComponentThatUsesTheNavigation.stories.js
-import SomeComponentThatUsesTheNavigation from './SomeComponentThatUsesTheNavigation';
-
-export default {
- component: SomeComponentThatUsesTheNavigation,
- parameters: {
- nextjs: {
- appDirectory: true,
- navigation: {
- segments: ['dashboard', 'analytics']
- },
- },
- },
-};
-
-export const Example = {};
-
-// SomeComponentThatUsesTheNavigation.js
-import { useSelectedLayoutSegment, useSelectedLayoutSegments, useParams } from 'next/navigation';
-
-export default function SomeComponentThatUsesTheNavigation() {
- const segment = useSelectedLayoutSegment(); // dashboard
- const segments = useSelectedLayoutSegments(); // ["dashboard", "analytics"]
- const params = useParams(); // {}
- ...
-}
-```
-
-To use `useParams`, you have to use a two string elements array for a segment, the first array element is the param key and the second array element is the param value.
-
-```js
-// SomeComponentThatUsesParams.stories.js
-import SomeComponentThatUsesParams from './SomeComponentThatUsesParams';
-
-export default {
- component: SomeComponentThatUsesParams,
- parameters: {
- nextjs: {
- appDirectory: true,
- navigation: {
- segments: [
- ['slug', 'hello'],
- ['framework', 'nextjs'],
- ]
- },
- },
- },
-};
-
-export const Example = {};
-
-// SomeComponentThatUsesParams.js
-import { useSelectedLayoutSegment, useSelectedLayoutSegments, useParams } from 'next/navigation';
-
-export default function SomeComponentThatUsesParams() {
- const segment = useSelectedLayoutSegment(); // hello
- const segments = useSelectedLayoutSegments(); // ["hello", "nextjs"]
- const params = useParams(); // { slug: "hello", framework: "nextjs" }
- ...
-}
-```
-
-The default value of `nextjs.navigation.segments` is `[]` if not set.
-
-#### Default Navigation Context
-
-The default values on the stubbed navigation context are as follows:
-
-```ts
-const defaultNavigationContext = {
- push(...args) {
- action('nextNavigation.push')(...args);
- },
- replace(...args) {
- action('nextNavigation.replace')(...args);
- },
- forward(...args) {
- action('nextNavigation.forward')(...args);
- },
- back(...args) {
- action('nextNavigation.back')(...args);
- },
- prefetch(...args) {
- action('nextNavigation.prefetch')(...args);
- },
- refresh: () => {
- action('nextNavigation.refresh')();
- },
- pathname: '/',
- query: {},
-};
-```
-
-#### Actions Integration Caveats
-
-If you override a function, you lose the automatic action tab integration and have to build it out yourself.
-
-```js
-// .storybook/preview.js
-
-export const parameters = {
- nextjs: {
- appDirectory: true,
- navigation: {
- push() {
- // The default implementation that logs the action into the Actions panel is lost
- },
- },
- },
-};
-```
-
-Doing this yourself looks something like this (make sure you install the `@storybook/addon-actions` package):
-
-```js
-// .storybook/preview.js
-import { action } from '@storybook/addon-actions';
-
-export const parameters = {
- nextjs: {
- appDirectory: true,
- navigation: {
- push(...args) {
- // Custom logic can go here
- // This logs to the Actions panel
- action('nextNavigation.push')(...args);
- // Return whatever you want here
- return Promise.resolve(true);
- },
- },
- },
-};
-```
-
-### Next.js Head
-
-[next/head](https://nextjs.org/docs/api-reference/next/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
-
-[Global sass/scss stylesheets](https://nextjs.org/docs/basic-features/built-in-css-support#sass-support) are supported without any additional configuration as well. Just import them into [preview.js](https://storybook.js.org/docs/react/configure/#configure-story-rendering)
-
-```js
-import '../styles/globals.scss';
-```
-
-This will automatically include any of your [custom sass configurations](https://nextjs.org/docs/basic-features/built-in-css-support#customizing-sass-options) in your `next.config.js` file.
-
-```js
-// next.config.js
-import * as path from 'path';
-
-export default {
- // Any options here are included in Sass compilation for your stories
- sassOptions: {
- includePaths: [path.join(__dirname, 'styles')],
- },
-};
-```
-
-### Css/Sass/Scss Modules
-
-[css modules](https://nextjs.org/docs/basic-features/built-in-css-support#adding-component-level-css) work as expected.
-
-```js
-// This import works just fine in Storybook now
-import styles from './Button.module.css';
-// sass/scss is also supported
-// import styles from './Button.module.scss'
-// import styles from './Button.module.sass'
-
-export function Button() {
- return (
-
- );
-}
-```
-
-### Styled JSX
-
-The built in CSS-in-JS solution for Next.js is [styled-jsx](https://nextjs.org/docs/basic-features/built-in-css-support#css-in-js), and this framework supports that out of the box too, zero config.
-
-```js
-// This works just fine in Storybook now
-function HelloWorld() {
- return (
-
- Hello world
-
scoped!
-
-
-
- );
-}
-
-export default HelloWorld;
-```
-
-You can use your own babel config too. This is an example of how you can customize styled-jsx.
-
-```json
-// .babelrc or whatever config file you use
-{
- "presets": [
- [
- "next/babel",
- {
- "styled-jsx": {
- "plugins": ["@styled-jsx/plugin-sass"]
- }
- }
- ]
- ]
-}
-```
-
-### Postcss
-
-Next.js lets you [customize postcss config](https://nextjs.org/docs/advanced-features/customizing-postcss-config#default-behavior). Thus this framework will automatically handle your postcss config for you.
-
-This allows for cool things like zero config tailwindcss! (See [Next.js' example](https://github.com/vercel/next.js/tree/canary/examples/with-tailwindcss))
-
-### Absolute Imports
-
-Goodbye `../`! Absolute imports from the root directory work just fine.
-
-```js
-// All good!
-import Button from 'components/button';
-// Also good!
-import styles from 'styles/HomePage.module.css';
-
-export default function HomePage() {
- return (
- <>
-
Hello World
-
- >
- );
-}
-```
-
-Also OK for global styles in `preview.js`!
-
-```js
-// .storybook/preview.js
-
-import 'styles/globals.scss';
-
-// ...
-```
-
-### Runtime Config
-
-Next.js allows for [Runtime Configuration](https://nextjs.org/docs/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.
-
-In the context of Storybook with this framework, you can expect Next.js's [Runtime Configuration](https://nextjs.org/docs/api-reference/next.config.js/runtime-configuration) feature to work just fine.
-
-Note, because Storybook doesn't server render your components, your components will only see what they normally see on the client side (i.e. they won't see `serverRuntimeConfig` but will see `publicRuntimeConfig`).
-
-For example, consider the following Next.js config:
-
-```js
-// next.config.js
-module.exports = {
- serverRuntimeConfig: {
- mySecret: 'secret',
- secondSecret: process.env.SECOND_SECRET, // Pass through env variables
- },
- publicRuntimeConfig: {
- staticFolder: '/static',
- },
-};
-```
-
-Calls to `getConfig` would return the following object when called within Storybook:
-
-```json
-{
- "serverRuntimeConfig": {},
- "publicRuntimeConfig": {
- "staticFolder": "/static"
- }
-}
-```
-
-### 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/api-reference/next.config.js/custom-webpack-config). 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.
-
-Any webpack modifications desired for Storybook should be made in [.storybook/main.js](https://storybook.js.org/docs/react/builders/webpack#extending-storybooks-webpack-config).
-
-Note: Not all webpack modifications are copy/paste-able between `next.config.js` and `.storybook/main.js`. It is recommended to do your research on how to properly make your modification to Storybook's webpack config and on how [webpack works](https://webpack.js.org/concepts/).
-
-Below is an example of how to add svgr support to Storybook with this framework.
-
-```js
-// .storybook/main.js
-export default {
- // ...
- webpackFinal: async (config) => {
- config.module = config.module || {};
- config.module.rules = config.module.rules || [];
-
- // This modifies the existing image rule to exclude .svg files
- // since you want to handle those files with @svgr/webpack
- const imageRule = config.module.rules.find((rule) => rule?.['test']?.test('.svg'));
- if (imageRule) {
- imageRule['exclude'] = /\.svg$/;
- }
-
- // Configure .svg files to be loaded with @svgr/webpack
- config.module.rules.push({
- test: /\.svg$/,
- use: ['@svgr/webpack'],
- });
-
- return config;
- },
-};
-```
-
-### 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/advanced-features/module-path-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.
-
-```json
-{
- "compilerOptions": {
- "baseUrl": ".",
- "paths": {
- "@/components/*": ["components/*"]
- }
- }
-}
-```
-
-### Experimental React Server Components (RSC)
-
-If your app uses [React Server Components (RSC)](https://nextjs.org/docs/app/building-your-application/rendering/server-components), Storybook can render them in stories in the browser.
-
-To enable this set the `experimentalRSC` feature flag in your `.storybook/main.js` config:
-
-```js
-// main.js
-export default {
- features: {
- experimentalRSC: true,
- },
-};
-```
-
-Setting this flag automatically wraps your story in a [Suspense](https://react.dev/reference/react/Suspense) wrapper, which is able to render asynchronous components in NextJS's version of React.
-
-If this wrapper causes problems in any of your existing stories, you can selectively disable it using the `react.rsc` [parameter](https://storybook.js.org/docs/writing-stories/parameters) at the global/component/story level:
-
-```js
-// MyServerComponent.stories.js
-export default {
- component: MyServerComponent,
- parameters: { react: { rsc: false } },
-};
-```
-
-Note that wrapping your server components in Suspense does not help if your server components access server-side resources like the file system or Node-specific libraries. To work around this, you'll need to mock out your data access layer using [Webpack aliases](https://webpack.js.org/configuration/resolve/#resolvealias) or an addon like [storybook-addon-module-mock](https://storybook.js.org/addons/storybook-addon-module-mock).
-
-If your server components access data via the network, we recommend using the [MSW Storybook Addon](https://storybook.js.org/addons/msw-storybook-addon) to mock network requests.
-
-In the future we will provide better mocking support in Storybook and support for [Server Actions](https://nextjs.org/docs/app/api-reference/functions/server-actions).
-
-### Notes for Yarn v2 and v3 users
-
-If you're using [Yarn](https://yarnpkg.com/) v2 or v3, you may run into issues where Storybook can't resolve `style-loader` or `css-loader`. For example, you might get errors like:
-
-`Module not found: Error: Can't resolve 'css-loader'`\
-`Module not found: Error: Can't resolve 'style-loader'`
-
-This is because those versions of Yarn have different package resolution rules than Yarn v1.x. If this is the case for you, just install the package directly.
-
-### FAQ
-
-#### Stories for pages/components which fetch data
-
-Next.js page files can contain imports to modules meant to run in a node environment (for use in data fetching functions). 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](https://storybook.js.org/docs/react/builders/webpack#extending-storybooks-webpack-config).
-
-**Before**
-
-```jsx
-// ./pages/my-page.jsx
-import fs from 'fs';
-
-// Using this component in your stories will break the Storybook build
-export default function Page(props) {
- return; // ...
-}
-
-export const getStaticProps = async () => {
- // Logic that uses `fs`
-};
-```
-
-**After**
-
-```jsx
-// ./pages/my-page.jsx
-import fs from 'fs';
-
-// Use this pure component in your stories instead
-import MyPage from 'components/MyPage';
-
-export default function Page(props) {
- return ;
-}
-
-export const getStaticProps = async () => {
- // Logic that uses `fs`
-};
-```
-
-Starting with Next.js 13, you can also fetch data directly within server components in the `app` directory. This does not (currently) work within Storybook for similar reasons as above. It can be worked around similarly as well, by extracting a pure component to a separate file and importing that component in your stories.
-
-**Before**
-
-```jsx
-// ./app/my-page/index.jsx
-async function getData() {
- const res = await fetch(...);
- // ...
-}
-
-// Using this component in your stories will break the Storybook build
-export default async function Page() {
- const data = await getData();
-
- return // ...
-}
-```
-
-**After**
-
-```jsx
-// ./app/my-page/index.jsx
-
-// Use this component in your stories
-import MyPage from './components/MyPage';
-
-async function getData() {
- const res = await fetch(...);
- // ...
-}
-
-export default async function Page() {
- const data = await getData();
-
- return ;
-}
-```
-
-#### Statically imported images won't load
-
-Make sure you are treating image imports the same way you treat them when using `next/image` in normal development.
-
-Before using this framework, image imports just imported the raw path to the image (e.g. `'static/media/stories/assets/logo.svg'`). Now image imports work the "Next.js way", meaning that you now get an object when importing an image. For example:
-
-```json
-{
- "src": "static/media/stories/assets/logo.svg",
- "height": 48,
- "width": 48,
- "blurDataURL": "static/media/stories/assets/logo.svg"
-}
-```
-
-Therefore, if something in storybook isn't showing the image properly, make sure you expect the object to be returned from an import instead of just the asset path.
-
-See [local images](https://nextjs.org/docs/basic-features/image-optimization#local-images) for more detail on how Next.js treats static image imports.
-
-#### Module not found: Error: Can't resolve `package name`
-
-You might get this if you're using Yarn v2 or v3. See [Notes for Yarn v2 and v3 users](#notes-for-yarn-v2-and-v3-users) for more details.
-
-#### What if I'm using the Vite builder?
-
-The `@storybook/nextjs` package abstracts the Webpack 5 builder and provides all the necessary Webpack configuration needed (and used internally) by Next.js. Webpack is currently the official builder in Next.js, and Next.js does not support Vite, therefore it is not possible to use Vite with `@storybook/nextjs`. You can use `@storybook/react-vite` framework instead, but at the cost of having a degraded experience, and we won't be able to provide you official support.
+See [documentation](https://storybook.js.org/docs/get-started/nextjs) for installation instructions, usage examples, api, and more.
## Acknowledgements
This framework borrows heavily from these Storybook addons:
- [storybook-addon-next](https://github.com/RyanClementsHax/storybook-addon-next) by [RyanClementsHax](https://github.com/RyanClementsHax/)
-- [storybook-addon-next-router](https://github.com/lifeiscontent/storybook-addon-next-router) by [lifeiscontent](https://github.com/lifeiscontent)
+- [storybook-addon-next-router](https://github.com/lifeiscontent/storybook-addon-next-router) by [lifeiscontent](https://github.com/lifeiscontent)
\ No newline at end of file
diff --git a/docs/get-started/nextjs.md b/docs/get-started/nextjs.md
new file mode 100644
index 000000000000..9c765276058b
--- /dev/null
+++ b/docs/get-started/nextjs.md
@@ -0,0 +1,935 @@
+---
+title: Storybook for Next.js
+---
+
+Storybook for Next.js is a [framework](../contribute/framework.md) that makes it easy to develop and test UI components in isolation for [Next.js](https://nextjs.org/) applications. It includes:
+
+- π Routing
+- πΌ Image optimization
+- β€΅οΈ Absolute imports
+- π¨ Styling
+- π Webpack & Babel config
+- π« and more!
+
+## Requirements
+
+- Next.js >= 13.5
+- Storybook >= 7.x
+
+## Getting started
+
+### In a project without Storybook
+
+Follow the prompts after running this command in your Next.js project's root directory:
+
+
+
+
+
+
+
+[More on getting started with Storybook.](./install.md)
+
+### 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:
+
+
+
+
+
+
+
+#### Automatic migration
+
+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:
+
+
+
+
+
+
+
+Then, update your `.storybook/main.js|ts` to change the framework property:
+
+
+
+
+
+
+
+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:
+
+
+
+
+
+
+
+## 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](https://nextjs.org/docs/pages/building-your-application/optimizing/images#local-images) are supported.
+
+```jsx
+// index.js
+import Image from 'next/image';
+import profilePic from '../public/me.png';
+
+function Home() {
+ return (
+ <>
+
My Homepage
+
+
Welcome to my homepage!
+ >
+ );
+}
+```
+
+### Remote images
+
+[Remote images](https://nextjs.org/docs/pages/building-your-application/optimizing/images#remote-images) are also supported.
+
+```jsx
+// index.js
+import Image from 'next/image';
+
+export default function Home() {
+ return (
+ <>
+
My Homepage
+
+
Welcome to my homepage!
+ >
+ );
+}
+```
+
+## 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`
+
+You don't have to do anything. `next/font/google` is supported out of the box.
+
+### `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.
+
+If the following component defines your localFont like this:
+
+```js
+// src/components/MyComponent.js
+import localFont from 'next/font/local';
+
+const localRubikStorm = localFont({ src: './fonts/RubikStorm-Regular.ttf' });
+```
+
+You have to tell Storybook where the `fonts` directory is located, via the [`staticDirs` configuration](../api/main-config-static-dirs.md#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.
+
+
+
+
+
+
+
+### Not supported features of `next/font`
+
+The following features are not supported (yet). Support for these features might be planned for the future:
+
+- [Support font loaders configuration in next.config.js](https://nextjs.org/docs/pages/building-your-application/optimizing/fonts#local-fonts)
+- [fallback](https://nextjs.org/docs/pages/api-reference/components/font#fallback) option
+- [adjustFontFallback](https://nextjs.org/docs/pages/api-reference/components/font#adjustfontfallback) option
+- [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
+
+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.
+
+For example, using [GitHub Actions](https://www.chromatic.com/docs/github-actions):
+
+```yaml
+# .github/workflows/ci.yml
+- uses: chromaui/action@v1
+ env:
+ #π the location of mocked fonts to use
+ NEXT_FONT_GOOGLE_MOCKED_RESPONSES: ${{ github.workspace }}/mocked-google-fonts.js
+ with:
+ projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
+ token: ${{ secrets.GITHUB_TOKEN }}
+```
+
+Your mocked fonts will look something like this:
+
+```js
+// mocked-google-fonts.js
+//π Mocked responses of google fonts with the URL as the key
+module.exports = {
+ 'https://fonts.googleapis.com/css?family=Inter:wght@400;500;600;800&display=block': `
+ /* cyrillic-ext */
+ @font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src: url(https://fonts.gstatic.com/s/inter/v12/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZJhiJ-Ek-_EeAmM.woff2) format('woff2');
+ unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
+ }
+ /* more font declarations go here */
+ /* latin */
+ @font-face {
+ font-family: 'Inter';
+ font-style: normal;
+ font-weight: 400;
+ font-display: block;
+ src: url(https://fonts.gstatic.com/s/inter/v12/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZ9hiJ-Ek-_EeA.woff2) format('woff2');
+ unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
+ }`,
+};
+```
+
+## 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 if you have the [Storybook actions addon](../essentials/actions.md).
+
+
+
+You should only use `next/router` in the `pages` directory. In the `app` directory, it is necessary to use `next/navigation`.
+
+
+
+### Overriding defaults
+
+Per-story overrides can be done by adding a `nextjs.router` property onto the story [parameters](../writing-stories/parameters.md). The framework will shallowly merge whatever you put here into the router.
+
+
+
+
+
+
+
+
+
+These overrides can also be applied to [all stories for a component](../api/parameters.md#meta-parameters) or [all stories in your project](../api/parameters.md#project-parameters). Standard [parameter inheritance](../api/parameters.md#parameter-inheritance) rules apply.
+
+
+
+### Default router
+
+The default values on the stubbed router are as follows (see [globals](../essentials/toolbars-and-globals.md#globals) for more details on how globals work).
+
+```ts
+// Default router
+const defaultRouter = {
+ push(...args) {
+ action('nextRouter.push')(...args);
+ return Promise.resolve(true);
+ },
+ replace(...args) {
+ action('nextRouter.replace')(...args);
+ return Promise.resolve(true);
+ },
+ reload(...args) {
+ action('nextRouter.reload')(...args);
+ },
+ back(...args) {
+ action('nextRouter.back')(...args);
+ },
+ forward() {
+ action('nextRouter.forward')();
+ },
+ prefetch(...args) {
+ action('nextRouter.prefetch')(...args);
+ return Promise.resolve();
+ },
+ beforePopState(...args) {
+ action('nextRouter.beforePopState')(...args);
+ },
+ events: {
+ on(...args) {
+ action('nextRouter.events.on')(...args);
+ },
+ off(...args) {
+ action('nextRouter.events.off')(...args);
+ },
+ emit(...args) {
+ action('nextRouter.events.emit')(...args);
+ },
+ },
+ // The locale should be configured globally: https://storybook.js.org/docs/essentials/toolbars-and-globals#globals
+ locale: globals?.locale,
+ asPath: '/',
+ basePath: '/',
+ isFallback: false,
+ isLocaleDomain: false,
+ isReady: true,
+ isPreview: false,
+ route: '/',
+ pathname: '/',
+ query: {},
+};
+```
+
+### Actions integration caveats
+
+If you override a function, you lose the automatic action tab integration and have to build it out yourself, which looks something like this (make sure you install the `@storybook/addon-actions` package):
+
+
+
+
+
+
+
+## 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`
+
+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:
+
+
+
+
+
+
+
+If your Next.js project uses the `app` directory for every page (in other words, it does not have a `pages` directory), you can set the parameter `nextjs.appDirectory` to `true` in the [`.storybook/preview.js|ts`](../configure/index.md#configure-story-rendering) file to apply it to all stories.
+
+
+
+
+
+
+
+### Overriding defaults
+
+Per-story overrides can be done by adding a `nextjs.navigation` property onto the story [parameters](../writing-stories/parameters.md). The framework will shallowly merge whatever you put here into the router.
+
+
+
+
+
+
+
+
+
+These overrides can also be applied to [all stories for a component](../api/parameters.md#meta-parameters) or [all stories in your project](../api/parameters.md#project-parameters). Standard [parameter inheritance](../api/parameters.md#parameter-inheritance) rules apply.
+
+
+
+### `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.
+
+
+
+
+
+With the above configuration, the component rendered in the stories would receive the following values from the hooks:
+
+```js
+// NavigationBasedComponent.js
+import { useSelectedLayoutSegment, useSelectedLayoutSegments, useParams } from 'next/navigation';
+
+export default function NavigationBasedComponent() {
+ const segment = useSelectedLayoutSegment(); // dashboard
+ const segments = useSelectedLayoutSegments(); // ["dashboard", "analytics"]
+ const params = useParams(); // {}
+ // ...
+}
+```
+
+
+
+To use `useParams`, you have to use a segments array where each element is an array containing two strings. The first string is the param key and the second string is the param value.
+
+
+
+
+
+
+
+With the above configuration, the component rendered in the stories would receive the following values from the hooks:
+
+```js
+// ParamsBasedComponent.js
+import { useSelectedLayoutSegment, useSelectedLayoutSegments, useParams } from 'next/navigation';
+
+export default function ParamsBasedComponent() {
+ const segment = useSelectedLayoutSegment(); // hello
+ const segments = useSelectedLayoutSegments(); // ["hello", "nextjs"]
+ const params = useParams(); // { slug: "hello", framework: "nextjs" }
+ ...
+}
+```
+
+
+
+These overrides can also be applied to [a single story](../api/parameters.md#story-parameters) or [all stories in your project](../api/parameters.md#project-parameters). Standard [parameter inheritance](../api/parameters.md#parameter-inheritance) rules apply.
+
+
+
+The default value of `nextjs.navigation.segments` is `[]` if not set.
+
+### Default navigation context
+
+The default values on the stubbed navigation context are as follows:
+
+```ts
+// Default navigation context
+const defaultNavigationContext = {
+ push(...args) {
+ action('nextNavigation.push')(...args);
+ },
+ replace(...args) {
+ action('nextNavigation.replace')(...args);
+ },
+ forward(...args) {
+ action('nextNavigation.forward')(...args);
+ },
+ back(...args) {
+ action('nextNavigation.back')(...args);
+ },
+ prefetch(...args) {
+ action('nextNavigation.prefetch')(...args);
+ },
+ refresh: () => {
+ action('nextNavigation.refresh')();
+ },
+ pathname: '/',
+ query: {},
+};
+```
+
+### Actions integration caveats
+
+If you override a function, you lose the automatic action tab integration and have to build it out yourself, which looks something like this (make sure you install the `@storybook/addon-actions` package):
+
+
+
+
+
+
+
+## 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
+
+[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.md#configure-story-rendering)
+
+```js
+// .storybook/preview.js|ts
+import '../styles/globals.scss';
+```
+
+This will automatically include any of your [custom Sass configurations](https://nextjs.org/docs/pages/building-your-application/styling/sass#customizing-sass-options) in your `next.config.js` file.
+
+```js
+// next.config.js
+import * as path from 'path';
+
+export default {
+ // Any options here are included in Sass compilation for your stories
+ sassOptions: {
+ includePaths: [path.join(__dirname, 'styles')],
+ },
+};
+```
+
+## CSS/Sass/Scss Modules
+
+[CSS modules](https://nextjs.org/docs/pages/building-your-application/styling/css-modules) work as expected.
+
+```jsx
+// src/components/Button.jsx
+// This import will work in Storybook
+import styles from './Button.module.css';
+// Sass/Scss is also supported
+// import styles from './Button.module.scss'
+// import styles from './Button.module.sass'
+
+export function Button() {
+ return (
+
+ );
+}
+```
+
+## 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.
+
+```jsx
+// src/components/HelloWorld.jsx
+// This will work in Storybook
+function HelloWorld() {
+ return (
+
+ Hello world
+
scoped!
+
+
+
+ );
+}
+
+export default HelloWorld;
+```
+
+You can use your own babel config too. This is an example of how you can customize styled-jsx.
+
+```json
+// .babelrc (or whatever config file you use)
+{
+ "presets": [
+ [
+ "next/babel",
+ {
+ "styled-jsx": {
+ "plugins": ["@styled-jsx/plugin-sass"]
+ }
+ }
+ ]
+ ]
+}
+```
+
+## 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/examples/with-tailwindcss))
+
+## 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.
+
+```jsx
+// index.js
+// All good!
+import Button from 'components/button';
+// Also good!
+import styles from 'styles/HomePage.module.css';
+
+export default function HomePage() {
+ return (
+ <>
+
Hello World
+
+ >
+ );
+}
+```
+
+Also OK for global styles in `.storybook/preview.js|ts`!
+
+```js
+// .storybook/preview.js|ts
+
+import 'styles/globals.scss';
+
+// ...
+```
+
+## 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.
+
+In the context of Storybook with this framework, you can expect Next.js's [Runtime Configuration](https://nextjs.org/docs/pages/api-reference/next-config-js/runtime-configuration) feature to work just fine.
+
+Note, because Storybook doesn't server render your components, your components will only see what they normally see on the client side (i.e. they won't see `serverRuntimeConfig` but will see `publicRuntimeConfig`).
+
+For example, consider the following Next.js config:
+
+```js
+// next.config.js
+module.exports = {
+ serverRuntimeConfig: {
+ mySecret: 'secret',
+ secondSecret: process.env.SECOND_SECRET, // Pass through env variables
+ },
+ publicRuntimeConfig: {
+ staticFolder: '/static',
+ },
+};
+```
+
+Calls to `getConfig` would return the following object when called within Storybook:
+
+```json
+// Runtime config
+{
+ "serverRuntimeConfig": {},
+ "publicRuntimeConfig": {
+ "staticFolder": "/static"
+ }
+}
+```
+
+## 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.
+
+Any Webpack modifications desired for Storybook should be made in [`.storybook/main.js|ts`](../builders/webpack.md#extending-storybooks-webpack-config).
+
+Note: Not all Webpack 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 Webpack config and on how [Webpack works](https://webpack.js.org/concepts/).
+
+Below is an example of how to add SVGR support to Storybook with this framework.
+
+
+
+
+
+
+
+## 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.
+
+```json
+// tsconfig.json
+{
+ "compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@/components/*": ["components/*"]
+ }
+ }
+}
+```
+
+## React Server Components (RSC)
+
+(β οΈ **Experimental**)
+
+If your app uses [React Server Components (RSC)](https://nextjs.org/docs/app/building-your-application/rendering/server-components), Storybook can render them in stories in the browser.
+
+To enable this set the `experimentalRSC` feature flag in your `.storybook/main.js|ts` config:
+
+
+
+
+
+
+
+Setting this flag automatically wraps your story in a [Suspense](https://react.dev/reference/react/Suspense) wrapper, which is able to render asynchronous components in NextJS's version of React.
+
+If this wrapper causes problems in any of your existing stories, you can selectively disable it using the `react.rsc` [parameter](https://storybook.js.org/docs/writing-stories/parameters) at the global/component/story level:
+
+
+
+
+
+
+
+Note that wrapping your server components in Suspense does not help if your server components access server-side resources like the file system or Node-specific libraries. To work around this, you'll need to mock out your data access layer using [Webpack aliases](https://webpack.js.org/configuration/resolve/#resolvealias) or an addon like [storybook-addon-module-mock](https://storybook.js.org/addons/storybook-addon-module-mock).
+
+If your server components access data via the network, we recommend using the [MSW Storybook Addon](https://storybook.js.org/addons/msw-storybook-addon) to mock network requests.
+
+In the future we will provide better mocking support in Storybook and support for [Server Actions](https://nextjs.org/docs/app/api-reference/functions/server-actions).
+
+## Notes for Yarn v2 and v3 users
+
+If you're using [Yarn](https://yarnpkg.com/) v2 or v3, you may run into issues where Storybook can't resolve `style-loader` or `css-loader`. For example, you might get errors like:
+
+```
+Module not found: Error: Can't resolve 'css-loader'
+Module not found: Error: Can't resolve 'style-loader'
+```
+
+This is because those versions of Yarn have different package resolution rules than Yarn v1.x. If this is the case for you, please install the package directly.
+
+## FAQ
+
+### 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.md#extending-storybooks-webpack-config).
+
+**Before**
+
+```jsx
+// app/my-page/index.jsx
+async function getData() {
+ const res = await fetch(...);
+ // ...
+}
+
+// Using this component in your stories will break the Storybook build
+export default async function Page() {
+ const data = await getData();
+
+ return // ...
+}
+```
+
+**After**
+
+```jsx
+// app/my-page/index.jsx
+
+// Use this component in your stories
+import MyPage from './components/MyPage';
+
+async function getData() {
+ const res = await fetch(...);
+ // ...
+}
+
+export default async function Page() {
+ const data = await getData();
+
+ return ;
+}
+```
+
+### Statically imported images won't load
+
+Make sure you are treating image imports the same way you treat them when using `next/image` in normal development.
+
+Before using this framework, image imports would import the raw path to the image (e.g. `'static/media/stories/assets/logo.svg'`). Now image imports work the "Next.js way", meaning that you now get an object when importing an image. For example:
+
+```json
+// Image import object
+{
+ "src": "static/media/stories/assets/logo.svg",
+ "height": 48,
+ "width": 48,
+ "blurDataURL": "static/media/stories/assets/logo.svg"
+}
+```
+
+Therefore, if something in Storybook isn't showing the image properly, make sure you expect the object to be returned from an import instead of only the asset path.
+
+See [local images](https://nextjs.org/docs/pages/building-your-application/optimizing/images#local-images) for more detail on how Next.js treats static image imports.
+
+### Module not found: Error: Can't resolve `package name`
+
+You might get this if you're using Yarn v2 or v3. See [Notes for Yarn v2 and v3 users](#notes-for-yarn-v2-and-v3-users) for more details.
+
+### What if I'm using the Vite builder?
+
+The `@storybook/nextjs` package abstracts the Webpack 5 builder and provides all the necessary Webpack configuration needed (and used internally) by Next.js. Webpack is currently the official builder in Next.js, and Next.js does not support Vite, therefore it is not possible to use Vite with `@storybook/nextjs`. You can use `@storybook/react-vite` framework instead, but at the cost of having a degraded experience, and we won't be able to provide you official support.
+
+## API
+
+### Parameters
+
+This framework contributes the following [parameters](../writing-stories/parameters.md) to Storybook, under the `nextjs` namespace:
+
+#### `appDirectory`
+
+Type: `boolean`
+
+Default: `false`
+
+If your story imports components that use `next/navigation`, you need to set the parameter `nextjs.appDirectory` to `true`. Because this is a parameter, you can apply it to a [single story](../api/parameters.md#story-parameters), [all stories for a component](../api/parameters.md#meta-parameters), or [every story in your Storybook](../api/parameters.md#project-parameters). See [Next.js Navigation](#nextjs-navigation) for more details.
+
+#### `navigation`
+
+Type:
+
+```ts
+{
+ asPath?: string;
+ pathname?: string;
+ query?: Record;
+ segments?: (string | [string, string])[];
+}
+```
+
+Default value:
+
+```js
+{
+ segments: [];
+}
+```
+
+The router object that is passed to the `next/navigation` context. See [Next.js's navigation docs](https://nextjs.org/docs/app/building-your-application/routing) for more details.
+
+#### `router`
+
+Type:
+
+```ts
+{
+ asPath?: string;
+ pathname?: string;
+ query?: Record;
+}
+```
+
+The router object that is passed to the `next/router` context. See [Next.js's router docs](https://nextjs.org/docs/pages/building-your-application/routing) for more details.
+
+### Options
+
+You can pass an options object for additional configuration if needed:
+
+```js
+// .storybook/main.js
+import * as path from 'path';
+
+export default {
+ // ...
+ framework: {
+ name: '@storybook/nextjs',
+ options: {
+ image: {
+ loading: 'eager',
+ },
+ nextConfigPath: path.resolve(__dirname, '../next.config.js'),
+ },
+ },
+};
+```
+
+The available options are:
+
+#### `builder`
+
+Type: `Record`
+
+Configure options for the [framework's builder](../api/main-config-framework.md#optionsbuilder). For Next.js, that builder is Webpack 5.
+
+#### `image`
+
+Type: `object`
+
+Props to pass to every instance of `next/image`. See [next/image docs](https://nextjs.org/docs/pages/api-reference/components/image) for more details.
+
+#### `nextConfigPath`
+
+Type: `string`
+
+The absolute path to the `next.config.js` file. This is necessary if you have a custom `next.config.js` file that is not in the root directory of your project.
diff --git a/docs/snippets/react/nextjs-add-framework.js.mdx b/docs/snippets/react/nextjs-add-framework.js.mdx
new file mode 100644
index 000000000000..620630a1322a
--- /dev/null
+++ b/docs/snippets/react/nextjs-add-framework.js.mdx
@@ -0,0 +1,8 @@
+```js
+// .storybook/main.js
+export default {
+ // ...
+ // framework: '@storybook/react-webpack5', π Remove this
+ framework: '@storybook/nextjs', // π Add this
+};
+```
diff --git a/docs/snippets/react/nextjs-add-framework.ts.mdx b/docs/snippets/react/nextjs-add-framework.ts.mdx
new file mode 100644
index 000000000000..945bc22217b3
--- /dev/null
+++ b/docs/snippets/react/nextjs-add-framework.ts.mdx
@@ -0,0 +1,12 @@
+```ts
+// .storybook/main.ts
+import { StorybookConfig } from '@storybook/nextjs';
+
+const config: StorybookConfig = {
+ // ...
+ // framework: '@storybook/react-webpack5', π Remove this
+ framework: '@storybook/nextjs', // π Add this
+};
+
+export default config;
+```
diff --git a/docs/snippets/react/nextjs-app-directory-in-meta.js.mdx b/docs/snippets/react/nextjs-app-directory-in-meta.js.mdx
new file mode 100644
index 000000000000..a941df07394e
--- /dev/null
+++ b/docs/snippets/react/nextjs-app-directory-in-meta.js.mdx
@@ -0,0 +1,13 @@
+```js
+// NavigationBasedComponent.stories.js
+import NavigationBasedComponent from './NavigationBasedComponent';
+
+export default {
+ component: NavigationBasedComponent,
+ parameters: {
+ nextjs: {
+ appDirectory: true, // π Set this
+ },
+ },
+};
+```
diff --git a/docs/snippets/react/nextjs-app-directory-in-meta.ts-4-9.mdx b/docs/snippets/react/nextjs-app-directory-in-meta.ts-4-9.mdx
new file mode 100644
index 000000000000..fb8adee4caf8
--- /dev/null
+++ b/docs/snippets/react/nextjs-app-directory-in-meta.ts-4-9.mdx
@@ -0,0 +1,16 @@
+```ts
+// NavigationBasedComponent.stories.ts
+import { Meta, StoryObj } from '@storybook/react';
+
+import NavigationBasedComponent from './NavigationBasedComponent';
+
+const meta = {
+ component: NavigationBasedComponent,
+ parameters: {
+ nextjs: {
+ appDirectory: true, // π Set this
+ },
+ },
+} satisfies Meta;
+export default meta;
+```
diff --git a/docs/snippets/react/nextjs-app-directory-in-meta.ts.mdx b/docs/snippets/react/nextjs-app-directory-in-meta.ts.mdx
new file mode 100644
index 000000000000..5489423e8336
--- /dev/null
+++ b/docs/snippets/react/nextjs-app-directory-in-meta.ts.mdx
@@ -0,0 +1,16 @@
+```ts
+// NavigationBasedComponent.stories.ts
+import { Meta, StoryObj } from '@storybook/react';
+
+import NavigationBasedComponent from './NavigationBasedComponent';
+
+const meta: Meta = {
+ component: NavigationBasedComponent,
+ parameters: {
+ nextjs: {
+ appDirectory: true, // π Set this
+ },
+ },
+};
+export default meta;
+```
diff --git a/docs/snippets/react/nextjs-app-directory-in-preview.js.mdx b/docs/snippets/react/nextjs-app-directory-in-preview.js.mdx
new file mode 100644
index 000000000000..94eb1afc548e
--- /dev/null
+++ b/docs/snippets/react/nextjs-app-directory-in-preview.js.mdx
@@ -0,0 +1,13 @@
+```js
+// .storybook/preview.js
+
+export default {
+ // ...
+ parameters: {
+ // ...
+ nextjs: {
+ appDirectory: true,
+ },
+ },
+};
+```
diff --git a/docs/snippets/react/nextjs-app-directory-in-preview.ts.mdx b/docs/snippets/react/nextjs-app-directory-in-preview.ts.mdx
new file mode 100644
index 000000000000..13f567e3899d
--- /dev/null
+++ b/docs/snippets/react/nextjs-app-directory-in-preview.ts.mdx
@@ -0,0 +1,16 @@
+```ts
+// .storybook/preview.ts
+import { Preview } from '@storybook/react';
+
+const preview: Preview = {
+ // ...
+ parameters: {
+ // ...
+ nextjs: {
+ appDirectory: true,
+ },
+ },
+};
+
+export default preview;
+```
diff --git a/docs/snippets/react/nextjs-configure-svgr.js.mdx b/docs/snippets/react/nextjs-configure-svgr.js.mdx
new file mode 100644
index 000000000000..11bb4a508913
--- /dev/null
+++ b/docs/snippets/react/nextjs-configure-svgr.js.mdx
@@ -0,0 +1,25 @@
+```js
+// .storybook/main.js
+export default {
+ // ...
+ webpackFinal: async (config) => {
+ config.module = config.module || {};
+ config.module.rules = config.module.rules || [];
+
+ // This modifies the existing image rule to exclude .svg files
+ // since you want to handle those files with @svgr/webpack
+ const imageRule = config.module.rules.find((rule) => rule?.['test']?.test('.svg'));
+ if (imageRule) {
+ imageRule['exclude'] = /\.svg$/;
+ }
+
+ // Configure .svg files to be loaded with @svgr/webpack
+ config.module.rules.push({
+ test: /\.svg$/,
+ use: ['@svgr/webpack'],
+ });
+
+ return config;
+ },
+};
+```
diff --git a/docs/snippets/react/nextjs-configure-svgr.ts.mdx b/docs/snippets/react/nextjs-configure-svgr.ts.mdx
new file mode 100644
index 000000000000..7d3ddab95264
--- /dev/null
+++ b/docs/snippets/react/nextjs-configure-svgr.ts.mdx
@@ -0,0 +1,29 @@
+```ts
+// .storybook/main.ts
+import { StorybookConfig } from '@storybook/nextjs';
+
+const config: StorybookConfig = {
+ // ...
+ webpackFinal: async (config) => {
+ config.module = config.module || {};
+ config.module.rules = config.module.rules || [];
+
+ // This modifies the existing image rule to exclude .svg files
+ // since you want to handle those files with @svgr/webpack
+ const imageRule = config.module.rules.find((rule) => rule?.['test']?.test('.svg'));
+ if (imageRule) {
+ imageRule['exclude'] = /\.svg$/;
+ }
+
+ // Configure .svg files to be loaded with @svgr/webpack
+ config.module.rules.push({
+ test: /\.svg$/,
+ use: ['@svgr/webpack'],
+ });
+
+ return config;
+ },
+};
+
+export default config;
+```
diff --git a/docs/snippets/react/nextjs-image-static-dirs.js.mdx b/docs/snippets/react/nextjs-image-static-dirs.js.mdx
new file mode 100644
index 000000000000..66d2f8b7e7cc
--- /dev/null
+++ b/docs/snippets/react/nextjs-image-static-dirs.js.mdx
@@ -0,0 +1,12 @@
+```js
+// .storybook/main.js
+export default {
+ // ...
+ staticDirs: [
+ {
+ from: '../src/components/fonts',
+ to: 'src/components/fonts',
+ },
+ ],
+};
+```
diff --git a/docs/snippets/react/nextjs-image-static-dirs.ts.mdx b/docs/snippets/react/nextjs-image-static-dirs.ts.mdx
new file mode 100644
index 000000000000..cec45e42c964
--- /dev/null
+++ b/docs/snippets/react/nextjs-image-static-dirs.ts.mdx
@@ -0,0 +1,16 @@
+```ts
+// .storybook/main.ts
+import { StorybookConfig } from '@storybook/nextjs';
+
+const config: StorybookConfig = {
+ // ...
+ staticDirs: [
+ {
+ from: '../src/components/fonts',
+ to: 'src/components/fonts',
+ },
+ ],
+};
+
+export default config;
+```
diff --git a/docs/snippets/react/nextjs-install.npm.js.mdx b/docs/snippets/react/nextjs-install.npm.js.mdx
new file mode 100644
index 000000000000..28b66be2c17e
--- /dev/null
+++ b/docs/snippets/react/nextjs-install.npm.js.mdx
@@ -0,0 +1,3 @@
+```shell
+npm install --save-dev @storybook/nextjs
+```
diff --git a/docs/snippets/react/nextjs-install.pnpm.js.mdx b/docs/snippets/react/nextjs-install.pnpm.js.mdx
new file mode 100644
index 000000000000..7774ac6c9b42
--- /dev/null
+++ b/docs/snippets/react/nextjs-install.pnpm.js.mdx
@@ -0,0 +1,3 @@
+```shell
+pnpm install --save-dev @storybook/nextjs
+```
diff --git a/docs/snippets/react/nextjs-install.yarn.js.mdx b/docs/snippets/react/nextjs-install.yarn.js.mdx
new file mode 100644
index 000000000000..48cd296d98b8
--- /dev/null
+++ b/docs/snippets/react/nextjs-install.yarn.js.mdx
@@ -0,0 +1,3 @@
+```shell
+yarn add --dev @storybook/nextjs
+```
diff --git a/docs/snippets/react/nextjs-navigation-override-in-story.js.mdx b/docs/snippets/react/nextjs-navigation-override-in-story.js.mdx
new file mode 100644
index 000000000000..49af21318d60
--- /dev/null
+++ b/docs/snippets/react/nextjs-navigation-override-in-story.js.mdx
@@ -0,0 +1,28 @@
+```js
+// NavigationBasedComponent.stories.js
+import NavigationBasedComponent from './NavigationBasedComponent';
+
+export default {
+ component: NavigationBasedComponent,
+ parameters: {
+ nextjs: {
+ appDirectory: true,
+ },
+ },
+};
+
+// If you have the actions addon,
+// you can interact with the links and see the route change events there
+export const Example = {
+ parameters: {
+ nextjs: {
+ navigation: {
+ pathname: '/profile',
+ query: {
+ user: '1',
+ },
+ },
+ },
+ },
+};
+```
diff --git a/docs/snippets/react/nextjs-navigation-override-in-story.ts-4-9.mdx b/docs/snippets/react/nextjs-navigation-override-in-story.ts-4-9.mdx
new file mode 100644
index 000000000000..07aec86243d4
--- /dev/null
+++ b/docs/snippets/react/nextjs-navigation-override-in-story.ts-4-9.mdx
@@ -0,0 +1,33 @@
+```ts
+// NavigationBasedComponent.stories.ts
+import { Meta, StoryObj } from '@storybook/react';
+
+import NavigationBasedComponent from './NavigationBasedComponent';
+
+const meta = {
+ component: NavigationBasedComponent,
+ parameters: {
+ nextjs: {
+ appDirectory: true,
+ },
+ },
+} satisfies Meta;
+export default meta;
+
+type Story = StoryObj;
+
+// If you have the actions addon,
+// you can interact with the links and see the route change events there
+export const Example: Story = {
+ parameters: {
+ nextjs: {
+ navigation: {
+ pathname: '/profile',
+ query: {
+ user: '1',
+ },
+ },
+ },
+ },
+};
+```
diff --git a/docs/snippets/react/nextjs-navigation-override-in-story.ts.mdx b/docs/snippets/react/nextjs-navigation-override-in-story.ts.mdx
new file mode 100644
index 000000000000..7b854c9bf8f3
--- /dev/null
+++ b/docs/snippets/react/nextjs-navigation-override-in-story.ts.mdx
@@ -0,0 +1,33 @@
+```ts
+// NavigationBasedComponent.stories.ts
+import { Meta, StoryObj } from '@storybook/react';
+
+import NavigationBasedComponent from './NavigationBasedComponent';
+
+const meta: Meta = {
+ component: NavigationBasedComponent,
+ parameters: {
+ nextjs: {
+ appDirectory: true,
+ },
+ },
+};
+export default meta;
+
+type Story = StoryObj;
+
+// If you have the actions addon,
+// you can interact with the links and see the route change events there
+export const Example: Story = {
+ parameters: {
+ nextjs: {
+ navigation: {
+ pathname: '/profile',
+ query: {
+ user: '1',
+ },
+ },
+ },
+ },
+};
+```
diff --git a/docs/snippets/react/nextjs-navigation-push-override-in-preview.js.mdx b/docs/snippets/react/nextjs-navigation-push-override-in-preview.js.mdx
new file mode 100644
index 000000000000..03e44ad039a7
--- /dev/null
+++ b/docs/snippets/react/nextjs-navigation-push-override-in-preview.js.mdx
@@ -0,0 +1,21 @@
+```js
+// .storybook/preview.js
+
+export default {
+ // ...
+ parameters: {
+ // ...
+ nextjs: {
+ navigation: {
+ push(...args) {
+ // Custom logic can go here
+ // This logs to the Actions panel
+ action('nextNavigation.push')(...args);
+ // Return whatever you want here
+ return Promise.resolve(true);
+ },
+ },
+ },
+ },
+};
+```
diff --git a/docs/snippets/react/nextjs-navigation-push-override-in-preview.ts.mdx b/docs/snippets/react/nextjs-navigation-push-override-in-preview.ts.mdx
new file mode 100644
index 000000000000..9534d5dd227f
--- /dev/null
+++ b/docs/snippets/react/nextjs-navigation-push-override-in-preview.ts.mdx
@@ -0,0 +1,24 @@
+```ts
+// .storybook/preview.ts
+import { Preview } from '@storybook/react';
+
+const preview: Preview = {
+ // ...
+ parameters: {
+ // ...
+ nextjs: {
+ navigation: {
+ push(...args) {
+ // Custom logic can go here
+ // This logs to the Actions panel
+ action('nextNavigation.push')(...args);
+ // Return whatever you want here
+ return Promise.resolve(true);
+ },
+ },
+ },
+ },
+};
+
+export default preview;
+```
diff --git a/docs/snippets/react/nextjs-navigation-segments-for-use-params-override-in-meta.js.mdx b/docs/snippets/react/nextjs-navigation-segments-for-use-params-override-in-meta.js.mdx
new file mode 100644
index 000000000000..1f7e5406db30
--- /dev/null
+++ b/docs/snippets/react/nextjs-navigation-segments-for-use-params-override-in-meta.js.mdx
@@ -0,0 +1,19 @@
+```js
+// NavigationBasedComponent.stories.js
+import NavigationBasedComponent from './NavigationBasedComponent';
+
+export default {
+ component: NavigationBasedComponent,
+ parameters: {
+ nextjs: {
+ appDirectory: true,
+ navigation: {
+ segments: [
+ ['slug', 'hello'],
+ ['framework', 'nextjs'],
+ ],
+ },
+ },
+ },
+};
+```
diff --git a/docs/snippets/react/nextjs-navigation-segments-for-use-params-override-in-meta.ts-4-9.mdx b/docs/snippets/react/nextjs-navigation-segments-for-use-params-override-in-meta.ts-4-9.mdx
new file mode 100644
index 000000000000..cae936cb0817
--- /dev/null
+++ b/docs/snippets/react/nextjs-navigation-segments-for-use-params-override-in-meta.ts-4-9.mdx
@@ -0,0 +1,22 @@
+```ts
+// NavigationBasedComponent.stories.ts
+import { Meta, StoryObj } from '@storybook/react';
+
+import NavigationBasedComponent from './NavigationBasedComponent';
+
+const meta = {
+ component: NavigationBasedComponent,
+ parameters: {
+ nextjs: {
+ appDirectory: true,
+ navigation: {
+ segments: [
+ ['slug', 'hello'],
+ ['framework', 'nextjs'],
+ ],
+ },
+ },
+ },
+} satisfies Meta;
+export default meta;
+```
diff --git a/docs/snippets/react/nextjs-navigation-segments-for-use-params-override-in-meta.ts.mdx b/docs/snippets/react/nextjs-navigation-segments-for-use-params-override-in-meta.ts.mdx
new file mode 100644
index 000000000000..ff779e2a26f6
--- /dev/null
+++ b/docs/snippets/react/nextjs-navigation-segments-for-use-params-override-in-meta.ts.mdx
@@ -0,0 +1,22 @@
+```ts
+// NavigationBasedComponent.stories.ts
+import { Meta, StoryObj } from '@storybook/react';
+
+import NavigationBasedComponent from './NavigationBasedComponent';
+
+const meta: Meta = {
+ component: NavigationBasedComponent,
+ parameters: {
+ nextjs: {
+ appDirectory: true,
+ navigation: {
+ segments: [
+ ['slug', 'hello'],
+ ['framework', 'nextjs'],
+ ],
+ },
+ },
+ },
+};
+export default meta;
+```
diff --git a/docs/snippets/react/nextjs-navigation-segments-override-in-meta.js.mdx b/docs/snippets/react/nextjs-navigation-segments-override-in-meta.js.mdx
new file mode 100644
index 000000000000..ae72d38b5b6a
--- /dev/null
+++ b/docs/snippets/react/nextjs-navigation-segments-override-in-meta.js.mdx
@@ -0,0 +1,16 @@
+```js
+// NavigationBasedComponent.stories.js
+import NavigationBasedComponent from './NavigationBasedComponent';
+
+export default {
+ component: NavigationBasedComponent,
+ parameters: {
+ nextjs: {
+ appDirectory: true,
+ navigation: {
+ segments: ['dashboard', 'analytics'],
+ },
+ },
+ },
+};
+```
diff --git a/docs/snippets/react/nextjs-navigation-segments-override-in-meta.ts-4-9.mdx b/docs/snippets/react/nextjs-navigation-segments-override-in-meta.ts-4-9.mdx
new file mode 100644
index 000000000000..28ef22f5ba8f
--- /dev/null
+++ b/docs/snippets/react/nextjs-navigation-segments-override-in-meta.ts-4-9.mdx
@@ -0,0 +1,19 @@
+```ts
+// NavigationBasedComponent.stories.ts
+import { Meta, StoryObj } from '@storybook/react';
+
+import NavigationBasedComponent from './NavigationBasedComponent';
+
+const meta = {
+ component: NavigationBasedComponent,
+ parameters: {
+ nextjs: {
+ appDirectory: true,
+ navigation: {
+ segments: ['dashboard', 'analytics'],
+ },
+ },
+ },
+} satisfies Meta;
+export default meta;
+```
diff --git a/docs/snippets/react/nextjs-navigation-segments-override-in-meta.ts.mdx b/docs/snippets/react/nextjs-navigation-segments-override-in-meta.ts.mdx
new file mode 100644
index 000000000000..7621ca48ff34
--- /dev/null
+++ b/docs/snippets/react/nextjs-navigation-segments-override-in-meta.ts.mdx
@@ -0,0 +1,19 @@
+```ts
+// NavigationBasedComponent.stories.ts
+import { Meta, StoryObj } from '@storybook/react';
+
+import NavigationBasedComponent from './NavigationBasedComponent';
+
+const meta: Meta = {
+ component: NavigationBasedComponent,
+ parameters: {
+ nextjs: {
+ appDirectory: true,
+ navigation: {
+ segments: ['dashboard', 'analytics'],
+ },
+ },
+ },
+};
+export default meta;
+```
diff --git a/docs/snippets/react/nextjs-remove-addons.js.mdx b/docs/snippets/react/nextjs-remove-addons.js.mdx
new file mode 100644
index 000000000000..51a0c7a29902
--- /dev/null
+++ b/docs/snippets/react/nextjs-remove-addons.js.mdx
@@ -0,0 +1,12 @@
+```js
+// .storybook/main.js
+export default {
+ // ...
+ addons: [
+ // ...
+ // π These can both be removed
+ // 'storybook-addon-next',
+ // 'storybook-addon-next-router',
+ ],
+};
+```
diff --git a/docs/snippets/react/nextjs-remove-addons.ts.mdx b/docs/snippets/react/nextjs-remove-addons.ts.mdx
new file mode 100644
index 000000000000..5cc33f78e218
--- /dev/null
+++ b/docs/snippets/react/nextjs-remove-addons.ts.mdx
@@ -0,0 +1,16 @@
+```ts
+// .storybook/main.ts
+import { StorybookConfig } from '@storybook/nextjs';
+
+const config: StorybookConfig = {
+ // ...
+ addons: [
+ // ...
+ // π These can both be removed
+ // 'storybook-addon-next',
+ // 'storybook-addon-next-router',
+ ],
+};
+
+export default config;
+```
diff --git a/docs/snippets/react/nextjs-router-override-in-story.js.mdx b/docs/snippets/react/nextjs-router-override-in-story.js.mdx
new file mode 100644
index 000000000000..d631f61cbc8c
--- /dev/null
+++ b/docs/snippets/react/nextjs-router-override-in-story.js.mdx
@@ -0,0 +1,24 @@
+```js
+// RouterBasedComponent.stories.js
+import RouterBasedComponent from './RouterBasedComponent';
+
+export default {
+ component: RouterBasedComponent,
+};
+
+// If you have the actions addon,
+// you can interact with the links and see the route change events there
+export const Example = {
+ parameters: {
+ nextjs: {
+ router: {
+ pathname: '/profile/[id]',
+ asPath: '/profile/1',
+ query: {
+ id: '1',
+ },
+ },
+ },
+ },
+};
+```
diff --git a/docs/snippets/react/nextjs-router-override-in-story.ts-4-9.mdx b/docs/snippets/react/nextjs-router-override-in-story.ts-4-9.mdx
new file mode 100644
index 000000000000..649fc74cf357
--- /dev/null
+++ b/docs/snippets/react/nextjs-router-override-in-story.ts-4-9.mdx
@@ -0,0 +1,29 @@
+```ts
+// RouterBasedComponent.stories.ts
+import { Meta, StoryObj } from '@storybook/react';
+
+import RouterBasedComponent from './RouterBasedComponent';
+
+const meta = {
+ component: RouterBasedComponent,
+} satisfies Meta;
+export default meta;
+
+type Story = StoryObj;
+
+// If you have the actions addon,
+// you can interact with the links and see the route change events there
+export const Example: Story = {
+ parameters: {
+ nextjs: {
+ router: {
+ pathname: '/profile/[id]',
+ asPath: '/profile/1',
+ query: {
+ id: '1',
+ },
+ },
+ },
+ },
+};
+```
diff --git a/docs/snippets/react/nextjs-router-override-in-story.ts.mdx b/docs/snippets/react/nextjs-router-override-in-story.ts.mdx
new file mode 100644
index 000000000000..3cdf5037ab4f
--- /dev/null
+++ b/docs/snippets/react/nextjs-router-override-in-story.ts.mdx
@@ -0,0 +1,29 @@
+```ts
+// RouterBasedComponent.stories.ts
+import { Meta, StoryObj } from '@storybook/react';
+
+import RouterBasedComponent from './RouterBasedComponent';
+
+const meta: Meta = {
+ component: RouterBasedComponent,
+};
+export default meta;
+
+type Story = StoryObj;
+
+// If you have the actions addon,
+// you can interact with the links and see the route change events there
+export const Example: Story = {
+ parameters: {
+ nextjs: {
+ router: {
+ pathname: '/profile/[id]',
+ asPath: '/profile/1',
+ query: {
+ id: '1',
+ },
+ },
+ },
+ },
+};
+```
diff --git a/docs/snippets/react/nextjs-router-push-override-in-preview.js.mdx b/docs/snippets/react/nextjs-router-push-override-in-preview.js.mdx
new file mode 100644
index 000000000000..b5e94878eee6
--- /dev/null
+++ b/docs/snippets/react/nextjs-router-push-override-in-preview.js.mdx
@@ -0,0 +1,21 @@
+```js
+// .storybook/preview.js
+
+export default {
+ // ...
+ parameters: {
+ // ...
+ nextjs: {
+ router: {
+ push(...args) {
+ // Custom logic can go here
+ // This logs to the Actions panel
+ action('nextRouter.push')(...args);
+ // Return whatever you want here
+ return Promise.resolve(true);
+ },
+ },
+ },
+ },
+};
+```
diff --git a/docs/snippets/react/nextjs-router-push-override-in-preview.ts.mdx b/docs/snippets/react/nextjs-router-push-override-in-preview.ts.mdx
new file mode 100644
index 000000000000..a1ae3c70fe6d
--- /dev/null
+++ b/docs/snippets/react/nextjs-router-push-override-in-preview.ts.mdx
@@ -0,0 +1,24 @@
+```ts
+// .storybook/preview.ts
+import { Preview } from '@storybook/react';
+
+const preview: Preview = {
+ // ...
+ parameters: {
+ // ...
+ nextjs: {
+ router: {
+ push(...args) {
+ // Custom logic can go here
+ // This logs to the Actions panel
+ action('nextRouter.push')(...args);
+ // Return whatever you want here
+ return Promise.resolve(true);
+ },
+ },
+ },
+ },
+};
+
+export default preview;
+```
diff --git a/docs/snippets/react/rsc-feature-flag.js.mdx b/docs/snippets/react/rsc-feature-flag.js.mdx
new file mode 100644
index 000000000000..82a2678bc411
--- /dev/null
+++ b/docs/snippets/react/rsc-feature-flag.js.mdx
@@ -0,0 +1,9 @@
+```js
+// .storybook/main.js
+export default {
+ // ...
+ features: {
+ experimentalRSC: true,
+ },
+};
+```
diff --git a/docs/snippets/react/rsc-feature-flag.ts.mdx b/docs/snippets/react/rsc-feature-flag.ts.mdx
new file mode 100644
index 000000000000..10b8a03ee75b
--- /dev/null
+++ b/docs/snippets/react/rsc-feature-flag.ts.mdx
@@ -0,0 +1,13 @@
+```ts
+// .storybook/main.ts
+import { StorybookConfig } from '@storybook/nextjs';
+
+const config: StorybookConfig = {
+ // ...
+ features: {
+ experimentalRSC: true,
+ },
+};
+
+export default config;
+```
diff --git a/docs/snippets/react/rsc-parameter-in-meta.js.mdx b/docs/snippets/react/rsc-parameter-in-meta.js.mdx
new file mode 100644
index 000000000000..c0247429a675
--- /dev/null
+++ b/docs/snippets/react/rsc-parameter-in-meta.js.mdx
@@ -0,0 +1,11 @@
+```js
+// MyServerComponent.stories.js
+import MyServerComponent from './MyServerComponent';
+
+export default {
+ component: MyServerComponent,
+ parameters: {
+ react: { rsc: false },
+ },
+};
+```
diff --git a/docs/snippets/react/rsc-parameter-in-meta.ts-4-9.mdx b/docs/snippets/react/rsc-parameter-in-meta.ts-4-9.mdx
new file mode 100644
index 000000000000..a9331a6bf74f
--- /dev/null
+++ b/docs/snippets/react/rsc-parameter-in-meta.ts-4-9.mdx
@@ -0,0 +1,14 @@
+```ts
+// MyServerComponent.stories.ts
+import { Meta, StoryObj } from '@storybook/react';
+
+import MyServerComponent from './MyServerComponent';
+
+const meta = {
+ component: MyServerComponent,
+ parameters: {
+ react: { rsc: false },
+ },
+} satisfies Meta;
+export default meta;
+```
diff --git a/docs/snippets/react/rsc-parameter-in-meta.ts.mdx b/docs/snippets/react/rsc-parameter-in-meta.ts.mdx
new file mode 100644
index 000000000000..2b512d759ca4
--- /dev/null
+++ b/docs/snippets/react/rsc-parameter-in-meta.ts.mdx
@@ -0,0 +1,14 @@
+```ts
+// MyServerComponent.stories.ts
+import { Meta, StoryObj } from '@storybook/react';
+
+import MyServerComponent from './MyServerComponent';
+
+const meta: Meta = {
+ component: MyServerComponent,
+ parameters: {
+ react: { rsc: false },
+ },
+};
+export default meta;
+```
diff --git a/docs/toc.js b/docs/toc.js
index 96afc9c56542..3842ff52af5a 100644
--- a/docs/toc.js
+++ b/docs/toc.js
@@ -18,6 +18,18 @@ module.exports = {
type: 'link',
description: 'Install the Storybook package in your project',
},
+ {
+ pathSegment: '',
+ title: 'Frameworks',
+ type: 'menu',
+ children: [
+ {
+ pathSegment: 'nextjs',
+ title: 'Next.js',
+ type: 'link',
+ },
+ ],
+ },
{
pathSegment: 'whats-a-story',
title: "What's a story?",