This site you're looking at underwent a
Gatsby +
MDX to
Next.js +
Notion transformation. It's still early but it feels like my ideal setup. I can add/edit a post in Notion and see the changes live without a new build.
The rest of this post goes through how I customized this flow to get back some of the MDX benefits. Take a look at the source Notion page and corresponding
API JSON to follow along.
Custom rendering
react-notion
comes with styling that renders your blocks to look like Notion. If you look at
the Block
component, it's a big render function that switch/cases on the block type. By forking this library, I'm able to render each block type however I want.
Toggle blocks
We're going to take advantage of the toggle block. This block has its own title
field as well as children blocks. We can use the title
field to identify our block. Then we can handle the children as we want.
One thing I do with toggle blocks is hide content that's referenced elsewhere. If the title
of a toggle is Ignore, that block is not rendered. If you look at the Notion source, there's an ignored toggle right here.
Inline tables
Notion tables are great for structured data and can be inlined inside pages. I custom handle Notion tables named
Panes. A link to a page inside a
Panes table will open a pane.
Try this link. And I can put this
Panes table inside my
Ignore toggle so the table isn't rendered.
Custom components
One reason developers love MDX is the ability to render
custom React components inside your markdown. Here's a hacky way to achieve something similar with Notion.
If a toggle block's title looks like <Component>, it's checked against a map of names to React components. A name match will render that component. If the first child block is a JSON code block, that JSON will be parsed and passed as props to the component. Any additional child block is passed as React children, recursively rendered by react-notion
. With this setup, you get most of the benefits of MDX custom components.
toggle
An example <MyCustomComponent>
toggle
<MyCustomComponent>
If you want to see these pieces in action, check out the
Monads for JavaScript developers post. I embed the VSCode editor inside panes that are loaded on demand.