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

Quickstart

Render an approval message and answer its buttons the way your Slack app would.

In this guide you render a message with two buttons, handle the click, and replace the buttons with the outcome, the same flow a Slack app runs with response_url.

This guide assumes you’ve finished Installation.

Render the message

Pass the blocks your app sends to chat.postMessage straight to <Message>:

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

const blocks = [
  {
    type: "section",
    text: { type: "mrkdwn", text: "<@U0ADA> wants to deploy *api@4.2.0* to production." },
  },
  {
    type: "actions",
    block_id: "deploy",
    elements: [
      {
        type: "button",
        style: "primary",
        action_id: "approve",
        value: "api@4.2.0",
        text: { type: "plain_text", text: "Approve" },
      },
      {
        type: "button",
        action_id: "reject",
        value: "api@4.2.0",
        text: { type: "plain_text", text: "Reject" },
      },
    ],
  },
];

export function Approval() {
  return <Message app={{ name: "Deploy Bot" }} blocks={blocks} />;
}
Your AppAPP
wants to deploy api@4.2.0 to production.

<@U0ADA> renders as a mention. Tell the renderer who that is with resolvers; until then it shows the raw id, as Slack does for a user it can’t find.

Handle the click

Wrap the message in a <BlockKitProvider> and pass onAction. It receives each action in the shape of one entry of a block_actions payload’s actions array:

import { BlockKitProvider, Message, type BlockAction } from "@nkootstra/block-kit";

function handleAction(action: BlockAction) {
  console.log(action.action_id, action.value);
  // → "approve" "api@4.2.0"
}

export function Approval() {
  return (
    <BlockKitProvider onAction={handleAction}>
      <Message app={{ name: "Deploy Bot" }} blocks={blocks} />
    </BlockKitProvider>
  );
}

Click a button below to see the action it sends:

Your AppAPP
wants to deploy api@4.2.0 to production.
onActionInteract with the preview.

Update the message

The second argument to onAction lets you answer the way an app would. message.update replaces the message the action came from, like posting to response_url with replace_original:

import {
  BlockKitProvider,
  Message,
  type ActionContext,
  type BlockAction,
} from "@nkootstra/block-kit";

function handleAction(action: BlockAction, { message }: ActionContext) {
  const verdict = action.action_id === "approve" ? ":white_check_mark: Approved" : ":x: Rejected";

  message?.update({
    blocks: [
      blocks[0],
      { type: "context", elements: [{ type: "mrkdwn", text: `${verdict} by <@U0GRACE>` }] },
    ],
  });
}

After a click, the message becomes:

Your AppAPP
wants to deploy api@4.2.0 to production.
:white_check_mark: Approved by

The context also has views, to open a modal, and state, with the current value of every input in the message.

Already have a Slack app?

If your app already handles interactions, with Bolt or your own request URL, you don’t need to rewrite its logic in React. Relay the clicks to it instead, and apply whatever it answers: see Connecting your app.

Next steps

Was this page helpful?