Sign inSign up

Custom decorator and globals in modes

ℹ️  This feature uses the modes API. Learn how to get started.

Decorators are a Storybook mechanism that allows you to augment stories with extra rendering functionality. They enable you to provide mock context, translations, or any other project-level settings that a component depends on.

By combining decorators with modes, you can test a story with various project-level configurations.

Configure your decorator

Let’s consider the following example that uses a decorator & globals to switch locale of a story. It uses the react-i18next library to provide translations.

Switching the locale between English, German and Arabic using the Storybook toolbar

The locale values are defined using global types. The withI18next decorator retrieves the value of the locale global and applies it to I18nextProvider, enabling us to test stories with different translations.

// .storybook/preview.js

import React, { Suspense } from "react";
import { I18nextProvider } from "react-i18next";
import i18n from "../src/i18n";

// Wrap your stories in the I18nextProvider component
const withI18next = (Story, context) => {
  const { locale } = context.globals;

  // When the locale global changes
  // Set the new locale in i18n
  useEffect(() => {
    i18n.changeLanguage(locale);
  }, [locale]);

  return (
    // This catches the suspense from components not yet ready (still loading translations)
    // Alternative: set useSuspense to false on i18next.options.react when initializing i18next
    <Suspense fallback={<div>loading translations...</div>}>
      <I18nextProvider i18n={i18n}>
        <Story />
      </I18nextProvider>
    </Suspense>
  );
};

const preview = {
  decorators: [withI18next],
  globalTypes: {
    locale: {
      name: "Locale",
      description: "Internationalization locale",
      toolbar: {
        icon: "globe",
        items: [
          { value: "en", title: "English" },
          { value: "de", title: "Deutsch" },
          { value: "ar", title: "عربي" },
        ],
        showName: true,
      },
    },
  },
};

export default preview;

Define decorator specific modes

Modes are defined in the .storybook/modes.js file. If your project doesn’t have this file yet, go ahead and create it. Set the value for the global associated with your decorator using the chromatic[mode_name].[global_name] parameter. For example:

// .storybook/modes.js

export const allModes = {
  english: {
    locale: "en",
  },
  german: {
    locale: "de",
  },
  arabic: {
    locale: "ar",
  },
};

Apply modes to enable your decorator

With the above set of modes, we can apply them as follows:

// ArticleCard.stories.js

import { allModes } from "../.storybook/modes";
import { MyComponent } from "./MyComponent";

export default {
  component: MyComponent,
  title: "MyComponent",
  parameters: {
    chromatic: {
      //🔶 Test each story for MyComponent in three modes
      modes: {
        english: allModes["english"],
        german: allModes["german"],
        arabic: allModes["arabic"],
      },
    },
  },
};

export const Base = {
  args: {
    //...
  },
};

When Chromatic captures your story, it will create three snapshots on your build, with the corresponding global/decorator enabled. Each mode will have an independent baselines and require distinct approval.