storybook
storybook copied to clipboard
[Bug]: Storybook 7 + builder-vite doesn't support deploy to subpath
Describe the bug
I tried to configure and deploy my storybook to subpath /storybook
. For that, I added new base path to vite config
async viteFinal(config) {
return mergeConfig(config, {
base: "/storybook/",
});
},
After deploying the new build, I found that only some of the paths had changed to '/storybook', the rest remained unchanged.
To Reproduce
https://github.com/akronb/storybook7-vite-subpath-example
The generated build is already in the directory storybook-static
System
Environment Info:
System:
OS: macOS 13.1
CPU: (8) arm64 Apple M1
Binaries:
Node: 16.15.1 - /opt/homebrew/opt/node@16/bin/node
Yarn: 1.22.19 - /opt/homebrew/opt/node@16/bin/yarn
npm: 8.11.0 - /opt/homebrew/opt/node@16/bin/npm
Browsers:
Chrome: 111.0.5563.64
Safari: 16.2
npmPackages:
@storybook/addon-essentials: ^7.0.0-rc.3 => 7.0.0-rc.3
@storybook/addon-interactions: ^7.0.0-rc.3 => 7.0.0-rc.3
@storybook/addon-links: ^7.0.0-rc.3 => 7.0.0-rc.3
@storybook/blocks: ^7.0.0-rc.3 => 7.0.0-rc.3
@storybook/react: ^7.0.0-rc.3 => 7.0.0-rc.3
@storybook/react-vite: ^7.0.0-rc.3 => 7.0.0-rc.3
@storybook/testing-library: ^0.0.14-next.1 => 0.0.14-next.1
Additional context
No response
The default base is relative should allow for deploying in a subpath, for example in github pages. Can you explain a bit more about how you are deploying the storybook?
Can you explain a bit more about how you are deploying the storybook?
The Storybook is put into a docker container with nginx, and the container distributes it to http://mysite.io/storybook.
After your comment, I looked into nginx behavior and stackoverflow, and it turned out that the problem was a lack of trailing slash.
For the URL http://mysite.io/storybook, the browser converts <link href="./sb-preview/runtime.mjs" rel="preload" as="script" />
to http://mysite.io/sb-preview/runtime.mjs
, because the relative path is built from the last / in the URL.
I still have a question about the base path in vite config. It was added to some of the paths (like /assets/iframe.js
), the rest remain relative. Shouldn't the behavior be consistent?
Shouldn't the behavior be consistent?
Yes, but I think some of those paths are created by parts of storybook that are not part of the preview / vite builder. I haven't dug into it, but that's my guess as to what is happening.
Any update on this?
@Stunext are you having issues? Can you describe what they are? Storybook can be deployed to a subpath so long as you don't set a base
config. As far as I know, nobody has done any further work on this to support setting the base
explicitly. Is that something you need to do?
Maybe it's my mistake... I've created a component library in React that I install in other projects via Git. The library is implemented on top of storybook and a static version of the storybook is also included in the library installation. At the same time the library exports a plugin for Vite that implemented redirects the path that starts with "/storybook" to the folder in node_modules of the storybook build. So that during "vite dev" you can access the library documentation directly in a project path.
The problem is that the paths in the storybook build ignore this additional "/storybook/" path and try to access from the "/" root even by adding base: "/storybook/",
in viteFinal. Due to not being able to solve the problem I am left with this monstrosity in the plugin.
export default function ProjectLib() {
return {
name: 'project-lib',
configureServer(server) {
server.middlewares.use(async(req, res, next) => {
try {
let referer = req.headers.referer;
let url = req.url.split(/[?#]/)[0];
let filePath = '';
switch (true)
{
case url.startsWith('/storybook'):
{
filePath = resolve(__dirname, 'node_modules/project-lib/dist/docs/index.html')
createReadStream(filePath).pipe(res)
}
break;
case url.startsWith('/sb-common-assets'):
case url.startsWith('/sb-manager'):
case url.startsWith('/sb-addons'):
case url.startsWith('/sb-preview'):
case url.startsWith('/static'):
case url.startsWith('/assets'):
{
filePath = resolve(__dirname, 'node_modules/project-lib/dist/docs/' + url)
if (statSync(filePath).isDirectory())
{
filePath = resolve(filePath, 'index.html')
}
if (statSync(filePath).isFile())
{
if (filePath.endsWith('.js') || filePath.endsWith('.mjs'))
{
res.setHeader('Content-Type', 'application/javascript');
}
createReadStream(filePath).pipe(res)
}
}
break;
case referer.endsWith('/storybook'):
{
filePath = resolve(__dirname, 'node_modules/project-lib/dist/docs' + url)
if (filePath.endsWith('.js') || filePath.endsWith('.mjs'))
{
res.setHeader('Content-Type', 'application/javascript');
}
createReadStream(filePath).pipe(res)
}
break;
case referer.includes('/storybook?path'):
case referer.includes('/iframe.html?viewMode'):
{
filePath = resolve(__dirname, 'node_modules/project-lib/dist/docs' + url)
if (statSync(filePath).isDirectory())
{
filePath = resolve(filePath, 'index.html')
}
if (statSync(filePath).isFile())
{
if (filePath.endsWith('.js') || filePath.endsWith('.mjs'))
{
res.setHeader('Content-Type', 'application/javascript');
}
createReadStream(filePath).pipe(res)
}
}
break;
default:
{
next()
}
break;
}
} catch (error) {
next()
}
})
}
}
}
This works for me (using with Nuxt 3 as the webserver, eg: npm run build-storybook -- -o public/storybook && nuxt build
):
managerHead: (head, { configType }) => {
if (configType === 'PRODUCTION') {
return (`
${head}
<base href="/storybook/">
`);
}
},
async viteFinal(baseConfig, { configType }) {
return mergeConfig(
baseConfig,
{
...(configType === 'PRODUCTION' ? { base: '/storybook/' } : {}),
// rest of config...
}
)
Hi there! Thank you for opening this issue, but it has been marked as stale
because we need more information to move forward. Could you please provide us with the requested reproduction or additional information that could help us better understand the problem? We'd love to resolve this issue, but we can't do it without your help!
I'm afraid we need to close this issue for now, since we can't take any action without the requested reproduction or additional information. But please don't hesitate to open a new issue if the problem persists – we're always happy to help. Thanks so much for your understanding.
Any progress? This is NOT fixed as v7.5.3.