Skip to content

[Bug]: AI manifests/snippets ignore external demo source and docs.source.code when CSF stories render imported wrapper components #34492

@geraldlrh

Description

@geraldlrh

Describe the bug

When a CSF story uses an imported wrapper/demo component, Storybook AI manifests generate the story snippet from the wrapper usage in the .stories.tsx file instead of
the actual demo source.

For example, if the story is written like this:

import type { Meta, StoryObj } from '@storybook/react';
import { Button } from 'antd-mobile';
import React from 'react';
import _Demo01 from './demo01';

const meta = {
  title: 'General/Button',
  component: Button,
} satisfies Meta<typeof Button>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Demo01: Story = {
  name: 'Page',
  render: () => <_Demo01 />,
};

and ./demo01.tsx contains the actual example source, the generated manifest snippet is still something like:

const Demo01 = () => <_Demo01 />;

instead of the real source from demo01.tsx.

This also appears to ignore parameters.docs.source.code / docs.source.originalSource as an override for the AI manifest snippet.

Actual behavior

The manifest snippet is based on the inline story render wrapper from the .stories.tsx file:

const Demo01 = () => <_Demo01 />;

Expected behavior

One of the following should happen:

  1. Storybook should respect parameters.docs.source.code / docs.source.originalSource for AI manifest snippets.
  2. Or Storybook should provide a hook/plugin API to preprocess story source before snippet extraction.
  3. Or Storybook should support resolving simple imported wrapper components when generating snippets.

At minimum, it would be helpful if the behavior were documented clearly.

Why this is a problem

A common pattern is to keep demos/examples in separate files and keep .stories.tsx minimal. In that setup, the generated AI manifest snippet becomes low-value because it
only shows the wrapper component usage, not the actual example code.

Reproduction link

example code see above

Reproduction steps

  1. Create a story file that imports an external demo/wrapper component:

    import _Demo01 from './demo01';

    export const Demo01: Story = {
    render: () => <_Demo01 />,
    };

  2. Put the actual example implementation in demo01.tsx.

  3. Run Storybook with AI manifests enabled.

  4. Inspect the generated manifest.``

System

- Storybook: 10.3.4
  - @storybook/csf-plugin: 10.3.4
  - storybook-react-rsbuild: 3.3.2
  - React: 19
  - Builder: Rsbuild / Rspack
  - Node: 24.11.1

Additional context

Technical context

From local inspection, the source snippet generation seems to happen in @storybook/csf-plugin, where the loader reads the raw .stories.tsx file from disk and parses that
source again for CSF enrichment. In other words, bundler/runtime transforms do not affect the snippet extraction path.

That means:

  • transforming the story at bundler level does not help
  • overriding docs.source.code also does not appear to affect the AI manifest snippet

This makes it difficult to customize snippet generation for stories that delegate rendering to external demo files.

Question

Is this the intended behavior for AI manifests/snippets, or would you consider supporting an override/preprocess mechanism for this use case?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions