--- name: custom-blocks description: Create, modify, and troubleshoot custom blocks in Notion Workers. Use when the user wants to build interactive UI inside Notion connected to Notion data. Covers the author workflow from project setup to local preview and deployment. user-invocable: false --- # Custom blocks Custom blocks are user-authored interfaces inside Notion that can connect to Notion workspace data. Custom blocks are in private alpha. The user's workspace might not have custom blocks enabled. If Notion reports that the feature is disabled, the workspace needs access before the user can use the block. A custom block has two parts: - A Worker declaration that uses `@notionhq/workers` to define the build and required data. - A frontend that uses `@notionhq/custom-blocks` to communicate with Notion from a sandboxed iframe. Read the relevant package documentation before changing either part. ## Current limitations Take into account these limits when building a custom block: - **Network access:** The custom block frontend cannot call external APIs or load dependencies from CDNs. Bundle scripts, styles, fonts, and other required assets with the deployed artifact. Use the custom blocks SDK to access Notion data. Images can also use `data:` URLs and permitted Notion-hosted sources. - **Query size:** `useDataSource` returns at most 999 rows per query. The default limit is 20. Use filters to select relevant rows and sorts to order them. Load rows progressively by increasing `limit` as needed, up to 999. If `hasMore` is true, show that the results are incomplete. Do not present calculations over incomplete results as totals for the entire data source. - **Property support:** Custom blocks do not support every Notion property type or operation. Support varies between reading, writing, filtering, and sorting. Check the installed SDK documentation and types for each required operation. - **Query filters:** Filters do not support `or` groups or nested groups. Use one property condition or one `and` group. - **External Links and navigation:** Do not implement external link navigation or authentication redirects with `window.open` or `window.location`. - **Page creation:** `pages.create` cannot set an icon or cover. Create the page first. Then use `pages.update` to set its icon or cover. - **Availability:** Custom blocks require private-alpha access. Page guests cannot view custom blocks. Notion Sites does not render them. ## Build the block The frontend must use the custom blocks SDK to connect to Notion and follow the sandbox constraints. You can use any framework that builds an `index.html` file and its browser assets. We recommend React with Vite. The examples below use React, Vite, and TypeScript. ### 1. Prepare the project For a new project, create a Worker from a custom block template: ```shell ntn workers new my-worker-name --template