The handshake
Three messages establish the connection:- The block sends
connectwhen the SDK loads. - The host replies with
init, carrying the block’s context. - The block sends
initResultto confirm it accepted the context.
NotionCustomBlock renders children after initialization succeeds.
When connected to a host, initialization validates all declared data source bindings. See binding a block to Notion data for how that works and what it means for your code.
If the host does not respond within the timeout, initialization rejects. The default is 15 seconds, which is deliberately longer than Notion’s own 10-second watchdog so that a host-reported error reaches you before the SDK’s generic timeout does.
Block and app context
The SDK provides getters, subscriptions, and React hooks for block and app context.Getter
Getters return the current value, such as the theme, current user, or containing page. They throw if called before initialization completes.Subscription
Subscriptions deliver the initial value and later changes. You can register them before initialization. They wait for initialization before delivering the initial value, or deliver immediately if initialization is complete.React hook
In React, use context hooks insideNotionCustomBlock. The wrapper waits for initialization, and the hooks keep components current as values change. React handles subscription cleanup when the component unmounts.
When initialization fails
Initialization rejects with aCustomBlockInitializationError, carrying a code and an isRetryable flag alongside the message.
If you open the block directly in a browser tab, initCustomBlock() rejects with NotInIframeError.
Use the dev shell when you need realistic host behavior or data source bindings.
Other codes describe what the host could not provide: a missing or invalid manifest, an unsupported protocol version, unavailable context or user, or a data source binding that is missing, unavailable, or does not match the declared schema. See error handling for the full contract.
Debug console
Press\ inside a running block to swap its UI for a log of the messages passing between the block and the host, and \ again to go back. This is the fastest way to see why a block is stuck in its loading state. It is built into NotionCustomBlock, so it is only available to blocks using the React SDK. See previewing before deploy.