Skip to content
Migration

TextPart markdown

TextPart in the React, Vue, and Solid UI packages now renders with TanStack Markdown. Pass extensions and highlighter. remarkPlugins, rehypePlugins, and disableDefaultPlugins are removed.

This page is only for apps that import the TextPart component. createChatHook does not use it unless you pass it as partsComponents.text.

Upgrade

  1. Find each TextPart in your code that has a plugin prop or a Solid components prop.
  2. Replace each prop with the prop map below.
  3. If you want colored code fences, follow Syntax highlighting.
  4. Read Silent changes. Default <TextPart content={...} /> compiles, but some output looks different.

Prop map

Old propNew prop
remarkPluginsextensions (MarkdownExtension[] from @tanstack/markdown)
rehypePluginsextensions or highlighter
disableDefaultPluginsRemoved. The streaming extension is always on.
Solid componentsRemoved
React componentscomponents (MarkdownComponents: a tag-name map with normal HTML props)

A unified plugin, such as remark-gfm or remark-cjk-friendly, is not a TanStack Markdown extension. You cannot pass it through.

Replace plugin props

CJK bold

TanStack Markdown parses CJK bold with no plugin. Remove the plugin:

tsx
// Before
import { TextPart } from '@tanstack/ai-react/ui'
import remarkCjkFriendly from 'remark-cjk-friendly'

<TextPart content={content} remarkPlugins={[remarkCjkFriendly]} />
tsx
// After
import { TextPart } from '@tanstack/ai-react/ui'

export function Reply({ content }: { content: string }) {
  return <TextPart content={content} />
}

Syntax highlighting

The old stack ran rehype-highlight. Then rehype-sanitize removed the hljs-* classes, so fenced code already looked plain.

To get colors, pass a TanStack Highlight callback. For the full steps, see Highlight markdown code.

tsx
// Before
<TextPart content={content} />
tsx
// After
import { TextPart } from '@tanstack/ai-react/ui'
import { highlightMarkdownCode } from './markdown-highlighter'

export function Reply({ content }: { content: string }) {
  return (
    <TextPart
      content={content}
      highlighter={highlightMarkdownCode}
      className="markdown-renderer"
    />
  )
}

Other remark or rehype plugins

A unified plugin has no drop-in replacement. Write the behavior again as a TanStack Markdown extension, or do it outside TextPart.

You cannot turn off the streaming extension.

React components

React still accepts components, but the type is now MarkdownComponents, not the Components type of react-markdown. TanStack Markdown passes only intrinsic HTML props.

A common override still type-checks, but renders wrong, because inline is always undefined:

tsx
// Before: compiles, but every code element renders as a block
<TextPart
  content={content}
  components={{
    code: ({ inline, children }) =>
      inline ? <code>{children}</code> : <pre>{children}</pre>,
  }}
/>
tsx
// After
import { TextPart } from '@tanstack/ai-react/ui'

export function Reply({ content }: { content: string }) {
  return (
    <TextPart
      content={content}
      components={{
        a: (props) => <a {...props} target="_blank" rel="noreferrer" />,
      }}
    />
  )
}

To tell a fence from inline code, read className (for example language-ts). Do not read inline or node.

Silent changes

These changes happen with a default <TextPart content={...} />. You get no type error.

InputBeforeAfter
Bare URL https://example.comAuto-linkedPlain text
Raw HTML such as <br> or <img>Sanitized, then renderedEscaped text
Task listcontains-task-list / task-list-itemCheckbox on a plain <li>
Fenced codePlain (highlight classes removed)Plain, with tm-code / language-*
CJK bold **…。**次Failed without a pluginWorks

Tables, lists, strikethrough, and fenced code still render.

These things do not change:

  • createChatHook apps that render {part.content} themselves.
  • The import path: still @tanstack/ai-react/ui (or the Vue or Solid /ui subpath).
  • The TextPart data type on messages ({ type: 'text', content }). That is a type, not this component.

Done

Your type checker passes, and your replies render with TanStack Markdown. To add colored code fences, follow Highlight markdown code.