BlockKit component

The public API is exactly what the package entry exports. Deep imports are unsupported. This page covers the components; validation helpers are on the validation page and exported types on the types page.

<BlockKit />

Renders a full payload: parses string input, applies the theme, provides context, and dispatches every block. Import react-blockkit/styles.css once from the host application's global entry; importing the component does not load CSS automatically.

import { BlockKit, type BlockKitAction, type BlockKitInput } from "react-blockkit";

export function handleAction(action: BlockKitAction) {
  console.log(action);
}

export function Preview({ payload }: { payload: BlockKitInput }) {
  return <BlockKit data={payload} theme="dark" onAction={handleAction} />;
}
PropTypeDefaultDescription
dataBlockKitInputrequiredPayload object, block array, or JSON string; rendering does not run strict validation
theme"light" | "dark""light"Color theme; also sets color-scheme for native controls
surface"message" | "modal" | "home""message"Slack's per-surface presentation (control sizes, block rhythm, actions layout) plus data-surface; does not validate or filter
onAction(action: BlockKitAction) => voidReceives local interactions from supported elements with an action_id; workflow_button renders but does not emit
resolversBlockKitResolversMaps user/channel/usergroup/team IDs, emoji, and dates to display values; imageSize supplies image-block byte counts
classNamestringAppended to the root element's class list
aria-labelstring"Slack Block Kit preview"Accessible name for the root role="article" element

A string data that fails JSON.parse throws BlockKitInvariantError with code: "invalid_json". Unknown discriminators render labeled fallbacks; see Unknown blocks and fallbacks.

<BlockKitProvider />

Supplies surface, resolvers, and the action handler to composed blocks. <BlockKit /> uses it internally; you only need it when rendering block or element components directly.

PropTypeDefault
childrenReactNoderequired
surfaceBlockKitSurface"message"
onAction(action: BlockKitAction) => void
resolversBlockKitResolvers

There is no theme prop here. Theming belongs to the <BlockKit /> root. The useBlockKitContext() hook exposes the current context value to custom components. Built-in block components do not branch on the context's surface.

Block components

Every block type has a standalone component. All of them share one props shape:

import type { BlockComponentProps, SectionBlockData } from "react-blockkit";

// block, optional className, optional path for nested composition
export type SectionProps = BlockComponentProps<SectionBlockData>;
ComponentRenders
BlockAny typed RenderableBlock; runtime dispatch falls back on unknown types
ActionsBlockactions
AlertBlockalert
CardBlockcard
CarouselBlockcarousel
ContainerBlockcontainer (including collapsible state)
ContextBlockcontext
ContextActionsBlockcontext_actions
DataTableBlockdata_table
DataVisualizationBlockdata_visualization (pie, bar, line, area)
DividerBlockdivider
FileBlockfile
HeaderBlockheader (semantic h1h4 via level)
ImageBlockimage
InputBlockinput, including message-surface previews
MarkdownBlockmarkdown
PlanBlockplan
RichTextBlockrich_text
SectionBlocksection (text, fields, accessory)
TableBlocktable (plus TableCell for individual cells)
TaskCardBlocktask_card
VideoBlockvideo

Element components

Elements take the Slack object as element. Action-capable components also accept the enclosing blockId, which is copied into emitted actions.

ComponentRendersAdditional optional props
InteractiveElementAny interactive element; runtime dispatch falls back on unknown typesclassName, blockId, path
ButtonElementbuttonclassName, blockId
SelectElementAll static/external/users/channels/conversations selects and their multi_* variantsclassName, blockId
OverflowElementoverflowclassName, blockId
ChoiceGroupcheckboxes and radio_buttonsclassName, blockId
InputElementText, email, URL, and number inputs; date/time/datetime pickers; file and rich-text inputsclassName, blockId, path
ImageElementimage elements and accessoriesclassName, variant

variant is "accessory", "cardHero", "cardIcon", or "context". path is for nested renderer composition; it does not validate the element.

Text primitives

ExportRole
TextRenders a TextObject, mrkdwn or plain text
MrkdwnRenders a mrkdwn string (formatting, links, mentions, emoji, dates)
RichTextRenders rich_text block elements
MarkdownRenders CommonMark and GFM from its markdown prop
tokenizeMrkdwn(text: string) => readonly MrkdwnToken[]; the mrkdwn tokenizer, usable without React
tokenizeMarkdownA flat compatibility tokenizer; not the CommonMark/GFM render tree

The four text models and their non-interchangeable syntax are covered in Markdown and mrkdwn.

StyleX themes

tokens, lightTheme, and darkTheme export the renderer's StyleX variable group and themes for apps that also build with StyleX. CSS-only consumers never need them, because the precompiled react-blockkit/styles.css already contains both.

Accessibility

The root is a role="article" with a configurable accessible name. Blocks use native list, table, link, image, and form semantics where the current preview supports them. See Accessibility for the exact behavior and known limitations before using interactive previews as application UI.