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

BlockKitProvider

Every prop of the provider that connects rendered blocks to your app.

<BlockKitProvider> holds the state of every input rendered beneath it, and is where interactions reach your code. It’s optional: without one, blocks render and inputs work, but actions go nowhere.

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

<BlockKitProvider
  onAction={(action, { views, message, state }) => {}}
  onSubmit={(payload, { views }) => {}}
  onOptions={(payload) => ({ options: [] })}
  resolvers={{ user: (id) => users[id]?.name }}
>
  <Message blocks={blocks} />
</BlockKitProvider>;

One provider can hold several surfaces. Each action still carries the message or view it came from.

Props

Handlers

PropType
onAction?(action: BlockAction, context: ActionContext) => void

Called for every action: a click, a selection, a date picked. `action` is one entry of the `block_actions` payload's `actions` array. `context` has `state`, `views` and, for actions in a message, `message`.

Type(action: BlockAction, context: ActionContext) => void
onPayload?(payload: BlockActionsPayload, context: PayloadContext) => void

The same actions, wrapped in the full `block_actions` payload your request URL would receive: team, user, container, `response_url` and `state`. Use it to forward actions to an existing app.

Type(payload: BlockActionsPayload, context: PayloadContext) => void
onSubmit?(payload, context: { views }) => SubmitResult | Promise<SubmitResult>

Called with a `view_submission` payload when a modal's submit button is pressed and its inputs are valid. Return a `response_action` (`errors`, `update`, `push` or `clear`), or nothing to close the modal. If it throws or rejects, the modal stays open.

Type(payload, context: { views }) => SubmitResult | Promise<SubmitResult>
onClose?(payload) => void

Called with a `view_closed` payload when a modal's close button is pressed.

Type(payload) => void
onOptions?(payload: BlockSuggestionPayload) => OptionsResponse | Promise<OptionsResponse>

Answers an `external_select`'s `block_suggestion` request with `{ options }` or `{ option_groups }`, as your options load URL would. Without it, external selects accept a typed value on Enter.

Type(payload: BlockSuggestionPayload) => OptionsResponse | Promise<OptionsResponse>
onStateChange?(state: StateValues) => void

Called whenever an input value changes, with the full `state.values`.

Type(state: StateValues) => void

Data

PropType
resolvers?Resolvers

Look up names for user, channel and usergroup ids, and profiles for the card a user mention opens. See [Mentions and resolvers](/guides/mentions-and-resolvers).

TypeResolvers
emoji?EmojiOptions

`imageUrl(unified)` builds the image URL for a standard emoji; `custom` maps workspace emoji names to image URLs or `alias:<name>`. See [Emoji](/guides/emoji).

TypeEmojiOptions
DefaultApple emoji from jsDelivr
identity?PayloadIdentity

`team`, `user`, `apiAppId`, `token`, `triggerId` and `responseUrl` stamped onto the payloads the provider builds.

TypePayloadIdentity
DefaultPlaceholder ids such as `T00000000` and `U00000000`
errors?Record<string, string>

Validation errors keyed by `block_id`, shown under `input` blocks: the shape of `response_action: "errors"`.

TypeRecord<string, string>

Display

PropType
surface?"message" | "modal" | "home"

The surface loose `<Blocks>` are laid out for. `<Message>`, `<Modal>` and `<HomeTab>` set their own.

Type"message" | "modal" | "home"
Default"message"
theme?"light" | "dark"

Forces a colour scheme for everything inside. Without it, the page's `data-theme` or the system preference applies. See [Theming](/guides/theming).

Type"light" | "dark"
timeZone?string

IANA zone for `<!date>` tokens and date and time elements.

Typestring
DefaultThe viewer's zone
childrenReactNode

The surfaces to render.

TypeReactNode

ActionContext

The second argument to onAction.

PropType
state?StateValues

The value of every input on the surface when the action happened, keyed by `block_id`, then `action_id`, like `view.state.values`.

TypeStateValues
views?ViewsApi

Open, push, update, close and clear modals, and publish the Home tab.

TypeViewsApi
message?MessageApi | undefined

Set for actions in a `<Message>`. `update({ blocks, text })` replaces the message; `delete()` removes it.

TypeMessageApi | undefined

ViewsApi

The calls your app makes with Slack’s views.* methods. A modal opened this way renders above the provider’s children and gets its own input state. Slack allows three modals in the stack.

PropType
open?(view) => string

`views.open`: replaces any open modals with this one. Returns the new view id.

Type(view) => string
push?(view) => string

`views.push`: stacks a modal on top of the current one. Returns the new view id.

Type(view) => string
update?(view, target?: { viewId?; externalId? }) => void

`views.update`: swaps a modal's content, keeping input values whose `block_id` and `action_id` are unchanged. Targets the top modal unless you pass `viewId` or `externalId`.

Type(view, target?: { viewId?; externalId? }) => void
close?() => void

Closes the top modal.

Type() => void
clear?() => void

Closes every open modal.

Type() => void
publish?(view) => void

`views.publish`: replaces the content of the `<HomeTab>` under this provider.

Type(view) => void

Was this page helpful?