API overview
Each context value has a getter, a subscription, and a React hook. Use a getter to read the current value once. Use a subscription to receive the initial value and later changes. In React, use a hook to keep a component current as the value changes. The getters and subscriptions below are methods oncustomBlock, imported from @notionhq/custom-blocks. Import React hooks from @notionhq/custom-blocks/react.
Getters throw before initialization completes. In React, call context hooks inside
NotionCustomBlock, which waits for initialization before rendering its children.
Subscriptions can register before initialization. They wait for initialization before delivering the initial value, or deliver immediately if initialization is complete. Start initialization with initCustomBlock() or NotionCustomBlock. Subscriptions do not start it themselves. These initialization APIs also report failures. Each subscription returns an unsubscribe function. Repeated cleanup calls have no effect.
After initial delivery, subscriptions compare values with Object.is. Objects use referential equality: a new reference triggers a callback even if its contents are unchanged. Updates to other context values do not trigger the callback. React hooks follow the same comparison rules.
Getter
Read the current theme after initialization:Subscription
Register before initialization to receive the initial theme and later changes:React hook
UseuseTheme() inside NotionCustomBlock to keep the component current. React handles subscription cleanup when the component unmounts.
Current user
UsegetCurrentUser(), subscribeToCurrentUser(), and useCurrentUser() to access the viewing user’s NotionUser. See users for profile fields and user APIs.
Custom block ID
UsegetBlockId(), subscribeToBlockId(), and useBlockId() to access the custom block’s own NotionBlockId.
The ID is stable for the lifetime of the block. Each subscription delivers once, unless cancelled before initialization. You can register before initialization without an error.
Parent
UsegetParent(), subscribeToParent(), and useParent() to access the block’s NotionParent.
For most blocks, the parent is the immediate container in the document tree. It is the containing page only when the block sits directly inside that page.
Custom views are an exception. Their backing custom block is attached to a view. The bridge reports the data source associated with that view as { type: "data_source_id", data_source_id }.
For a custom block directly inside a page surface, the bridge reports { type: "page_id", page_id }.
Containing page
UsegetPage(), subscribeToPage(), and usePage() to access a CustomBlockPage with the page’s id and parent.
The containing page is the nearest page surface. Its parent describes the page surface, not the custom block.
A page surface can be a regular page, a full-page database, or a wiki root.
Parent values
useParent() and usePage().parent use the NotionParent type. The result has one of these shapes:
A wiki root is a page surface. The bridge treats it as a page surface for page context, parent reporting, and page APIs:
usePage().idcan be the wiki root’s ID.- A custom block directly on the wiki root can receive that ID as
useParent().page_id. usePage().parentdescribes the wiki root’s own parent.
Theme and contrast mode
The theme APIs return"light" or "dark". The contrast mode APIs return "standard" or "high". See appearance and sizing for styles and examples.
Manifest
UsegetManifest(), subscribeToManifest(), and useManifest() to access the declared CustomBlockManifest. The manifest stays fixed for the lifetime of the running block, so each subscription delivers it once. You can register before initialization without an error.
See data sources for manifest details and subscribeToDataSource() for query snapshots.