npx skills add ...
npx skills add getsentry/sentry --skill react-component-documentation
npx skills add getsentry/sentry --skill react-component-documentation
Create or update component documentation in Sentry's MDX stories format. Use when asked to "document a component", "add stories", "write component docs", "create an mdx file", "add a stories.mdx", or document a design system component. Generates structured MDX with live demos, accessibility guidance, and auto-generated API docs from TypeScript types.
Create a .mdx file for a Sentry component following the conventions in static/app/components/core/.
Before writing, collect the information that makes documentation useful beyond mechanical structure. Ask the user these questions — or, if they aren't available, search existing usages in the codebase (Grep for the component name across static/app/views/) to infer answers.
| Question | Where it surfaces in the docs |
|---|---|
| When should a developer reach for this component? | Introduction or a ## When to use section |
| When should they NOT use it — and what should they use instead? | > [!WARNING] callout or ## See Also with guidance |
| What does each variant/priority mean semantically? | Description in each variant's section (e.g., "danger = destructive and irreversible") |
| What do developers commonly get wrong? | > [!WARNING] callouts, icon-only accessibility notes, required prop reminders |
| Does this component require a specific parent, peer, or provider to work correctly? | Noted in the introduction or a > [!NOTE] callout |
| Are there related components that overlap in purpose? | ## See Also with one-line guidance on when to prefer each |
| Which props and variants are worth documenting with a demo? | See prop triage below |
You don't need answers to all questions for every component. Skip ones that don't apply. The goal is to not write docs that only describe how to use the API — write docs that tell developers when and why.
Not every prop needs a demo section. Ask the user: "Which props should I document, and are there any variants or values with specific intended uses?"
If the user isn't available, read the component's TypeScript props and classify each:
| Tier | Document how | Examples |
|---|---|---|
| Core — defines the component's primary behavior or appearance | Full ## section with live demo and semantic description of each value | priority, variant, size |
| Modifier — adjusts a single aspect; values are self-explanatory | Brief mention with a demo, or a single combined demo with other modifiers | disabled, busy, icon, showIcon |
| Structural — controls layout or composition | Demo showing the before/after or compound usage | system, expand, trailingItems |
| Internal / pass-through — not user-facing | Skip entirely | className, style, ref, data-test-id |
For enum props specifically, always ask: "Does each value have a distinct intended meaning, or are they purely visual?" If distinct (e.g., danger means destructive, not just red), document the semantics — not just the visual difference.
Find the component source file:
Read the component file to understand:
Component.SubComponent, export {TabList, TabPanels})The MDX file goes next to the component: <component-dir>/<component>.mdx.
If the file already exists, read it first and update rather than overwrite.
Determining the import path:
static/app/components/core/ are published as @sentry/scraps/<name>sentry/components/<path>To confirm the exact @sentry/scraps package name and type-loader path, check an existing import in the component directory or a neighboring .mdx file — the type-loader path can be @sentry/scraps/<name> or @sentry/scraps/<name>/<name> depending on the package structure.
Category values:
| Category | Components |
|---|---|
buttons | Button, ButtonBar, LinkButton |
forms | Input, Select, Checkbox, Radio, Slider, Switch |
navigation | Tabs, SegmentedControl, Disclosure |
status | Alert, Badge, Tag, Toast |
layout | Flex, Grid, Stack, Container, Surface |
typography | Text, Heading, Prose |
patterns | design patterns, principles |
For principle/pattern docs (no interactive component), use layout: document instead of category, and replace a11y: with reference: under resources.
Follow this import order exactly:
Omit any group that isn't needed. For product components (not in @sentry/scraps), omit the type-loader lines and document props manually in a table (see Step 5).
Complex export: If the component exports need filtering (e.g., to hide internal exports), use the explicit form instead of export {documentation}:
Organize content by feature or user-facing variant, not by prop name:
<Storybook.SideBySide>## per major feature: ## Sizes, ## Priorities, ## States, ## CompositionPrefer titles like ## Sizes, ## Variants, ## States over ## The size prop.
When to use / See Also patterns:
For components not in @sentry/scraps, list props manually instead of using the type-loader:
Alerts come in five types: muted, info, warning, success, and danger.
<Storybook.Demo> <Alert.Container> Muted Info Warning Success Danger </Alert.Container> </Storybook.Demo>
This component meets WCAG 2.2 AA standards:
Before completing, verify:
<component>.mdx)title, description, and source@sentry/scraps components<Storybook.Demo> is immediately followed by a matching code block<img> tags (use <Image>), no inline SVGs, no styled components// 1. External packages (react, etc.) — only if needed for examples
import {useState} from 'react';
// 5. Type-loader for auto-generated API docs (@sentry/scraps components only)
import documentation from '!!type-loader!@sentry/scraps/<component>';
// 3. @sentry/scraps component(s)
import {ComponentName} from '@sentry/scraps/<component>';
// 2. Sentry internals used in examples (icons, utils)
import {IconAdd, IconEdit} from 'sentry/icons';
// 4. Stories namespace (always last before type-loader)
import * as Storybook from 'sentry/stories';
export {documentation};import RawDocumentation from '!!type-loader!@sentry/scraps/<component>';
export const documentation = {
exports: RawDocumentation.exports,
props: {
...RawDocumentation?.props,
// Remove internal props if needed
},
};## When to use
Use `<Alert>` for inline feedback within a page. For application-level banners that span the full viewport, use the `system` prop or reach for `<Toast>` if the message is transient.
> [!WARNING]
> Do not use `<Alert variant="danger">` for confirmation dialogs. Use a modal instead.## See Also
- [LinkButton](/stories/core/linkbutton/) — use when the action navigates to a new URL
- [Link](/stories/core/link/) — use for inline text navigation, not standalone CTAs> [!TIP]
> Use the `<prop>` prop when you need <use case>.
> [!WARNING]
> Avoid <pattern> because <reason>.
> [!NOTE]
>
> <Additional context.>## Props
| Prop | Type | Default | Description |
| --------- | --------------------------------- | -------- | ------------------------- |
| `variant` | `'info' \| 'warning' \| 'danger'` | `'info'` | Controls the visual style |
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Controls the size |