Markdown and mrkdwn
Slack payloads can carry four different text models. They are not aliases, and
using Markdown syntax in a mrkdwn field (or the reverse) changes the output.
| Payload shape | Syntax and behavior | Renderer primitive |
|---|---|---|
{ type: "plain_text", text } | Literal text; formatting markers stay visible | <Text text={…} /> |
{ type: "mrkdwn", text } | Slack mrkdwn: *bold*, _italic_, ~strike~, <url|label>, mentions, dates, and emoji | <Text text={…} /> or <Mrkdwn text="…" /> |
{ type: "markdown", text } block | CommonMark plus GFM: **bold**, standard links, headings, quotes, lists, task lists, tables, and code fences | <Markdown markdown="…" /> |
{ type: "rich_text", elements } | A structured Slack element tree; strings are not reparsed as either syntax | <RichText block={…} /> |
Compare the payloads
A section's mrkdwn text uses Slack delimiters and Slack link notation:
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*Deploy complete* — <https://example.com/run/42|open run>"
}
}A markdown block uses ordinary Markdown:
{
"type": "markdown",
"text": "**Deploy complete** — [open run](https://example.com/run/42)"
}In particular:
**bold**is CommonMark bold; mrkdwn uses*bold*.[label](url)is a Markdown link; mrkdwn uses<url|label>.- Markdown headings, nested lists, task lists, and tables are structural. Mrkdwn does not turn those constructs into equivalent HTML structures.
- CommonMark backslash escapes apply only to the
markdownblock. Do not rely on them to escape mrkdwn delimiters.
Markdown behavior
The markdown block renderer uses CommonMark and GFM parsing. It renders
emphasis, deletion, links and autolinks, blockquotes, ordered and unordered
lists, task lists, tables, thematic breaks, and inline or fenced code. Unsafe
schemes and control-bearing URLs lose the link while retaining readable text.
Raw HTML is displayed as text; it is never injected into the DOM. Markdown image syntax is also rendered as readable alt/link text rather than fetching and embedding an image.
Slack entities remain useful inside Markdown. In ordinary Markdown text,
<@U123>, <#C123>, <!date^…>, and :shortcode: use the same resolvers and
fallbacks as mrkdwn. Backslash-escaped or character-encoded mention and emoji
markers stay literal, as do escaped or encoded [ link openers. Syntax inside
code spans or code blocks is not activated.
The strict validator applies Slack's aggregate Markdown text budget. Tolerant rendering does not run that validator. A Markdown block that exceeds the 12,000-character, delimiter, table-size, structural-marker, or nesting safety bounds keeps its affected source visible as inert text.
Public text components
import { Markdown, Mrkdwn, Text } from "react-blockkit";
export function TextExamples() {
return (
<>
<Text text={{ type: "plain_text", text: "**literal markers**" }} />
<Mrkdwn text="*Slack bold* and <https://example.com|a link>" />
<Markdown markdown="**Markdown bold** and [a link](https://example.com)" />
</>
);
}tokenizeMrkdwn() exposes the tokens used by <Mrkdwn />.
tokenizeMarkdown() is a small, flat compatibility tokenizer; it is not the
CommonMark/GFM tree used to render <Markdown />. Render the component when
you need to inspect exact Markdown output.