> ## Documentation Index
> Fetch the complete documentation index at: https://developers.notion.com/llms.txt
> Use this file to discover all available pages before exploring further.

# App context

> Read the block's ID, parent, page, and viewing user, and follow them as they change.

<Warning>
  Custom blocks are in private alpha:

  * Do not discuss publicly or share with anyone outside your workspace.
  * Access must be enabled per workspace. Installing the SDK does not grant access.
  * These APIs may experience breaking changes without notice.
</Warning>

App context is what the host tells the block about where it is running. All of it arrives in the init payload and stays current for the life of the block.

## 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 on `customBlock`, imported from `@notionhq/custom-blocks`. Import React hooks from `@notionhq/custom-blocks/react`.

| Context | Getter | Subscription | React hook |
| - | - | - | - |
| Current user | `getCurrentUser()` | `subscribeToCurrentUser(callback)` | `useCurrentUser()` |
| Custom block ID | `getBlockId()` | `subscribeToBlockId(callback)` | `useBlockId()` |
| Parent | `getParent()` | `subscribeToParent(callback)` | `useParent()` |
| Containing page | `getPage()` | `subscribeToPage(callback)` | `usePage()` |
| Theme | `getTheme()` | `subscribeToTheme(callback)` | `useTheme()` |
| Contrast mode | `getContrastMode()` | `subscribeToContrastMode(callback)` | `useContrastMode()` |
| Manifest | `getManifest()` | `subscribeToManifest(callback)` | `useManifest()` |

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:

```ts theme={null}
import { customBlock, initCustomBlock } from "@notionhq/custom-blocks"

await initCustomBlock()
const theme = customBlock.getTheme()
console.log(theme)
```

### Subscription

Register before initialization to receive the initial theme and later changes:

```ts theme={null}
import { customBlock, initCustomBlock } from "@notionhq/custom-blocks"

const unsubscribe = customBlock.subscribeToTheme(theme => {
  console.log(theme)
})

await initCustomBlock()

// Call unsubscribe() when the view is removed to stop future callbacks.
```

### React hook

Use `useTheme()` inside `NotionCustomBlock` to keep the component current. React handles subscription cleanup when the component unmounts.

```tsx theme={null}
import { NotionCustomBlock, useTheme } from "@notionhq/custom-blocks/react"

export function App() {
  return (
    <NotionCustomBlock>
      <ThemeLabel />
    </NotionCustomBlock>
  )
}

function ThemeLabel() {
  const theme = useTheme()
  return <p>Current theme: {theme}</p>
}
```

## Current user

Use `getCurrentUser()`, `subscribeToCurrentUser()`, and `useCurrentUser()` to access the viewing user's `NotionUser`. See [users](/custom-blocks/sdk/users) for profile fields and user APIs.

## Custom block ID

Use `getBlockId()`, `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

Use `getParent()`, `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

Use `getPage()`, `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:

| Parent | Meaning |
| - | - |
| `{ type: "page_id", page_id }` | The object is directly inside a page surface: a regular page, a full-page database, or a wiki root. |
| `{ type: "data_source_id", data_source_id }` | The object belongs to a data source. For a custom view, this is the data source shown by the view. |
| `{ type: "workspace", workspace: true }` | The object is directly under the workspace. |
| `{ type: "block_id", block_id }` | The object is directly inside another block, such as a toggle, column, or callout. |
| `{ type: "agent_id", agent_id }` | The object belongs to an agent instruction page or one of its blocks. |

A wiki root is a page surface. The bridge treats it as a page surface for page context, parent reporting, and page APIs:

* `usePage().id` can be the wiki root's ID.
* A custom block directly on the wiki root can receive that ID as `useParent().page_id`.
* `usePage().parent` describes 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](/custom-blocks/sdk/appearance) for styles and examples.

## Manifest

Use `getManifest()`, `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](/custom-blocks/sdk/data-sources) for manifest details and `subscribeToDataSource()` for query snapshots.
