Specify default page for Storybook
Asked Answered
E

6

22

I have storybook in my React app, and for some reason when i run yarn storybook it's always open the same story (it's automatically select selectedKind and selectedStory) . How can i manually select default story?

Estimate answered 11/12, 2018 at 12:48 Comment(0)
K
9

The Kind and Story are selected based on the URL query parameters (i.e. http://localhost:9001/?selectedKind=Component&selectedStory=default will select the Component kind and default story). If you don't have any URL parameters, then storybook will choose the first story in the list (which is the first story loaded via however you have storybook configured).

If you just want to choose the first story in the list, then load you story files in a specific order in your loadStories function in .storybook/config.js file.


If, however, you want to always force the same story to be selected, then follow the instructions below.

The best way to do this would be to use the Storybook's addonAPI. Here is an example that worked for me (with a safeguard so you don't get stuck on the same story forever):

// .storybook/addons.js
import addonAPI from '@storybook/addons';

let firstLoad = true;
addonAPI.register('my-organisation/my-addon', (storybookAPI) => {
  storybookAPI.onStory((kind, story) => {
    // when you enter a story, if you are just loading storybook up, default to a specific kind/story. 
    if (firstLoad) {
      firstLoad = false; // make sure to set this flag to false, otherwise you will never be able to look at another story.
      storybookAPI.selectStory('FirstKind', 'default story');
    }
  });
});

With that snippet, no matter what story you end up on based on the URL, you can select the first story to land on.

You can read more about the storybook addonAPI here: https://storybook.js.org/addons/api/ I would probably allow an additional query parameter in the URL to force the kind+story from the URL to be chosen.

Note: there may be an existing addon that provides this functionality, but a quick search yielded no viable results.

Kwasi answered 18/1, 2019 at 21:22 Comment(4)
πŸ‘ for simply requiring the story you want to default to first in config.js – Interjection
If you're using main.js variant of the config, you can also place it first in the stories array, like stories : ["../src/index.stories.mdx", "..src/**/*.stories.(tsx|mdx)"]. – Thankless
Beware, this solution can appear to fail if you have a mixture of CSF and old format stories. – Spoon
@Nucleon great answer! – Reisfield
M
37

With storybook v6, just pust default page's mdx to the first position in stories field;

Demo

// .storybook/main.js

module.exports={
  stories:[
    '../packages/intro.stories.mdx', // default page
    '../packages/**/*.stories.mdx'
  ]
}
Machado answered 23/6, 2021 at 9:31 Comment(3)
This is the best answer since Storybook 6 was released. I thought briefly that it didn't work but that was due to custom story sorting. This is a great solution for Storybook 6 and above and should become the default answer. – Arvid
Totally agree: and quite unfortunately this is not immediately obvious from their documentation, although they did mention that import order matters :) thank you! – Catie
Works for Angular Projects as well πŸ™ – Marinara
K
9

The Kind and Story are selected based on the URL query parameters (i.e. http://localhost:9001/?selectedKind=Component&selectedStory=default will select the Component kind and default story). If you don't have any URL parameters, then storybook will choose the first story in the list (which is the first story loaded via however you have storybook configured).

If you just want to choose the first story in the list, then load you story files in a specific order in your loadStories function in .storybook/config.js file.


If, however, you want to always force the same story to be selected, then follow the instructions below.

The best way to do this would be to use the Storybook's addonAPI. Here is an example that worked for me (with a safeguard so you don't get stuck on the same story forever):

// .storybook/addons.js
import addonAPI from '@storybook/addons';

let firstLoad = true;
addonAPI.register('my-organisation/my-addon', (storybookAPI) => {
  storybookAPI.onStory((kind, story) => {
    // when you enter a story, if you are just loading storybook up, default to a specific kind/story. 
    if (firstLoad) {
      firstLoad = false; // make sure to set this flag to false, otherwise you will never be able to look at another story.
      storybookAPI.selectStory('FirstKind', 'default story');
    }
  });
});

With that snippet, no matter what story you end up on based on the URL, you can select the first story to land on.

You can read more about the storybook addonAPI here: https://storybook.js.org/addons/api/ I would probably allow an additional query parameter in the URL to force the kind+story from the URL to be chosen.

Note: there may be an existing addon that provides this functionality, but a quick search yielded no viable results.

Kwasi answered 18/1, 2019 at 21:22 Comment(4)
πŸ‘ for simply requiring the story you want to default to first in config.js – Interjection
If you're using main.js variant of the config, you can also place it first in the stories array, like stories : ["../src/index.stories.mdx", "..src/**/*.stories.(tsx|mdx)"]. – Thankless
Beware, this solution can appear to fail if you have a mixture of CSF and old format stories. – Spoon
@Nucleon great answer! – Reisfield
E
5

You can fix this with storySort, I had this issue but I figured it out.

To choose a file or component as your landing file, you can specify in your .storybook/preview.js file. Just like this:

    export const parameters = {
      .........,
      options: {
        storySort: {
          order: ['Components', ['Forms', ['Select']]],
        },
      },
    };

Sample of my component library

To sort stories alphabetically, you can do this

    export const parameters = {
      .........,
      options: {
        storySort: (a, b) => a[1].id.localeCompare(b[1].id),
      },
    };

Egidius answered 20/5, 2022 at 18:1 Comment(0)
K
3

To select a specific story on load, if a story is not specified, use the following addon

// .storybook/addons.js
import { STORIES_CONFIGURED, STORY_MISSING } from '@storybook/core-events'
import addonAPI from '@storybook/addons'

addonAPI.register('my-organisation/first-page', storybookAPI => {
  storybookAPI.on(STORIES_CONFIGURED, (kind, story) => {
    if (storybookAPI.getUrlState().path === '/story/*') {
      storybookAPI.selectStory('Kind', 'Story')
    }
  })
  storybookAPI.on(STORY_MISSING, (kind, story) => {
    storybookAPI.selectStory('Kind', 'Story')
  })
})

replacing Kind, Story with your desired story. Testing the URL for /story/* stops changing the page if a specific story is requested and the second listener works for the case where a missing story, or incorrect URL is supplied. Unfortunately, at this time, there's no API to select the docs page.

Karajan answered 15/10, 2019 at 11:24 Comment(0)
R
0

Adding on to the other answers, what worked for me was to both update storySort, which changes the order but not the default story opened, and change

configure(req, module);

to

const loadStories = () => {
  // Required to make the default story opened the first one in storySort.
  req.keys().forEach((filename) => req(filename));
};
configure(loadStories, module);

Which makes the default actually the first story displayed. That's because this makes storybook's webpack import all the files to get the metadata/names etc so it can use it for sorting. Both were done in .storybook/preview.ts but for some it might be config.ts.

Relay answered 18/6, 2024 at 18:31 Comment(0)
H
-1

In our case storybook was always selecting the first story with a root (even with story loading order adjusted), but we wanted an introduction without a root to be first. It's a poor mans solution because you see the redirect visually, but the best we could do was:

// ./addons/default-story/register.js
import { SET_GLOBALS, STORY_PREPARED, STORY_MISSING } from '@storybook/core-events'
import { addons } from '@storybook/addons';

addons.register('your-org/default-story', api => {
  const emitter = addons.getChannel();

  let shouldRedirect = false;

  emitter.on(SET_GLOBALS, (kind, story) => {
    if (!window.location.search) {
      shouldRedirect = true;
    }
  })

  emitter.on(STORY_PREPARED, (kind, story) => {
    if (shouldRedirect) {
      api.selectStory("Introduction", "Introduction")
    }
    shouldRedirect = false
  })


  emitter.on(STORY_MISSING, (kind, story) => {
    api.selectStory('Introduction', 'Introduction')
  })
})

Ps, load this in your main.js file:

  addons: [
    "./addons/default-story/register.js",
Hoeve answered 13/12, 2021 at 21:15 Comment(0)

© 2022 - 2025 β€” McMap. All rights reserved.