Custom decorator and globals in modes
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 the locale of a story. It uses the react-i18next library to provide translations.
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.
import type { Preview } from "@storybook/react-vite";
import React, { Suspense, useEffect } 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: Preview = {
decorators: [withI18next],
globalTypes: {
locale: {
description: "Internationalization locale",
toolbar: {
icon: "globe",
items: [
{ value: "en", title: "English" },
{ value: "de", title: "Deutsch" },
{ value: "ar", title: "عربي" },
],
},
},
},
initialGlobals: {
locale: "en", // Sets the default locale to English
},
};
export default preview;
Define decorator specific modes
Modes are defined in the .storybook/modes.js|ts 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:
export const allModes = {
english: {
locale: "en",
},
german: {
locale: "de",
},
arabic: {
locale: "ar",
},
} as const;
Apply modes to enable your decorator
With the above set of modes, we can apply them as follows:
// Adjust this import to match your framework (e.g., nextjs, vue3-vite)
import type { Meta } from "@storybook/your-framework";
import { allModes } from "../.storybook/modes";
import { MyComponent } from "./MyComponent";
const meta = {
component: MyComponent,
title: "MyComponent",
parameters: {
chromatic: {
//🔶 Test each story for MyComponent in three modes
modes: {
english: allModes["english"],
german: allModes["german"],
arabic: allModes["arabic"],
},
},
},
} satisfies Meta<typeof MyComponent>;
When Chromatic captures your story, it will create three snapshots on your build with the corresponding global/decorator enabled. Each mode will have independent baselines and require distinct approval.