Building Rich Text Editors the Right Way (abridged)
At work, I've added a few rich text editors to our product using Lexical. Same underlying component, but different constraints in each place.
I thought that, since the library handles all the gnarly stuff, this should be easy. Nope! I want to write a longer post with examples, but my take on how to do this right is:
- Make the import/export format use HTML
- Take the HTML and map it to a pandoc AST, store that in your database (likely using the JSON AST)
- Convert from that format to whatever format you need (still using
pandoc) on the backend - If you're upgrading an existing field, store the plain text version separately for backwards compatibility and use a new field for the AST
In an ideal world, you would store Lexical's own tree structure in your database. That's the lossiest data format you could store it; Lexical's node tree has all of the metadata/config you could need. That, unfortunately, restricts how you can use it unless you're willing to:
- Write your backend in JS and use Lexical to handle it
- Maintain your own converter between
pandoc's AST and Lexical's node tree
With the pandoc AST, you're as close to Lexical's node tree as you can without either issue above. HTML as the import/export format gets close to that as well, but not quite. Still, it's good enough for the interchange format.