How to Build a Notion-style editor with AI-powered autocompletion
![How to Build a Notion-style editor with AI-powered autocompletion](/content/images/size/w2000/2024/04/ph_feature_image_5@3x-1.png)
TLDR: In this article, we will explore a high-level design of Potion —a Notion-style email builder with AI-powered autocompletion. Also, I just launched Potion on Producthunt.
Let’s get started.
Requirements
Rich-text editors come in all shapes and forms e. g., editors in apps like Substack, Medium and even Notion.
![](https://blog.ohansemmanuel.com/content/images/2024/04/image.png)
But let’s take these one step further and create an editor not simply capable of text inputs, but includes interactive nodes and exports to valid email HTML.
- The editor must be capable of supporting text (without any character limits)
- The editor must support rich content such as images
- The editor must support email template nodes such as buttons and dividers
- The editor must be able to support layout columns e.g., a 2-column or 3-column layout
![](https://cdn-images-1.medium.com/max/800/1*ZCROIMELbvCuAlvPpzSfWg.png)
Here’s an example of Potion with the Netflix email template:
![](https://cdn-images-1.medium.com/max/800/1*l1peYMEGV0YG23ViQZkcsw.gif)
High-level design
I’ll skip the overall system design (databases, API gateway, edge middleware etc.) and focus solely on what goes on in the clients:
1. The Potion Editor
The main components of our editor include a global state and associating view and model.
![](https://blog.ohansemmanuel.com/content/images/2024/04/image-2.png)
To parse the editor state and render valid email output, the entire content of the editor is powered by a very strict schema (model) that enforces what’s possible and visible to a user (the view).
For a rich extensible headless editor, I chose Tiptap.
![](https://blog.ohansemmanuel.com/content/images/2024/04/image-3.png)
2. The Potion Renderer
When a user previews the editor content, they must get the same visual representation but an HTML output. To be specific, XHTML 1.0 (the markup supported in most email clients)
![](https://cdn-images-1.medium.com/max/800/1*4GIMb7eHzIQXmC5yxHUJ0A.gif)
The potion renderer takes an object representation of the editor state, walks the entire tree and maps each view item to corresponding email-compatible markup while keeping the same styles and output.
![](https://blog.ohansemmanuel.com/content/images/2024/04/image-4.png)
If you strip away the custom code for walking the tree and other business logic, the email-compatible components are provided by react-email.
![](https://blog.ohansemmanuel.com/content/images/2024/04/image-5.png)
In a nutshell, the potion renderer could be summarised as state (object) + theme (object) = React Fragment nodes [] eventually rendered to HTML by react-email.
When you bring it all together, you have a combination of two main components.
![](https://blog.ohansemmanuel.com/content/images/2024/04/image-6.png)
Shameless plug: Support Potion on Producthunt
Worthy mentions
If we zoom into one of the editor components (view), our design must include custom nodes such as buttons, images, layout grids etc.
![](https://cdn-images-1.medium.com/max/800/1*YTE5knTos3XbGPv8j-EgyQ.gif)
These aren’t supported natively by Tiptap. However, the underlying editor used by Tiptap, prosemirror, supports plugins — there’s also an associated API within Tiptap.
This means we could define custom schemas and associating nodes.
![](https://blog.ohansemmanuel.com/content/images/2024/04/image-7.png)
What about AI autocompletion?
AI’s all the rage these days, and for good reasons.
![](https://cdn-images-1.medium.com/max/800/1*NUZjnp-lLctlZO4hwmGx8g.gif)
Except you’re fine-tuning an open-source model or creating a custom model, creating streaming UI interfaces isn’t a complex feat.
The easiest way to build this as a React developer is to use the Vercel AI SDK.
This is how Potion works under the hood as well.
![](https://blog.ohansemmanuel.com/content/images/2024/04/ph_feature_image_1@3x-1.png)
Conclusion
There are many interesting technical challenges with building such an editor. I could write a series of blog posts on this. Ultimately, this was fun to build!
P.S.: Check out Potion on Producthunt.