title |
---|
MDX |
MDX files mix Markdown and Javascript/JSX to create rich interactive documentation. You can use Markdown’s readable syntax (such as # heading
) for your documentation, include stories defined in Component Story Format (CSF), and freely embed JSX component blocks at any point in the file. All at once.
In addition, you can write pure documentation pages in MDX and add them to Storybook alongside your stories.
Writing stories directly in MDX was deprecated in Storybook 7. Please reference the previous documentation for guidance on that feature.
Let's get started with an example, Checkbox.mdx
, that combines Markdown with a single story.
<CodeSnippets paths={[ 'common/checkbox-story.mdx.mdx', ]} />
This MDX file references a story file, Checkbox.stories.js
, that is written in Component Story Format (CSF):
<CodeSnippets paths={[ 'common/checkbox-story-csf.js.mdx', ]} usesCsf3 csf2Path="writing-docs/mdx#snippet-checkbox-story-csf" />
And here's how that's rendered in Storybook:
There’s a lot going on here. We're writing Markdown, we're writing JSX, and we're also defining and referencing Storybook stories that are drop-in compatible with the entire Storybook ecosystem.
Let’s break it down.
The first thing you'll notice is that the component documentation is divided into distinct formats: one for writing component stories describing each possible component state and the second one for documenting how to use them. This split leverages the best qualities of each format:
- CSF is great for succinctly defining stories (component examples). If you use TypeScript, it also provides type safety and auto-completion.
- MDX is great for writing structured documentation and composing it with interactive JSX elements.
💡 If you’re coming from a previous version of Storybook, you might be accustomed to using MDX both for documentation and for defining stories in the same .stories.mdx
file. We’ve deprecated this functionality and plan to remove it in a future version of Storybook. We provide migration scripts to help you onto the new format.
Assuming you’re already familiar with writing stories with CSF, we can dissect the MDX side of things in greater detail.
The document consists of a number of blocks separated by blank lines. Since MDX mixes a few different languages together, it uses those blank lines to help distinguish where one starts, and the next begins. Failing to separate blocks by whitespace can cause (sometimes cryptic) parse errors.
Going through the code blocks in sequence:
{ /* Checkbox.mdx */ }
Comments in MDX are JSX blocks that contain JS comments.
<CodeSnippets paths={[ 'common/storybook-auto-docs-mdx-docs-imports.mdx.mdx', ]} />
Imports the components and stories that will be used in the JSX throughout the rest of the file.
<CodeSnippets paths={[ 'common/storybook-auto-docs-mdx-docs-meta-block.mdx.mdx', ]} />
The Meta
block defines where the document will be placed in the sidebar. In this case, it is adjacent to the Checkbox’s stories. By default, the docs sidebar node is titled "Docs"
, but this can be customized by passing a name
prop (e.g., <Meta of={CheckboxStories} name="Info" />
). If you want to place a docs node at an arbitrary point in the navigation hierarchy, you can use the title
prop (e.g., <Meta title="path/to/node" />
).
<CodeSnippets paths={[ 'common/storybook-auto-docs-mdx-docs-definition.mdx.mdx', ]} />
MDX2 supports standard markdown (”commonmark”) by default and can be extended to support GitHub-flavored markdown (GFM) and other extensions (see Breaking changes, below).
<CodeSnippets paths={[ 'common/storybook-auto-docs-mdx-docs-story.mdx.mdx', ]} />
Finally, MDX supports blocks of arbitrary JSX.
In this case, we are leveraging “Doc Blocks”, a library of documentation components designed to work with Storybook stories to show your stories, your component APIs & controls for interacting with your components inside your documentation, among other utilities.
In addition to Doc Blocks, MDX can incorporate arbitrary React components, making it a very flexible documentation system. Suppose you want a stylized list of “dos and don’ts” for your component; you can use off-the-shelf components or write your own.
<CodeSnippets paths={[ 'common/storybook-auto-docs-mdx-docs-dos-donts.mdx.mdx', ]} />
While MDX2 supports a variety of runtimes (React, Preact, Vue), Storybook’s implementation is React-only. That means your documentation is rendered in React, while your stories render in the runtime of your choice (React, Vue, Angular, Web Components, Svelte, etc.).
There are a lot of breaking changes if you’re moving from MDX1 to MDX2. As far as we know, all of these are due to changes in the MDX library itself rather than changes to Storybook’s usage. Nevertheless, as an MDX user, you will probably need to update your MDX files as part of the upgrade. MDX has published their own Migration guide. Here we try to summarize some of the key changes for Storybook users.
From the MDX migration guide:
We now “sandbox” components, for lack of a better name. It means that when you pass a component for
h1
, it does get used for# hi
but not for<h1>hi</h1>
This means that the first heading in the following example gets replaced, whereas the second does not. It may not sound like a significant change, but in practice, it is highly disruptive and manifests itself in various ways. Unfortunately, this cannot be automatically converted in a safe way.
# Some heading
<h1>another heading</h1>
Also, from the MDX migration guide:
We turned off GFM features in MDX by default. GFM extends CommonMark to add autolink literals, footnotes, strikethrough, tables, and task lists. If you do want these features, you can use a plugin. How to do so is described in our guide on GFM.
In Storybook, you can apply MDX options, including plugins, in the main configuration file:
<CodeSnippets paths={[ 'common/storybook-main-config-remark-options.js.mdx', 'common/storybook-main-config-remark-options.ts.mdx', ]} />
💡 The remark-gfm
package isn't provided by default during migration. We recommend installing it as a development dependency if you use its features.
To help you transition to the new version, we've created a migration helper in our CLI. We recommend using it and reaching out to the maintainers using the default communication channels (e.g., Discord server, GitHub issues) for problems you encounter.
npx storybook@next automigrate mdx1to2
MDX documents can also be used to create documentation-only pages. Suppose you're documenting an existing component and only provide a <Meta>
Doc Block without additional props or Story
blocks. In that case, Storybook will consider it as "documentation-only" and appear differently in the sidebar navigation menu:
<CodeSnippets paths={[ 'common/storybook-auto-docs-mdx-docs-docs-only-page.mdx.mdx', ]} />
When writing MDX, you may want to provide links to other stories or documentation pages and sections. You can use the path
query string.
Considering a story with ID some--id
, this redirects to the Docs tab of the story:
[Go to specific documentation page](?path=/docs/some--id)
This redirects to the Canvas tab of the story:
[Go to specific story canvas](?path=/story/some--id)
You can also use anchors to target a specific section of a page:
[Go to the conclusion of the documentation page](?path=/docs/some--id#conclusion)
- Docs for creating documentation for your stories
- MDX for customizing your documentation
- Publishing docs to automate the process of publishing your documentation