Getting started
react-blockkit renders Slack Block Kit JSON as a Slack-like React preview.
Pass it a payload object, a block array, or a JSON string.
Install
pnpm add react-blockkit react react-domReact 18.2 or newer through React 19 is supported as a peer dependency. Import the precompiled stylesheet once from your global application entry or root layout:
import "react-blockkit/styles.css";The JavaScript entry does not load CSS for you. The stylesheet ships compiled,
so no StyleX plugin or build configuration is required. Import it after
layered frameworks such as Tailwind so the CSS layer order is correct.
Unlayered host rules can override layered library styles regardless of import
order; scope those rules away from [data-block-kit-root] when fidelity
matters.
First render
import { BlockKit, type BlockKitData } from "react-blockkit";
const data = {
blocks: [
{
type: "section",
text: {
type: "mrkdwn",
text: "A message with *bold text* and <https://slack.com|a link>.",
},
},
],
} satisfies BlockKitData;
export function Preview() {
return <BlockKit aria-label="Example Slack message" data={data} />;
}View payload JSON
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "A message with *bold text* and <https://slack.com|a link>."
}
}
]
}Server rendering
Server-side rendering and static generation are supported without browser globals. The server emits the preview markup; callbacks and interactive control behavior activate after hydration.
In a React Server Components framework, render <BlockKit /> through a client
module because it uses React hooks and context:
"use client";
import { BlockKit, type BlockKitInput } from "react-blockkit";
export function BlockKitPreview({ data }: { data: BlockKitInput }) {
return <BlockKit data={data} />;
}Keep react-blockkit/styles.css in the framework's global CSS entry rather
than importing it from every client component.
Date pickers do not read the current clock. A datetime picker's server markup uses the server's local time zone; hydration suppresses that expected value mismatch and then updates the control to the viewer's local time. Render that control after mount only when its pre-hydration value must already use the viewer's zone.
Next
- Try payloads live in the playground.
- Rendering messages: input shapes, surfaces, and composing individual blocks.
- Handling actions: wiring up buttons, selects, and inputs.
- Markdown and mrkdwn: choosing the correct Slack text format.
- Accessibility: current semantics and preview limitations.
<BlockKit />reference: the full props table.- Compiling Markdown to Block Kit? slackmark produces payloads this renderer accepts.