Describe the bug
When using <Preview /> to render a component in a mdx file, it doesn't show the code sample unless the sample also defines a story using <Story /> in the child.
To Reproduce
Use the following in a stories.js file;
import BoxReadMe from './Box.mdx';
const stories = storiesOf('Atoms/Box', module);
stories.addParameters({
docs: {
page: BoxReadMe,
},
});
And then put this in the mdx file.
<Preview>
<Box
label="Montezuma the Cat"
description="Montezuma is honestly the best cat I've ever seen."
/>
</Preview>
You'll get No Code Available.
Expected behavior
I expect it to show the code that is used to power whatever is placed within the Preview components.
Additional context
I'm unsure if this is a bug or not, but I feel the name Preview is a little bit confusing.
This should be fixed in #7966 and available in 5.3.0-alpha.x
@shilman Is this currently in an alpha release? I tried .24 and it doesn't appear to be working still.
@JamesIves yeah i'm classifying this as a feature, so it will be part of 5.3.0 according to sever. released in 5.3.0-alpha.x
@shilman I think there might have been a misunderstanding of the issue.
I tried out 5.3.0-alpha.24 and the problem still seems to happen. #7996 that you linked also seems to be different than the problem that we're experiencing.
@RohitRajendran Sorry it's #7966. What does your Preview block look like? And how does it display?
<Preview>
<Box
label="Montezuma the Cat"
description="Montezuma is honestly the best cat I've ever seen."
/>
</Preview>
It's currently showing the following, but you'll note it says No Code Available.

Version: Storybook 5.3.0-alpha.24.
@atanasster would you mind looking into this?
@JamesIves
() => {
const Docs = markdown.parameters.docs.page;
return <Docs />;
}
here is the source:
https://github.com/storybookjs/storybook/blob/next/examples/official-storybook/stories/addon-docs/mdx.stories.js

@JamesIves you need to:
Box.mdx to Box.stories.mdx*.mdx get passed through the storybook MDX compilerRenaming it to stories.mdx results in the need for a Meta tag, without one it throws an error due to a missing title. Is there a way to associate a stories.mdx file with a stories.js file? The pattern I'm following in the original post results in an error, and naming the meta title in the mdx file the same as the storiesOf title also throws an error.
It does work however if the titles are unique, but that's not ideal because it doesn't create an association.
@JamesIves HMMmmm 馃
Take a look at https://github.com/storybookjs/storybook/blob/next/addons/docs/docs/recipes.md#csf-stories-with-mdx-docs
This pattern is only available in 5.3, but would that work for you?
@JamesIves HMMmmm 馃
Take a look at https://github.com/storybookjs/storybook/blob/next/addons/docs/docs/recipes.md#csf-stories-with-mdx-docs
This pattern is only available in 5.3, but would that work for you?
Sorry I have so many questions.
I attempted this pattern using the following:
TwitterIcon.stories.js
import React from 'react';
import TwitterIcon from './TwitterIcon';
import {text} from '@storybook/addon-knobs';
const defaultProps = () => ({
fill: text('fill', '#000'),
height: text('height', '2rem'),
width: text('width', '2rem'),
});
export default {
title: 'Atoms/Icons/TwitterIcon',
component: TwitterIcon,
includedStories: ['basic'],
}
const basic = () => <TwitterIcon {...defaultProps()} />;
basic.story = {
title: 'story'
}
And within TwitterIcon.stories.mdx
import {Preview, Props, Meta} from '@storybook/addon-docs/blocks';
import TwitterIcon from './TwitterIcon';
<Meta title="Atoms/Icons/TwitterIcon" component={TwitterIcon} />
# TwitterIcon
The TwitterIcon component creates a Twitter social media icon using inline SVG. This icon is typically used within page/content footers and headers.
## Importing 馃摝
## Example 馃殌
<Preview>
<TwitterIcon
height="3rem"
width="3rem"
fill="#000"
/>
</Preview>
The problem I'm running into now is that it doesn't generate the basic story, instead now all I see is the Docs page. Am I missing something from the CSF export to ensure this displays?
@JamesIves You need to follow the recipe. In this recipe, the .stories.js is just defining JS functions that get used in the MDX, so this line is key:
includeStories: [], // or don't load this file at all
Then, in .stories.mdx you'd actually define the story there:
<Story name="story">{stories.basic}</Story>
It would probably be a lot easier if you just did everything in MDX?
The issue with both of these recipes (mdx and csf with mdx) is that I can't define stories without showing the preview for them. If I define the stories directly in the mdx file I end up with this issue #8342 which was the inspiration behind having the mdx file be purely documentation for the stories in the .stories.js file. It also means I'll have to define multiple stories that don't flow well with the documentation purely for snapshot testing which isn't ideal
I feel like I could probably hide the story definitions using a div, but that feels very hacky. Maybe there should be some sort of wrapper component from addon-blocks that handles this?
I wish I could just override the docs page and have code previews without it running through the Storybook mdx compiler 馃槩
@JamesIves Sorry this is ending up being such an ordeal for you. Hopefully we can get a clean recipe going for you that satisfies all your needs. A few things...
1) You can disable stories from displaying in MDX:
<Story name="foo" parameters={{ docs: { disable: true }}} />
...
</Story>
2) I could imagine a version of the MDX compiler which runs on all your MDX files and handles this preview case, and another pass that only applies to .stories.mdx which requires Meta and generates exports for Story elements.
Can confirm this is also a pain point for me, i would much rather keep my stories and docs seperate. @shilman are you planning on supporting preview blocks like this when .mdx files are used purely for docs?
@sami616 You can already create a docs-only .stories.mdx file and use:
<Preview>
<div>some code</div>
</Preview
@shilman right, but not when it's used in the context detailed in this issue? ie calling the docs page for my story Accordion.docs.mdx and consuming it via
Accordion.story = {
parameters: {
docs: { page: accordionMDX },
},
}
I see No code available just like @JamesIves
@shilman I'm seeing the exact same issue as @sami616 on 5.3.18 everything. I have to have my stories as CSF to be able to integrate them with InVision DSM.
@shilman code is available but its not the output its the export in CSF file - would be great to get the rendered output
Does it work with the v6 version @shilman ?
We are experiencing the same issue. Preview is not visible if importing the mdx file :/ We are on a 5.3 version.
Which pattern are you using @darkowic ?
The following are all working in 6.0:
import { importedCsf } from './csf.stories.js';
<Canvas>
<div>some jsx</div>
</Canvas>
<Canvas>
<Story name="some story"><div>some story</div></Story>
</Canvas>
<Canvas>
<Story name="imported CSF story" story={importedCsf} />
</Canvas>
@shilman the pattern from the original question here or what others have been asking above here:
@shilman right, but not when it's used in the context detailed in this issue? ie calling the docs page for my story Accordion.docs.mdx and consuming it via
Accordion.story = { parameters: { docs: { page: accordionMDX }, }, }I see
No code availablejust like @JamesIves
or here:
Renaming it to
stories.mdxresults in the need for aMetatag, without one it throws an error due to a missing title. Is there a way to associate astories.mdxfile with astories.jsfile? The pattern I'm following in the original post results in an error, and naming the meta title in the mdx file the same as thestoriesOftitle also throws an error.It does work however if the titles are unique, but that's not ideal because it doesn't create an association.
For 5.3, the preview is visible only if the MDX files are parsed by the story parser. It won't work without Meta but Meta creates a new docs page visible in the navigation. What we want to achieve, is to connect the MDX file with a story without creating additional stories:
import cardsDocs from './cards.mdx';
export default {
title: 'Components/Cards',
component: Card,
parameters: {
docs: {
page: cardsDocs,
},
},
};
@darkowic the recommended way is embedding CSF in MDX, and it's supported quite well in 6.0, IMO, with the <Story story={importedCsf} /> construct. Is there a reason why you don't want to use that pattern?
Our use-case is that we have some Component story (with knobs/controls) and we want to have a docs page for it. We want to switch between the docs page and the example by using the tabs (Canvas and Docs). The docs page describes the component details (with some code samples) and how it works and the canvas is a simple playground. We want to keep the docs page in a separate mdx file. That's it. Well, sounds like pretty common approach ;) But maybe we should rethink our storybooks approach.
@darkowic I believe the recommended recipe I described above will suit your needs (and actually work in storybook). More info here: https://github.com/storybookjs/storybook/blob/next/addons/docs/docs/recipes.md#csf-stories-with-mdx-docs
The recipe at https://github.com/storybookjs/storybook/blob/next/addons/docs/docs/recipes.md#csf-stories-with-mdx-docs does not work (storybook 6.0.16) as intended, and does not explain where to add includeStories: [] when it cannot go inside the default export you are not supposed to have in the CSF example.
Use case: I want to create a docs page that has stories, without creating a story/menu entry for every story used in the MDX.
That said, Preview seems to offer just what I need.
@lars-bo-colourbox can you explain what doesn't work in that recipe? the includeStories comment above was from 5.2. storybook is now 6.0 and the recommendation has changed.
@shilman The recipe says "Your stories are defined in CSF, but because of includeStories: [], they are not actually added to Storybook." But the stories are added to storybook.
Shouldn't the recipe be updated to match Storybook 6? Or explicitly say that it's for 5.2? As it is, a piece of code is referred to (includeStories: []), although it is not mentioned anywhere on the page.
I am new to SB 6, and I find it hard to find comprehensive documentation. Like a list of components @storybook/addon-docs/blocks gives us, and which props they have.
Also, it would be helpful to address the issues people will have with components using createPortal (obviously), and forwardRef (maybe less obvious). It can all be done, but it would be great to know how instead of spending hours of trial and failure.
Apart from that, upgrading from 5 to 6 feels like going from 5 to 10. Someone did an absolutely amazing job.
Most helpful comment
@shilman right, but not when it's used in the context detailed in this issue? ie calling the docs page for my story Accordion.docs.mdx and consuming it via
I see
No code availablejust like @JamesIves