How to build an accessible Reasoning in React
Built on native <details>/<summary>, so the trigger is a keyboard-operable disclosure (Enter/Space) with its expanded state exposed by the browser, it works before hydration, and find-in-page can open it. The content carries aria-busy while streaming and is never a live region; the sparkle is decorative and pulses only under prefers-reduced-motion: no-preference
When to use a Reasoning
- Showing a model’s reasoning or thinking trace above its answer, collapsed once the answer arrives
- Giving readers an opt-in look at how an AI reached a result without cluttering the reply
When not to use it
- General show/hide content — use Collapsible or Accordion
- A sequence of discrete agent steps with their own status — use Steps or Timeline
- Reporting the phase of a request — use AiStatus
Keyboard interactions
Role button, verified at WCAG 2.2-AA.
EnterSpace
Common mistakes
Avoid: Wrapping the reasoning text in aria-live so it is read as it streams
Prefer: <Reasoning streaming> — the content is aria-busy and silent; pair it with AiStatus for the phase
Announcing every token of a reasoning trace drowns out everything else
Example
<Reasoning streaming>The user wants a summary, so I will start with the totals…</Reasoning>