
Notion Renderer
A fully customizable React renderer for the official Notion API.
Please note that this package is currently in alpha release.
Therefore, there may be significant changes to the API without prior notice.
Example
Installation
npm install @udus/notion-renderer@alpha
Usage
Quick Start
First, fetch the blocks of the page you want to render using fetchBlockList.
Next, pass the fetched block list to the BlockRenderer.
If you are using Next.js, you can do it as shown in the sample code below.
import { BlockRenderer } from "@udus/notion-components/components";
import { fetchBlockList } from "@udus/notion-components/libs";
import type { InferGetStaticPropsType, NextPage } from "next";
export const getStaticProps = async () => {
const blocks = await fetchBlockList("YOUR_PAGE_ID");
return {
props: {
blocks,
},
};
};
type Props = InferGetStaticPropsType<typeof getStaticProps>;
const Index: NextPage<Props> = ({ blocks }) => {
return <BlockRenderer blocks={blocks} />;
};
export default Index;
And you will need to import CSS styles like below.
// Load the CSS to be used with the Notion Renderer.
import "@udus/notion-components/styles/globals.css";
// Load the CSS used for rendering equations
import "katex/dist/katex.min.css";
Please set your Notion integration token as an environment variable named NOTION_TOKEN.
.env
NOTION_TOKEN=secret_epO17gyx***********************************
Custom Component
You can render the page using a custom component instead of the default components, you can also create and use your own components. Please see the example of creating custom components at the following link: https://github.com/udus122/notion-renderer/tree/alpha/src/components/Blocks/Custom
export default () => (
<BlockRenderer
blocks={blocks}
blockMapper={
toggle: OpenedToggle,
heading_1: OpenedHeading1,
heading_2: OpenedHeading2,
heading_3: OpenedHeading3,
} />
)
Color
If you want to use dark mode, please set the theme to theme="dark" as follows.(theme="light" is default.)
export default () => (
<BlockRenderer blocks={blocks} theme="dark" />
)
If you want to change the color theme, please overwrite the CSS variables set to .notion-light or .notion-dark as follows. The default values are listed below.
:root {
/* light-theme */
--color-text-default: rgb(55 53 47);
--color-bg-default: rgb(255 255 255);
--color-pill-default: rgb(227 226 224 / 50%);
--color-text-gray: rgb(120 119 116);
--color-bg-gray: rgb(241 241 239);
--color-pill-gray: rgb(227 226 224);
--color-text-brown: rgb(159 107 83);
--color-bg-brown: rgb(244 238 238);
--color-pill-brown: rgb(238 224 218);
--color-text-orange: rgb(217 115 13);
--color-bg-orange: rgb(251 236 221);
--color-pill-orange: rgb(250 222 201);
--color-text-yellow: rgb(203 145 47);
--color-bg-yellow: rgb(251 243 219);
--color-pill-yellow: rgb(253 236 200);
--color-text-green: rgb(68 131 97);
--color-bg-green: rgb(237 243 236);
--color-pill-green: rgb(219 237 219);
--color-text-blue: rgb(51 126 169);
--color-bg-blue: rgb(231 243 248);
--color-pill-blue: rgb(211 229 239);
--color-text-purple: rgb(144 101 176);
--color-bg-purple: #eae4f2;
--color-pill-purple: rgb(244 240 247 / 80%);
--color-text-pink: rgb(193 76 138);
--color-bg-pink: rgb(249 238 243 / 80%);
--color-pill-pink: rgb(245 224 233);
--color-text-red: rgb(212 76 71);
--color-bg-red: rgb(253 235 236);
--color-pill-red: rgb(255 226 221);
/* dark-theme */
.notion-dark {
--color-text-default: rgb(255 255 255 / 81%);
--color-bg-default: rgb(25 25 25);
--color-pill-default: rgb(55 55 55);
--color-text-gray: rgb(155 155 155);
--color-bg-gray: rgb(47 47 47);
--color-pill-gray: rgb(90 90 90);
--color-text-brown: rgb(186 133 111);
--color-bg-brown: rgb(74 50 40);
--color-pill-brown: rgb(96 59 44);
--color-text-orange: rgb(199 125 72);
--color-bg-orange: rgb(92 59 35);
--color-pill-orange: rgb(133 76 29);
--color-text-yellow: rgb(202 152 73);
--color-bg-yellow: rgb(86 67 40);
--color-pill-yellow: rgb(137 99 42);
--color-text-green: rgb(82 158 114);
--color-bg-green: rgb(36 61 48);
--color-pill-green: rgb(43 89 63);
--color-text-blue: rgb(94 135 201);
--color-bg-blue: rgb(20 58 78);
--color-pill-blue: rgb(40 69 108);
--color-text-purple: rgb(157 104 211);
--color-bg-purple: rgb(60 45 73);
--color-pill-purple: rgb(73 47 100);
--color-text-pink: rgb(209 87 150);
--color-bg-pink: rgb(78 44 60);
--color-pill-pink: rgb(105 49 76);
--color-text-red: rgb(223 84 82);
--color-bg-red: rgb(82 46 42);
--color-pill-red: rgb(110 54 48);
}
}
Supported Objects
Block
Most common block types are supported.
| Block Type | Supported | Mapper Field Name | HTML Tag | Notes |
|---|---|---|---|---|
| Audio | audio |
<audio> |
||
| Bookmark | bookmark |
<div> |
When retrieving an object from the API, we use @extractus/article-extractor to obtain meta information of the site such as OGP images and descriptions. | |
| Breadcrumb | breadcrumb |
<div> |
When retrieving an object from the API, we recursively obtain the parent page. | |
| Bulleted list item | bullted_list/bullted_list_item |
<ul>/<li> |
||
| Callout | callout |
<div> |
||
| Child database | child_database |
<Link> |
||
| Child page | child_page |
<Link> |
||
| Code | code |
<pre><code> |
By default, SyntaxHighlight is not included. If necessary, please create a custom component. | |
| Column list and column | column_list |
<div> |
||
| Divider | divider |
<hr> |
||
| Embed | embed |
passing the oEmbed content to dangerouslySetInnerHTML |
When retrieving an object from the API, we use @extractus/oembed-extractor to obtain the oEmbed content. | |
| Equation | equation |
katex | In order to render properly, you need to import katex/dist/katex.min.css. |
|
| File | file |
<Link> |
||
| Heading1 | heading_1 |
<h1> |
||
| Heading2 | heading_2 |
<h2> |
||
| Heading3 | heading_3 |
<h3> |
||
| Image | image |
<img> |
||
| Link Preview | link_preview |
<Link> |
When retrieving an object from the API, we use @extractus/article-extractor to obtain meta information of the site such as OGP images and descriptions. | |
| Link To Page | link_to_page |
<Link> |
||
| Numbered lit item | numbered_list/numbered_list_item |
<ol>/<li> |
||
| Paragraph | paragraph |
<p> |
||
pdf |
<object type="application/pdf> |
|||
| Quote | quote |
<blockquote> |
||
| Synced block | synced_block |
<div> |
||
| Table | table |
<table> |
||
| Table of contents | table_of_contents |
<div> |
||
| Template | template |
Deprecated | ||
| To do | to_do |
<div> |
||
| Toggle Blocks | toggle |
<details><summary> |
||
| Video | video |
<video> |
YouTube is supported through the oEmbed API. |
Rich text
| Rich text Type | Supported | Mapper Field Name | HTML Tag | Notes |
|---|---|---|---|---|
| Equation | equation |
katex | In order to render properly, you need to import katex/dist/katex.min.css. |
|
| Mention | mention |
<span> |
||
| Text | text |
<span> |
Annotation
| Annotation Type | Supported | Mapper Field Name | HTML Tag | Notes |
|---|---|---|---|---|
| Bold | bold |
<strong> |
||
| Italic | italic |
<em> |
||
| Strikethrough | strikethrough |
<del> |
||
| Underline | underline |
<u> |
||
| Code | code |
<code> |
||
| Color | color |
<span> |
Page
| Page components | Supported | Notes |
|---|---|---|
| Cover | ||
| Icon | ||
| Title |
Properties
| Property Type | Supported | Mapper Field Name | Notes |
|---|---|---|---|
| Checkbox | checkbox |
||
| Created by | created_by |
||
| Created time | created_time |
||
| Date | date |
||
email |
|||
| Files | files |
||
| Formula | formula |
||
| Last edited by | last_edited_by |
||
| Last edited time | last_edited_time |
||
| Multi-select | multi_select |
||
| Number | number |
||
| People | people |
||
| Phone number | phone_number |
||
| Relation | relation |
WIP | |
| Rollup | rollup |
WIP | |
| Rich text | rich_text |
||
| Select | select |
||
| Status | status |
||
| Title | title |
||
| URL | url |
||
| Unique ID | unique_id |
||
| Verification | verification |
Database
| Layout Type | Supported | Layout Name | Notes |
|---|---|---|---|
| Table | table |
||
| Gallery | gallery |
||
| List | list |
||
| Board | board |
||
| Calendar | calendar |
||
| Timeline | timeline |
Contributing
Pull requests are welcome.