Streaming Completion

Keep unfinished Markdown readable while a response is still arriving.

Markdown syntax often arrives in pieces. A response may temporarily end inside emphasis, a link, a table row, or a code fence. In mode="streaming", vue-stream-markdown completes supported unfinished syntax before parsing so users see a stable preview instead of raw delimiters.

Completion affects only the rendered preview. The content value is never modified.

Streaming and static modes

Use streaming mode while content is arriving:

<Markdown :content="content" mode="streaming" />

Switch to static mode when generation finishes:

<Markdown :content="content" mode="static" />

Static mode skips completion and renders the original Markdown exactly as supplied.

Emphasis and inline syntax

An unfinished delimiter is kept from leaking into the preview while the text grows:

This answer is **still being generated

The same behavior covers common emphasis, inline code, strikethrough, and CJK-adjacent formatting cases.

Incomplete link text can appear as a loading link without becoming clickable:

[Read the complete guide

Once the destination arrives, the normal link style and interaction are enabled:

[Read the complete guide](https://example.com)

Images

An image destination may also arrive over several updates. Streaming mode keeps the incomplete syntax from flashing as plain text and exposes a loading state until the image is ready.

Tables

Partial rows remain a table while columns are still arriving:

When the response completes, static mode renders the final source without inferred cells or delimiters.

Mathematics

With @stream-markdown/math configured, an unfinished equation remains renderable during streaming and is replaced by the exact final expression in static mode.

See Mathematics for extension setup and KaTeX styles.

Footnotes

An incomplete footnote marker is hidden while it is being typed. Complete references are preserved for parsing but remain hidden during streaming until their definitions arrive. The parser then displays the resolved reference numbers and updates the footnote content as it grows.

Custom completion

Use the completion prop when an application needs rules beyond the defaults:

<script setup lang="ts">
function completion(markdown: string) {
  const opening = markdown.lastIndexOf('<thinking>')
  const closing = markdown.lastIndexOf('</thinking>')
  return opening > closing ? `${markdown}</thinking>` : markdown
}
</script>

<template>
  <Markdown :content="content" :completion="completion" mode="streaming" />
</template>

See Parser for completion options and Comark plugins.