The React adapter renders Markdown source or a pre-parsed document without an intermediate HTML string.
import { Markdown } from '@tanstack/markdown/react'
export function Article({ source }: { source: string }) {
return <Markdown>{source}</Markdown>
}Markdown returns a fragment, so the surrounding semantic element remains under application control.
Map an HTML tag name to a component or another tag:
import type { ComponentProps } from 'react'
import { Markdown } from '@tanstack/markdown/react'
function ExternalLink(props: ComponentProps<'a'>) {
const external = props.href?.startsWith('http')
return (
<a
{...props}
rel={external ? 'noreferrer' : props.rel}
target={external ? '_blank' : props.target}
/>
)
}
<Markdown components={{ a: ExternalLink }}>{source}</Markdown>Mappings apply to every intrinsic tag emitted through the React renderer, including extension component tag names.
import { parseMarkdown } from '@tanstack/markdown/parser'
import { Markdown } from '@tanstack/markdown/react'
const document = parseMarkdown(source)
export function Article() {
return <Markdown>{document}</Markdown>
}The AST contains no functions, classes, or environment-specific values. It can be built ahead of time or loaded from a content cache.
Use renderMarkdownReact outside JSX, or renderBlockReact and renderInlineReact when composing a custom renderer around the standard nodes.
The adapter generates deterministic keys from tree positions. Core SSR output is tested against the HTML renderer. Custom components, raw HTML, highlighter output, and HTML-only extension hooks are application-controlled boundaries and are not covered by that equivalence guarantee.