Skip to content

fix(builder-vite): disable Vite's publicDir to prevent double-copying static assets#34861

Closed
jesustorres-code wants to merge 1 commit into
storybookjs:mainfrom
jesustorres-code:fix/vite-builder-disable-public-dir-copy
Closed

fix(builder-vite): disable Vite's publicDir to prevent double-copying static assets#34861
jesustorres-code wants to merge 1 commit into
storybookjs:mainfrom
jesustorres-code:fix/vite-builder-disable-public-dir-copy

Conversation

@jesustorres-code
Copy link
Copy Markdown

@jesustorres-code jesustorres-code commented May 21, 2026

Summary

  • Root cause: Vite's built-in publicDir mechanism independently copies ../public to the build output root. When a user routes that same directory to a custom destination via staticDirs, it ends up copied twice — once by Vite to /, once by Storybook to the configured path. If ../public/index.json exists, it silently overwrites the Storybook-generated index.json, breaking story discovery.
  • Fix: Set publicDir: false in Storybook's shared Vite config (vite-config.ts) so Storybook owns all static file copying.
  • Backwards compat: Export a staticDirs preset from @storybook/builder-vite that re-adds ../public → / when the directory exists and the user hasn't already mapped it elsewhere. Existing projects get identical behavior without any config changes.

Changes

  • code/builders/builder-vite/src/vite-config.ts — add publicDir: false to sbConfig
  • code/builders/builder-vite/src/preset.ts — export staticDirs that mirrors Vite's default public dir behavior via Storybook's own copy mechanism

Test plan

  • Create a Vite + React project with Storybook, add public/index.json with {}
  • Set staticDirs: [{ from: '../public', to: '/foo' }] in .storybook/main.ts
  • Run build-storybookstorybook-static/index.json should contain valid story index data, not {}
  • storybook-static/foo/ should contain the public directory contents
  • Existing project with no staticDirs config: ../public still served at / (backwards compat)
  • Existing project with staticDirs: ['../public']: no duplicate copy, no regression

Closes #24627

Summary by CodeRabbit

  • Bug Fixes
    • Fixed static file handling in the Vite builder to prevent duplicate copying of public directory contents. Static assets are now managed through the staticDirs configuration, with Vite's public directory disabled to avoid conflicts.

Review Change Stack

… static assets

When a user configures `staticDirs` with a custom destination (e.g.
`{ from: '../public', to: '/foo' }`), Vite's own `publicDir` mechanism
was independently copying `../public` to the build root in addition to
wherever `staticDirs` directed it. This caused `../public/index.json`
to overwrite the Storybook-generated `index.json`, breaking builds.

Set `publicDir: false` in the shared Vite config so Storybook owns all
static asset copying via `staticDirs`. Export a `staticDirs` preset from
`@storybook/builder-vite` that mirrors the original Vite default behavior
(copy `../public` to `/`) when the directory exists and the user has not
already mapped it to a custom destination. This keeps existing projects
working without any config changes.

Fixes storybookjs#24627
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 40ea04fe-f95d-4af1-a617-ad5cdad2c432

📥 Commits

Reviewing files that changed from the base of the PR and between 229cf14 and e398885.

📒 Files selected for processing (2)
  • code/builders/builder-vite/src/preset.ts
  • code/builders/builder-vite/src/vite-config.ts

📝 Walkthrough

Walkthrough

The PR reconfigures how Storybook's Vite builder handles static files. Vite's default publicDir behavior is disabled via configuration, and a new staticDirs preset function is added to replicate that behavior through Storybook's static directory system, preventing duplicate file copying while maintaining backwards compatibility.

Changes

Static directory handling with Vite

Layer / File(s) Summary
Static directories preset function
code/builders/builder-vite/src/preset.ts
Module imports are expanded to include preset type utilities. A new staticDirs preset property function checks for a project-root public directory and appends a mapping { from: '../public', to: '/' } if present and not already configured.
Vite publicDir configuration
code/builders/builder-vite/src/vite-config.ts
publicDir: false is set in the base Vite config with inline comments explaining that Storybook handles static copying via staticDirs preset and this prevents double-copying.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • storybookjs/storybook#33438: Implements the publicDir: false + staticDirs default behavior to prevent Vite from redundantly copying static directories.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@valentinpalkovic
Copy link
Copy Markdown
Contributor

Superseded by #33703

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants