Write notes for your Storybook stories.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Storybook Addon Notes allows you to write notes (text or HTML) for your stories in Storybook. It provides both tab-based and panel-based display modes for documentation, supports Markdown rendering with embedded Giphy support, and enables multiple notes sections for different audiences (design, development).
npm install -D @storybook/addon-notesThe addon integrates with Storybook's parameter system rather than providing direct imports for normal usage. For addon registration:
// In .storybook/main.js
module.exports = {
addons: ['@storybook/addon-notes/register'] // or 'register-panel'
};Deprecated decorator functions (avoid in new code):
import { withNotes, withMarkdownNotes } from '@storybook/addon-notes';Register the addon in your .storybook/main.js:
module.exports = {
addons: ['@storybook/addon-notes/register']
}Add notes to stories using the notes parameter:
export default {
title: 'Component',
parameters: {
notes: 'Simple text notes for this story',
},
};
export const BasicStory = () => <Component />;Alternatively, register as a panel instead of a tab:
module.exports = {
addons: ['@storybook/addon-notes/register-panel']
}Add simple text notes to stories using a string parameter.
// Story configuration with text notes
export default {
parameters: {
notes: 'Simple text notes for this story',
},
};Add markdown-formatted notes with rich content support.
import markdownNotes from './notes.md';
export default {
parameters: {
notes: { markdown: markdownNotes },
},
};Add text notes using object format for consistency.
export default {
parameters: {
notes: { text: 'Text content for the notes panel' },
},
};Create multiple named sections for different audiences or topics.
import introNotes from './intro.md';
import designNotes from './design.md';
export default {
parameters: {
notes: {
'Introduction': introNotes,
'Design Notes': designNotes
},
},
};Embed Giphy GIFs in markdown notes using the custom Giphy component. The component fetches the first result from Giphy's search API.
interface GiphyProps {
query: string; // Search term for Giphy API
}
class Giphy extends Component<GiphyProps, GiphyState> {
componentDidMount(): void;
render(): React.ReactElement | null;
}Usage in Markdown:
# Story Notes
This component handles user interactions.
<Giphy query="celebration" />
More documentation content here...Disable notes display for specific stories.
export default {
parameters: {
notes: { disable: true },
},
};Note: These decorators are deprecated and should not be used in new code.
/**
* @deprecated Use parameter-based notes instead
*/
function withNotes(options: string | NotesOptions): any;
/**
* @deprecated Use parameter-based notes instead
*/
function withMarkdownNotes(text: string, options: any): void;
// Internal utility functions
function formatter(code: string): string;// Parameter types
type Parameters =
| string
| TextParameter
| MarkdownParameter
| DisabledParameter
| TabsParameter;
interface TextParameter {
text: string;
}
interface MarkdownParameter {
markdown: string;
}
interface DisabledParameter {
disable: boolean;
}
type TabsParameter = Record<string, string>;
// Component props
interface PanelProps {
active: boolean;
api: API;
}
interface GiphyProps {
query: string;
}
interface GiphyState {
src: string | null;
}
interface SyntaxHighlighterProps {
className?: string;
children: ReactElement;
[key: string]: any;
}
interface NotesLinkProps {
href: string;
children: ReactElement;
}const ADDON_ID = 'storybookjs/notes';
const PANEL_ID = 'storybookjs/notes/panel';
const PARAM_KEY = 'notes';
// Registration entry points
const REGISTER_TAB = '@storybook/addon-notes/register';
const REGISTER_PANEL = '@storybook/addon-notes/register-panel';The addon automatically handles:
<Giphy query="search-term" />Notes can be configured at different levels:
// Component-level notes (applies to all stories)
export default {
title: 'Components/Button',
parameters: {
notes: 'General button component documentation',
},
};
// Story-level notes (overrides component-level)
export const PrimaryButton = () => <Button primary />;
PrimaryButton.story = {
parameters: {
notes: 'Specific notes for the primary button variant',
},
};Works seamlessly with Component Story Format (CSF):
import Component from './Component';
import componentNotes from './Component.notes.md';
export default {
title: 'Component',
component: Component,
parameters: {
notes: { markdown: componentNotes },
},
};
export const Default = {};
export const WithCustomNotes = {
parameters: {
notes: 'Story-specific notes override component notes',
},
};The addon includes an internal formatter that normalizes whitespace in template literals:
/**
* Formats code strings by removing common indentation from template literals
* @param code - Raw code string to format
* @returns Formatted code string with normalized whitespace
*/
function formatter(code: string): string;The addon handles various error conditions gracefully:
Example error scenarios:
// Invalid parameter format - throws error
export default {
parameters: {
notes: { /* missing text or markdown property */ }
}
};
// Network error handling - graceful fallback
// If Giphy API fails, the component simply doesn't renderThe addon supports two display modes:
@storybook/addon-notes/register): Notes appear in a dedicated tab in the addons panel@storybook/addon-notes/register-panel): Notes appear directly in the main addons panel areaChoose the mode that best fits your Storybook configuration and team preferences.
The addon supports custom markdown component overrides and theming:
// Custom markdown components can be registered
import { addons, types } from '@storybook/addons';
// Register custom elements that will be available in markdown
addons.getChannel().emit('addElement', {
type: types.NOTES_ELEMENT,
id: 'my-custom-element',
render: ({ children }) => <div className="custom">{children}</div>
});Styling Considerations:
The addon uses Storybook's theming system and can be customized via the theme:
// In .storybook/manager.js
import { themes } from '@storybook/theming';
import { addons } from '@storybook/addons';
addons.setConfig({
theme: {
...themes.normal,
addonNotesTheme: {
fontFamily: 'Monaco, monospace',
fontSize: '14px'
}
}
});