Docs
Storybook Docs

storySorts

Parent: main.js|ts configuration

Type: (StorySortConfig | StorySortOrder | StorySortFn)[]

Default: []

Sorts the stories in the sidebar. Without sorters, stories appear in the order in which they are imported. See the guide for usage examples.

.storybook/main.ts
// Replace your-framework with the framework you are using (e.g., react-vite, nextjs, nextjs-vite)
import { defineMain } from '@storybook/your-framework/node';
 
export default defineMain({
  framework: '@storybook/your-framework',
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  storySorts: [{ order: ['Intro', 'Components'] }, { method: 'alphabetical' }],
});

Each sorter compares two stories. When a sorter considers two stories equal, the next sorter decides their order. In the example above, Intro and Components come first, and the alphabetical sorter orders every other story.

StorySortConfig

type StorySortConfig = {
  includeNames?: boolean;
  locales?: string;
  method?: 'alphabetical' | 'configure';
  order?: StorySortOrder;
};
  • includeNames: Whether to compare story names as well as titles. Defaults to false.
  • locales: The locale to use for alphabetical sorting. Defaults to your system locale.
  • method: 'alphabetical' sorts the stories not listed in order alphabetically. 'configure' keeps them in import order.
  • order: The titles to show first, in the given order.

StorySortOrder

type StorySortOrder = (string | StorySortOrder)[];

An array is shorthand for { order: [...] }. A nested array orders the second level of the title before it, as in ['Intro', 'Pages', ['Home', 'Login'], 'Components']. A '*' entry marks where all unlisted stories go.

StorySortFn

type StorySortFn = (a: IndexEntry, b: IndexEntry) => number;

A comparator like the one passed to Array.prototype.sort. It receives two story index entries, each with an id, title, name, and importPath, and returns a negative number, zero, or a positive number. The comparator runs in Node.js when Storybook builds the story index, so it cannot use browser APIs.

Adding a sorter from a preset

Presets and addons can add sorters too. Storybook applies storySorts like other preset fields, so a preset receives the sorters defined so far and returns the new list:

my-addon/preset.js
export const storySorts = (existing = []) => [...existing, { method: 'alphabetical' }];

Storybook applies the main configuration after all addons, so a plain storySorts array in main comes after the sorters that addons add. To give your own sorters precedence over them, write storySorts as a function and put yours first:

.storybook/main.ts
// Replace your-framework with the framework you are using (e.g., nextjs-vite, sveltekit, etc.)
import { defineMain } from '@storybook/your-framework/node';
 
export default defineMain({
  storySorts: (existing = []) => [{ order: ['Intro'] }, ...existing],
});