Describe the bug
When initially starting the dev server, it does a series of redirects. But it often (not always) ends up in this incorrect state:
/ -> /?path=/story/* -> /?path=/undefined/undefined
The side navigation is displayed correctly (all stories and links). However, the links are corrupt: ?path=/undefined/teststory--base-web
where the undefined
should be story
.
When I open the base URL manually again, it works. I can't reproduce this but it happens quite frequently (about half of times).
I have basic.stories.js
with title: "Test Story"
and export const BaseWeb
.
Expected behavior
The initial redirect should end up at:
/?path=/story/test-story--base-web
System:
Environment Info:
System:
OS: macOS 10.15.5
CPU: (8) x64 Intel(R) Core(TM) i7-8559U CPU @ 2.70GHz
Binaries:
Node: 10.16.3 - ~/.volta/tools/image/node/10.16.3/6.9.0/bin/node
Yarn: 1.19.1 - ~/.volta/tools/image/yarn/1.19.1/bin/yarn
npm: 6.9.0 - ~/.volta/tools/image/node/10.16.3/6.9.0/bin/npm
Browsers:
Chrome: 83.0.4103.106
Firefox: 77.0.1
Safari: 13.1.1
npmPackages:
@storybook/addon-a11y: 6.0.0-beta.33 => 6.0.0-beta.33
@storybook/addon-actions: 6.0.0-beta.33 => 6.0.0-beta.33
@storybook/addon-knobs: 6.0.0-beta.33 => 6.0.0-beta.33
@storybook/addon-links: 6.0.0-beta.33 => 6.0.0-beta.33
@storybook/addons: 6.0.0-beta.33 => 6.0.0-beta.33
@storybook/react: 6.0.0-beta.33 => 6.0.0-beta.33
We have the same (or similar overlapping) problem. I'll try to amend this comment with more details when I have more time later tonight. Thanks in advance for any help!
I'll try to create a standalone repro, and I'm happy to hop on a screenshare to troubleshoot together.
Setup
Development
Built/Deployed Storybook
Same symptoms as above, but navigating to different stories doesn't work without a full refresh each time.
.storybook/main.js
module.exports = {
stories: ['../src/**/*.stories.@(ts|tsx|mdx)'],
addons: ['@storybook/addon-actions', '@storybook/addon-links', '@storybook/addon-knobs/register'],
};
src/components/Button/Button.stories.tsx
import React from 'react';
import { action } from '@storybook/addon-actions';
import { withKnobs, text, boolean, select } from '@storybook/addon-knobs';
import Button from './Button';
export default {
title: 'Button',
component: Button,
decorators: [withKnobs],
};
export const button = () => (
<Button
variant={select(
'variant',
['primary', 'secondary', 'tertiary', 'link', 'adornment'],
'primary'
)}
disabled={boolean('disabled', false)}
href={text('href', '')}
small={boolean('small', false)}
margin={select('margin', ['normal', 'dense', 'none'], 'normal')}
loading={boolean('loading', false)}
uppercase={boolean('uppercase', false)}
onClick={action('Clicked button')}
>
{text('label', 'Hello World!')}
</Button>
);
@tajo / @chrislopresto thanks for the issue. Could you try the following?
logLevel: 'debug'
to main.js
The logs should include all the event messages (e.g "manager received setStories
") if 1&2 worked properly.
@tmeasday Here are some browser logs. I'll try to work on a repro later.
Text of 馃憜
manager received currentStoryWasSet _undefined_
manager received storyMissing _undefined_
manager received setStories
Object
error: null
globalArgs: {}
globalParameters: {}
kindParameters: Button: {framework: "react", component: {鈥, subcomponents: undefined, fileName: "./src/components/Button/Button.stories.tsx", args: undefined,聽鈥Menu: {framework: "react", component: {鈥, subcomponents: undefined, fileName: "./src/components/Menu/Menu.stories.tsx", args: undefined,聽鈥QuestionIconPopup: {framework: "react", component: {鈥, subcomponents: undefined, fileName: "./src/components/QuestionIconPopup/QuestionIconPopup.stories.tsx", args: undefined,聽鈥__proto__: Object
stories: button--button: {id: "button--button", kind: "Button", name: "Button", story: "Button", parameters: {鈥,聽鈥menu--menu: {id: "menu--menu", kind: "Menu", name: "Menu", story: "Menu", parameters: {鈥,聽鈥menu--menu-opens-left: {id: "menu--menu-opens-left", kind: "Menu", name: "Menu Opens Left", story: "Menu Opens Left", parameters: {鈥,聽鈥questioniconpopup--with-html: {id: "questioniconpopup--with-html", kind: "QuestionIconPopup", name: "With Html", story: "With Html", parameters: {鈥,聽鈥questioniconpopup--with-text: {id: "questioniconpopup--with-text", kind: "QuestionIconPopup", name: "With Text", story: "With Text", parameters: {鈥,聽鈥__proto__: Objectv: 2__proto__: Objectconstructor: 茠 Object()hasOwnProperty: 茠 hasOwnProperty()isPrototypeOf: 茠 isPrototypeOf()propertyIsEnumerable: 茠 propertyIsEnumerable()toLocaleString: 茠 toLocaleString()toString: 茠 toString()valueOf: 茠 valueOf()__defineGetter__: 茠 __defineGetter__()__defineSetter__: 茠 __defineSetter__()__lookupGetter__: 茠 __lookupGetter__()__lookupSetter__: 茠 __lookupSetter__()get __proto__: 茠 __proto__()set __proto__: 茠 __proto__()
index.js:39
preview received channelCreated
To throw a 馃敡 into the mix... or possibly help...
The initial story redirect does work somewhat consistently (not perfectly) if I am focused on the browser tab as it renders. If I right click on http://localhost:6006 and select "Open Link in New Window", the initial storybook redirect usually works:
The initial story does not usually work if I am not focused on the browser tab as it renders. If I right click on http://localhost:6006 and select "Open Link in New Tab", the initial storybook usually does NOT work:
@tajo / @chrislopresto thanks for the issue. Could you try the following?
manager received currentStoryWasSet _undefined_
manager received storyMissing _undefined_
manager received setStories
{
"v": 2,
"globalParameters": {},
"globalArgs": {},
"error": null,
"kindParameters": {
"TestStory": {
"framework": "react",
"fileName": "./src/__tests__/basic.stories.js"
}
},
"stories": {
"teststory--base-web": {
"id": "teststory--base-web",
"kind": "TestStory",
"name": "Base Web",
"story": "Base Web",
"parameters": {
"__id": "teststory--base-web",
"argTypes": {}
},
"args": {}
}
}
}
preview received sharedStateSet-manager-baseweb/bg Primary
preview received sharedStateSet-manager-baseweb/rtl false
preview received sharedStateSet-manager-baseweb/theme Light Move
preview received sharedStateSet-manager-baseweb/breakpoint __BREAKPOINT_NOT_SET
preview received sharedStateChanged-manager-baseweb/breakpoint __BREAKPOINT_NOT_SET
[HMR] connected
preview received storybook/a11y/highlight {}
preview received sharedStateChanged-manager-baseweb/bg _undefined_
preview received baseweb/change-bg _undefined_
preview received sharedStateChanged-manager-baseweb/rtl false
preview received baseweb/change-rtl false
preview received sharedStateChanged-manager-baseweb/theme _undefined_
preview received baseweb/change-theme _undefined_
DevTools failed to load SourceMap: Could not load content for http://localhost:51372/unfetch.mjs.map: HTTP error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILURE
manager received currentStoryWasSet
{
"storyId": "teststory--base-web",
"viewMode": "story"
}
manager received storybookjs/knobs/set-options
{
"escapeHTML": true
}
manager received setStories
{
"v": 2,
"globalParameters": {},
"globalArgs": {},
"error": null,
"kindParameters": {
"TestStory": {
"framework": "react",
"fileName": "./src/__tests__/basic.stories.js"
}
},
"stories": {
"teststory--base-web": {
"id": "teststory--base-web",
"kind": "TestStory",
"name": "Base Web",
"story": "Base Web",
"parameters": {
"__id": "teststory--base-web",
"argTypes": {}
},
"args": {}
}
}
}
manager received storyRendered teststory--base-web
preview received sharedStateChanged-manager-baseweb/breakpoint __BREAKPOINT_NOT_SET
preview received setCurrentStory Object
preview received storybook/a11y/highlight Object
preview received sharedStateSet-manager-baseweb/bg Primary
preview received sharedStateSet-manager-baseweb/rtl false
preview received sharedStateSet-manager-baseweb/theme Light Move
preview received sharedStateSet-manager-baseweb/breakpoint __BREAKPOINT_NOT_SET
preview received storybook/a11y/request *
manager received currentStoryWasSet Object
manager received storyUnchanged Object
preview received sharedStateChanged-manager-baseweb/bg _undefined_
preview received baseweb/change-bg _undefined_
[HMR] connected
preview received sharedStateChanged-manager-baseweb/rtl false
preview received baseweb/change-rtl false
preview received sharedStateChanged-manager-baseweb/theme _undefined_
preview received baseweb/change-theme _undefined_
manager received storybook/a11y/error TypeError
manager received previewKeydown Object
manager received previewKeydown Object
manager received previewKeydown Object
DevTools failed to load SourceMap: Could not load content for http://localhost:51372/unfetch.mjs.map: HTTP error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILURE
So it seems that currentStoryWasSet
not being initially set causes the issue. Anyway, I experience the same intermittent behavior as @chrislopresto.
Did some quick debugging. It seems that selectionSpecifier
is undefined
when this bug occurs. You initialize this value here but is this a race condition assuming that URL is already set to /?path=/story/*
? The first loaded URL is just /
.
Should selectionSpecifier
be ever undefined
in the story_store
? Stories are correctly set, why not defaulting to story/*
and pick the first one?
I am not familiar with the codebase and not completely sure where/how you control these redirects.
Thanks for the debugging @tajo
You initialize this value here but is this a race condition assuming that URL is already set to /?path=/story/*? The first loaded URL is just /.
That's not quite right because start.ts
runs in the preview, but the URLs you posted are in the manager. The preview (the iframe)'s URL should start as /iframe.html?id=*
but it seems like perhaps it isn't? Perhaps you could put a debugger in and see what the URL is when that code runs? (getSelectionSpecifierFromPath
)
Should selectionSpecifier be ever undefined in the story_store? Stories are correctly set, why not defaulting to story/* and pick the first one?
I was trying to retain the behaviour where if you go to /iframe.html
with no query parameters it does not render any story. The manager should never render that URL in the iframe as far as I know.
Whether or not that behaviour all that useful I am not sure (I find it helpful for some of my fairly specific use cases).
@tmeasday When getSelectionSpecifierFromPath
is invoked the first time from start.ts
in the preview, the value of _global.document.location.href
is http://localhost:6006/iframe.html?id=undefined&viewMode=story
I haven't managed to create a standalone repro, but I do have debugger statements set up locally. If you want to give me a hit list of debug/logpoints, I'm happy to run down the list and report back.
Hey @chrislopresto I've managed to get a reproduction (via https://github.com/chromaui/storybook-template-react) and I've tracked down the problem to this line:
I've no idea why the setTimeout
is there but it seems it is the cause of the race condition whether the id=*
or id=undefined
when the preview is rendered.
@tmeasday Hey, I did some tests here and looks like this error happens only on version 6.0.0-beta.33
Version 6.0.0-beta.31
works fine 馃憤
Version 6.0.0-beta.32
works fine 馃憤
Version 6.0.0-beta.33
doesn't work fine 馃憥
Hope that it helps with the solution.
Version 6.0.0-beta.31
works fine 馃憤
Version 6.0.0-beta.32
works fine 馃憤
Version 6.0.0-beta.33
doesn't work fine 馃憥
This seems to be right.
Yep, thanks team. We鈥檝e identified where the problem is and @ndelangen and I鈥檒l work towards a solution in the next day or two
Yee-haw!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.0.0-beta.36 containing PR #11293 that references this issue. Upgrade today to try it out!
You can find this prerelease on the @next
NPM tag.
I can confirm that beta.36 resolves our story loading issues in development mode. Thanks! 馃帀
We still have an issue with the static storybook build: navigating to different stories doesn't work without a full refresh each time. I'll log this as a separate issue.
Most helpful comment
Yee-haw!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.0.0-beta.36 containing PR #11293 that references this issue. Upgrade today to try it out!
You can find this prerelease on the
@next
NPM tag.