The Notion to HTML API will convert your (private) database items to HTML. You can customise the HTML output with multiple query parameters. If you want to convert a public Notion page to HTML. Use this API by @asnunes.
token
parameter in the request body and set the value to the Internal Integration Token
of your Notion integrationhttps://notion-to-html.herokuapp.com/[pageId]
.How to get the pageId? Get it with an integration or see how get it manually (go to "Where can I find my page's ID?").
npm install
to install dependenciesnpm run start
to start the development server on localhost:3000
For production deployment I recommend Heroku
The API uses standard HTTP error codes.
200 - OK
: Everything worked out as expected401 - Unauthorized
: No valid API key provided.500 - Server error
: Something unexpected happened, the API is downNested child blocks are supported only one level depp on toggle, list and to_do blocks.
- First level list
- Second level list
- Third level list (unsupported)
> Second level toggle
> Third level paragraph (unsupported)
callout
blocks are automatically styled with a background color or a borderEach param expects a boolean value and is set to false
by default. To apply a parameter add it to the request query: notion-to-html.herokuapp.com/pageId?param1=true¶m2=true
Key | When set to true |
---|---|
webflow |
Optimizes styling for Webflow Richtext |
uploadImages |
Uploads each uploaded image to Cloudinary |
headingIds |
Adds ids on headings for in-page links |
headingAnchors |
Adds anchor links before each heading |
darkMode |
Optimizes the color scheme for dark mode |
htmlTags |
Converts annotations as HTML tags (instead of styles) |
copyCodeBtn |
Inserts a button for copying code blocks |
webflow
param adds classes to optimize the output for Webflow Rich Text block. See my blog post for copy-paste custom Webflow styles.
Image tweaks:
w-richtext-figure-type-image
w-richtext-figure-type-fullwidth
(for images without caption center
)center
keyword in caption will set the image to centered with the classname w-richtext-align-center
.Other improved elements:
<ul>
(class ul-2nd-level
)pre-container
)divider
)w-richtext-align-fullwidth w-richtext-figure-type-video
, default iframe styling)Toggles are changed to:
<details>
<summary class="toggle-summary">
<div className="toggle-triangle">
<span>▶</span>
</div>
<div className="toggle-summary-content">Toggle summary</div>
</summary>
<div className="details-content">Hidden toggle content</div>
</details>
URLs of images uploaded to Notion expire after one day. This is why each image must pe uploaded to a third party. Note: duplicate uploads are prevented.
Image upload setup:
Start configuring
under Configure your SDK
cloudinaryCloudName
, cloudinaryApiKey
, cloudinaryApiSecret
and set the right values.uploadImages
parameter to trueAdds id
to all heading blocks. With this param turned on, you can use native Notion in-document anchors. Use the link in the form your-page.com/article-slug#heading-id
.
Adds an anchor icon before each heading block. This parameter works only id headingIds
is turned on as well.
The anchor element will have the following form:
<h1>
<a href="#heading-id" class="heading-anchor">
<svg><!-- Anchor icon --></svg>
</a>
<span>Example heading</span>
</h2>
Recommended anchor icon styling:
.heading-anchor {
padding-right: 4px;
margin-left: -20px;
visibility: hidden;
line-height: 1;
border: none !important;
}
h1:hover .heading-anchor,
h2:hover .heading-anchor,
h3:hover .heading-anchor {
visibility: visible;
}
Optimizes the background and text colors for dark mode.
Converts inline styles to corresponding HTML tags.
For example <span style="font-weight:bold">text</span>
changes to converted to <strong>text</strong>
.
Annotation | HTML tag |
---|---|
bold | <strong> |
italic | <i> |
strikethrough | <strike> |
inline co de | <code> |
underline | <u> |
Inserts a button compatible with the FinSweets' Copy to clipboard attribute in each code block. If turned on, the following structure is given to code blocks:
<pre>
<code>{CODE CONTENT}</code>
<a href="#" className="copy-button"
fs-copyclip-element="click"
fs-copyclip-text="{CODE CONTENT}"
fs-copyclip-message="Copied!"
fs-copyclip-duration="1000"
>Copy</a>
</pre>