Richer Text


Photo by Ray Hennessy on Unsplash

Announcing Richer Text v2.0! 🎉

Published June 28, 2024 by Andrea Fomera

Richer Text is now v1.0v2.0 and ready for production use.

When I started this project at the end of 2022, my goal was to use it to learn React so I could better help on things at work. My goals have since shifted for Richer Text and it’s become so much bigger and better than I could have ever imagined. It became my goal to make the text editor I’ve always wanted for my Ruby on Rails applications, but without giving up the niceties that ActionText provides.

In early 2024 the decision was made to rewrite the entire editor using Lit to build custom elements directly without React as a dependency.

What is Richer Text?

Richer Text is a modern text editor built on top of Tiptap, and ProseMirror. It includes a mechanism for storing either HTML or JSON that is returned from Tiptap and rendering the content, inspired by ActionText’s functionality of storing content separately from the model.

Richer Text features a roboust text editor complete with everything from the basics to rich custom embeds. For a full list of features check below:

Why another editor?

Great question, my motives for starting Richer Text were spurred by the desire to have a flexible editor that I could easily extend and fully customize the way I always wanted to with Trix.

Trix served me well for many years, but in 2023, nearly 2024 it’s time to make way for new editors.

Enter, Tiptap which is built on ProseMirror and handles much of the heavy lifting for us with wrangling ProseMirror into sensible code, but it comes headless. The perfect fit for someone looking to provide their own UI for an editor, thus Richer Text was born.

Is Richer Text’s name a jab/poke at anyone/thing?

Nope, it’s really not. I loved using ActionText in my projects, until I ran into issues customizing Trix for my needs (ever try adding tables to trix? 😅). I think it’s a great library and loved the simplicity of storing Rich Text in it’s own table. I only picked the name Richer Text because i’m boring and could get the domain + rubygem name combo I liked.

JSON vs HTML storage

Which is better? 🤪 Just kidding, it’s really up to you. Though I recommend choosing JSON storage for your content, since you’ll have full control over the rendering of HTML, and your content will always render the most up-to-date HTML if you change how an Image should render.

By choosing JSON storage, you also get the ability to use Richer Text’s custom embeds, built in oEmbed support, iframely’s 1900+ embeds and more.

Future vision

I know it’s an uphill climb to reach adoption with Richer Text, but I hope you’ll give it a good try. I want to make the best storage solution for Rich content out there, that allows extensibility and choosing your own front-end text editor.

That’s why I built support in for Rhino Editor to store it’s content as JSON on the backend. While I hope people want to use my editor, I also just want to provide an ActionText like solution for other text editors.

Perhaps one day in the future, we’ll have a Markdown text editor, and you’ll probably find me extending Richer Text to store and render Markdown content.

How does it work?

While you can use RicherText.js outside of Ruby on Rails and still benefit from a great text editor, where it really shines is when you use it with the richer_text rubygem.

Getting started is a matter of a few commands:

bundle add richer_text

rails richer_text:install

rails db:migrate

Once you’ve done that you can setup your Model with the Richer Text attribute:

class Post < ApplicationRecord
  # One example is storing the JSON from the text editor:
  has_richer_text :body, store_as: :json
  # Or to store HTML...
  # has_richer_text :body
end

Permit the body attribute in your controller params

  params.require(:post).permit(:title, :body)

In your _form.html.erb partial:

  <%= form.label :body %>
  <%= form.richer_text_area :body %>

Then you can render the content out with:

  <%= @post.body %>

That’s all! Enjoy using RicherText 🥳

Try it out