Rotion draws Notion pages and databases with React components. Galleries, tables, calendars and every kind of block come styled and ready, and the site builds to plain static HTML. Everything below was fetched from Notion and drawn by Rotion when this page was built.
Things I will do by tomorrow:
This principle has been a key, and a huge success in my years of software engineering. A common problem among software engineers and developers today is that they tend to over complicate problems.
https://people.apache.org/~fhanik/kiss.html
Go:
func main() {
v := "world"
fmt.Printf("hello %s!", v)
}The solar system planets size:
Planet | Radius |
Sun | 696,340 km |
Mercury | 2,439.7 km |
Venus | 6,051.8 km |
Earth | 6,371 km |
Mars | 3,389.5 km |
Jupiter | 69,911 km |
Saturn | 58,232 km |
Uranus | 25,362 km |
Neptune | 24,622 km |
Pluto | 1,188.3 km |

<Page blocks={blocks} />Every block, drawn the way Notion shows it
Each tile is cut from a real Notion page. Open one to see the whole page and how Rotion renders it.
1st header
2nd header
3rd header
Callout with Paragraph
Callout with Paragraph
Callout with Paragraph
Callout with Paragraph

Things I will do by tomorrow:
Go:
func main() {
v := "world"
fmt.Printf("hello %s!", v)
}
The solar system planets size:
Planet | Radius |
Sun | 696,340 km |
Mercury | 2,439.7 km |
Venus | 6,051.8 km |
Earth | 6,371 km |
Mars | 3,389.5 km |
Jupiter | 69,911 km |
Saturn | 58,232 km |
Uranus | 25,362 km |
Neptune | 24,622 km |
Pluto | 1,188.3 km |
This principle has been a key, and a huge success in my years of software engineering. A common problem among software engineers and developers today is that they tend to over complicate problems.
https://people.apache.org/~fhanik/kiss.html
Make it look like your site
The components come styled, and every part of that styling can be changed. There are four ways to do it.
Set the custom properties
Colors, fonts, borders, corners and the gallery’s columns are --rotion-* custom properties. Set them on :root, or on a wrapper to style one part of the site.
.blog {
--rotion-font-family: 'Inter', sans-serif;
--rotion-primary-text: #3d1a1f;
--rotion-border-radius: 12px;
--rotion-gallery-grid-template-columns-medium: repeat(3, 1fr);
}Style any element by its class
Every element the components render has a class name starting with rotion-, so plain CSS reaches whatever the properties do not.
.rotion-gallery-card:hover {
transform: translateY(-2px);
}
.rotion-text-h1 {
font-family: 'Fraunces', serif;
}Choose how dark mode works
rotion/style.css follows the operating system’s setting. Import rotion/style-without-dark.css instead to switch themes your own way.
// Follows prefers-color-scheme
import 'rotion/style.css'
// Or leave dark mode to your site
import 'rotion/style-without-dark.css'Decide what each view shows
Props and options choose the properties to show, where each row links, the size of the cards and more.
<Gallery
db={db}
keys={['Name', 'Tags']}
options={{
href: { Name: '/people/[id]' },
image: { size: 'large', fit: false },
}}
/>From a Notion page to HTML
Fetch the page, fetch its blocks, and hand them to the Page component. Images and files are downloaded next to your site, so nothing you publish points back to Notion.
The arrows show which way the data flows.
Install and render a page
Install the package, set NOTION_TOKEN, and a Notion page is a few lines of code away.
npm install rotionimport { FetchBlocks, FetchPage } from 'rotion'
import { Page } from 'rotion/ui'
const id = process.env.NOTION_PAGE_ID!
export default async function Home() {
const page = await FetchPage({
page_id: id,
last_edited_time: 'force',
})
const blocks = await FetchBlocks({
block_id: id,
last_edited_time: page.last_edited_time,
})
return <Page blocks={blocks} />
}