Guides

React

React

The React adapter renders Markdown source or a pre-parsed document without an intermediate HTML string.

Component usage

tsx
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.

Replace intrinsic elements

Map an HTML tag name to a component or another tag:

tsx
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.

Pre-parse for SSR

tsx
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.

Lower-level rendering

Use renderMarkdownReact outside JSX, or renderBlockReact and renderInlineReact when composing a custom renderer around the standard nodes.

Parity and keys

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.