Skip to content
Block Kit for React
Esc
↑↓navigate↵open⌘Jpreview
On this page

mrkdwn

Slack's mrkdwn syntax, the parser and formatting helpers in @nkootstra/block-kit/mrkdwn, and the Mrkdwn and Text components.

Mrkdwn is Slack’s own text format (not quite Markdown) used in mrkdwn text objects throughout Block Kit. @nkootstra/block-kit ships a parser for it, usable on its own (no React, no DOM) through @nkootstra/block-kit/mrkdwn, and the <Mrkdwn>/<Text> components that render its output.

Your AppAPP
Bold, italic, strike, code, and a link.
A quoted line.
mentioned #general and @engineering.

Mrkdwn and Text

<Mrkdwn> renders a raw mrkdwn string directly:

import { Mrkdwn } from "@nkootstra/block-kit";

<Mrkdwn text="*Hello* <@U0ADA>, check out <https://example.com|this>." />;
PropType
textstring
Typestring
verbatim?boolean

Slack's verbatim flag. When false, bare URLs (https://... or www...) are auto-linked.

Typeboolean
Defaultfalse
emojiSize?number

Pixel size for :emoji: images.

Typenumber
Default22

<Text> renders a full Block Kit text object, either kind, and is what block/element components use internally:

import { Text } from "@nkootstra/block-kit";

<Text text={{ type: "mrkdwn", text: "*Hello*" }} />;
<Text text={{ type: "plain_text", text: "Hello :wave:" }} />;

A plain_text object has no formatting beyond emoji shortcodes: no bold, links or mentions, since that’s what Slack itself restricts it to.

Supported syntax

PropType
*bold*?Bold

*text* → <b>text</b>

TypeBold
_italic_?Italic

_text_ → <i>text</i>

TypeItalic
~strike~?Strike

~text~ → <s>text</s>

TypeStrike
`code`?Inline code

Monospace, no other formatting parsed inside.

TypeInline code
```pre```?Preformatted block

Fenced block, shown verbatim; a single newline right after the opening fence or before the closing one is dropped, matching Slack.

TypePreformatted block
> quote?Quote

One or more consecutive lines starting with >.

TypeQuote
>>> quote?Block quote

Everything after >>> is quoted, including following lines.

TypeBlock quote
<url|label>?Link

Renders as label; falls back to showing the raw url with no |label part.

TypeLink
bare url?Auto-link

Linked automatically unless verbatim is true.

TypeAuto-link
<@U123>?User mention
TypeUser mention
<#C123>?Channel mention

<#C123|name> supplies a fallback label for when the channel can't be resolved.

TypeChannel mention
<!subteam^S123>?Usergroup mention
TypeUsergroup mention
<!here> / <!channel> / <!everyone>?Special mention

Broadcasts to online members, the channel, or everyone.

TypeSpecial mention
<!date^ts^fmt^url|fallback>?Date

See below.

TypeDate
:shortcode:?Emoji

See the emoji guide.

TypeEmoji

Special mentions

<!here>, <!channel> and <!everyone> render as Slack’s bold, highlighted broadcast pills rather than a user/channel mention:

Your AppAPP
@channel heads up, deploying now.

Dates

<!date^1392734382^{date_short} at {time}^https://example.com|Feb 18, 2014> formats a Unix timestamp in the viewer’s own locale and time zone, with an optional link and a |fallback shown only when the format can’t be rendered:

Your AppAPP
Deployed Feb 18, 2014 at 2:39 PM.

{token} placeholders inside the format string: {date}, {date_short}, {date_long}, {date_long_full}, {date_num}, {date_slash}, {date_pretty}, {date_short_pretty}, {date_long_pretty} (the _pretty variants show “Today”/“Yesterday”/“Tomorrow” when applicable), {time}, {time_secs}, and {ago} (a relative time like “in 3 hours”). Unknown tokens are left as-is.

formatSlackDate does the same formatting outside of parsed mrkdwn, useful when you have a raw timestamp and format string from elsewhere:

import { formatSlackDate } from "@nkootstra/block-kit/mrkdwn";

formatSlackDate(1392734382, "{date_short} at {time}");
// → "Feb 18, 2014 at 6:39 AM"

formatSlackDate(1392734382, "{date_long_pretty}", {
  timeZone: "America/New_York",
  locale: "en-US",
});
PropType
locale?string

BCP 47 locale.

Typestring
Default"en-US"
timeZone?string

IANA zone. Defaults to the runtime's zone.

Typestring
now?number

Reference time (ms) for {ago} and the _pretty variants. Defaults to Date.now().

Typenumber

<BlockKitProvider timeZone="..."> sets the zone used for dates parsed inline within <Mrkdwn>. Pass timeZone to formatSlackDate directly when formatting outside of that context.

Other exports

import { parse, decodeEntities, parsePlainTextEmoji } from "@nkootstra/block-kit/mrkdwn";
PropType
parse?(input: string, options?: { verbatim?: boolean }) => Root

Parses a mrkdwn string into an AST (MrkdwnNode[]). Never throws: malformed markup is kept as plain text.

Type(input: string, options?: { verbatim?: boolean }) => Root
decodeEntities?(text: string) => string

Decodes &amp; &lt; &gt; the way Slack encodes them in mrkdwn.

Type(text: string) => string
parsePlainTextEmoji?(input: string) => Array<Text | Emoji>

Splits a plain_text string into text and emoji nodes, with no other mrkdwn parsing. This is what `Text` uses for plain_text objects.

Type(input: string) => Array<Text | Emoji>

parse is what powers <Mrkdwn>; reach for it directly when you want the structured AST instead of React output, for example to render mrkdwn somewhere other than the DOM, or to extract just the plain text.

Was this page helpful?