> ## 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.

# Appearance and sizing

> Match Notion's theme and let the host resize the block to fit its content.

<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>

A block should look like part of the page it sits in and should be as tall as its content. Both are cooperative: the SDK exposes Notion's design tokens, and the block reports the height it wants rather than setting it.

## Design tokens

`NotionTokenScope` makes Notion's design tokens available to descendants and keeps them in sync as the host's appearance changes. Pair it with the `@notionhq/custom-blocks/nds.css` import so the block matches the page it sits in, including dark mode and high contrast.

```tsx theme={null}
import "@notionhq/custom-blocks/nds.css"
import {
	NotionCustomBlock,
	NotionTokenScope,
} from "@notionhq/custom-blocks/react"

<NotionCustomBlock>
	<NotionTokenScope>
		<App />
	</NotionTokenScope>
</NotionCustomBlock>
```

## Theme and contrast

Use design tokens to style the block. When your code needs the current appearance, use a getter, subscription, or React hook. Theme is `"light"` or `"dark"`. Contrast mode is `"standard"` or `"high"`.

The getter and subscription names below are methods on `customBlock`. Import React hooks from `@notionhq/custom-blocks/react`.

| Context | Getter | Subscription | React hook |
| - | - | - | - |
| Theme | `getTheme()` | `subscribeToTheme(callback)` | `useTheme()` |
| Contrast mode | `getContrastMode()` | `subscribeToContrastMode(callback)` | `useContrastMode()` |

Getters read the current value after [initialization](/custom-blocks/sdk/initialization). Subscriptions can register earlier. They deliver the initial value once initialized, then later changes. React hooks keep components current when called inside `NotionCustomBlock`.

See [app context](/custom-blocks/sdk/app-context#api-overview) for examples and subscription cleanup.

## Sizing

React blocks wrapped in `NotionCustomBlock` resize automatically to fit their content. In a framework-neutral frontend, call `customBlock.autoResize({ target })` after `initCustomBlock()` resolves, passing the element whose height should drive the iframe.

Notion clamps automatically reported heights to a minimum of 100 pixels and a maximum of 10,000 pixels.

To cap automatic sizing at a shorter height, set `max-height` and `overflow-y` on `#root`:

```css theme={null}
#root {
	max-height: 600px;
	overflow-y: auto;
}
```

If a viewer drags the block's resize handle, the manually set height takes precedence over automatic content sizing. Automatic sizing resumes when the viewer chooses **Fit content**.
