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-dom

React 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} />;
}
A message with bold text and a link.
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