AI models produce markdown-formatted output by default: bold, italics, bulleted lists, headers, and inline code are the native vocabulary of modern LLM responses. Rendering that output as plain text means users see raw **asterisks** and ## hashes cluttering every answer, destroying readability and forcing users to mentally parse formatting tokens. This also degrades accessibility by collapsing semantic structure into an undifferentiated wall of text, failing the intent of WCAG 2.2 SC 1.3.1 (Info and Relationships).
High because unreadable output is functionally broken even when the model response is technically correct.
Install a markdown renderer and pipe AI message content through it in your message component at src/components/chat/MessageBubble.tsx. Pair it with Tailwind's typography plugin for clean default styling, and never render raw HTML from AI output without sanitization.
import ReactMarkdown from 'react-markdown';
<div className="prose dark:prose-invert">
<ReactMarkdown>{message.content}</ReactMarkdown>
</div>
ID: ai-chat-visibility.response-display.markdown-rendering
Severity: high
What to look for: Find where AI message content is displayed in the UI. Count all message rendering locations and for each classify whether content is rendered as plain text (wrapping message content in a plain paragraph) or passed through a markdown renderer. Look for react-markdown, marked, remark, micromark, or custom markdown parsers in package.json. Check whether markdown syntax would render as formatted HTML or appear as raw asterisks and hashes.
Pass criteria: AI response content is rendered through a markdown parser in at least 1 rendering location. Bold, italic, headers, unordered and ordered lists, and inline code appear as formatted HTML, not raw markdown syntax.
Fail criteria: Response content is rendered as plain text without markdown processing. Users see raw **bold** instead of formatted bold text.
Do NOT pass when: A markdown library is installed but the message component does not use it — having react-markdown in package.json without importing it in the message renderer does not count as pass.
Skip (N/A) when: The application is documented as a non-markdown interface (e.g., a pure voice assistant or structured-data-only output). Signal: no markdown-related dependencies and response display is deliberately plain text.
Detail on fail: "Message content rendered as plain text — no markdown processor found in dependencies; users see raw markdown syntax"
Remediation: Add react-markdown to your project. In your message component at src/components/chat/MessageBubble.tsx (or equivalent), wrap content:
import ReactMarkdown from 'react-markdown';
<div className="prose dark:prose-invert">
<ReactMarkdown>{message.content}</ReactMarkdown>
</div>
If using Tailwind, the @tailwindcss/typography plugin provides clean markdown styling via the prose class. Avoid rendering raw HTML from AI output without sanitization.
Cross-reference: For a deeper analysis of accessible content rendering, the Accessibility Fundamentals Audit covers heading hierarchy and semantic HTML in detail.