How to add and customize the Trix Editor for your Ruby on Rails Application
Pretend we have a user model and we want to add a rich text field called bio to it. We want the user to write and format their bio with Bold, Underline, Italic and Lists.
We’re going to go through these steps to make this happen:
- Install Action Text and Trix
- Add the Trix Editor to your form
- Set up a Stimulus Controller for the Trix Editor (optional)
- Add an underline button to the Toolbar
- Remove buttons from the Toolbar
- Add custom icons to the Toolbar
- Make it pretty
TLDR; Check out the final code.
We also have our model, views, controllers, and routes ready to go — models/user.rb, views/users/show.html.erb, views/users/edit.html.erb, controllers/users.rb plus a route /users/:id that’s aliased as edit_user_path
Let’s get started.
1. Install Action Text and Trix
Check out the Rails Action Text documentation to get set up. Otherwise, I’ll do a quick summary.
First, install Action Text
Note: This automatically installs the Trix Editor package for you. But, it doesn’t install Rails Active Storage, which is required if you want your editor to handle uploading images and files.
bin/rails action_text:install
Then, add Action Text & Trix Editor to your Javascript entrypoint
// @ application.js
import “Trix”
import “@rails/actiontext”
Then, add rich text to your user model
# @ models/user.rb
has_rich_text :bio
Finally, render the rich text
# @ views/users/show.html.rb
<%= @user.bio %>
2. Add the Trix Editor to your form
All you need to do is add the rich_text_area form tag to your form and the Trix Editor will be instantiated and ready for use.
# @ views/users/edit.html.erb
<%= form_with model: @user %, url: edit_user_path(@user.id), method: patch do |form| >
<%= form.rich_text_area :bio %>
<%= form.submit “Save” %>
<% end %>
You should see the editor now! <link to playground>
3. Set up a Stimulus Controller for the Trix Editor (optional)
To keep it all in rails land, we are going to put our javascript in a Stimulus Controller. However, you can skip this step and put the pure javascript code elsewhere.
Follow the Hotwired Guide to installing Stimulus in your application and generate and register your Stimulus Controller. We’re going to start by listening to events fired by the Trix Editor.
// @ assets/javascripts/controllers/trix-controller.js
import { Controller } from "@hotwired/stimulus";
export default class TrixController extends Controller {
connect() {
// wait for the trix editor is attached to the DOM to do stuff
addEventListener("trix-initialize", function (event) {
console.log("im inititalized!");
// ...
// add underline code
// remove buttons code
// add custom icons code here
// ...
}, true);
// remove file upload handling
addEventListener("trix-file-accept", function (event) {
event.preventDefault();
}, true);
}
}
Don’t forget to attach your controller to the editor!
# @ views/users/edit.html.erb
<%= form.rich_text_area :bio, data: { controller: "trix" } %>
4. Add an underline button to the Toolbar
Trix doesn’t automatically come with an underline formatting option, let’s add that back in.
// @ assets/javascripts/controllers/trix-controller.js
// inside the 'trix-initialize' event listener
// initialize underline attribute
Trix.config.textAttributes.underline = {
tagName: "u",
style: { textDecoration: "underline" },
inheritable: true,
parser: function (element) {
var style = window.getComputedStyle(element);
return style.textDecoration === "underline";
},
};
// create underline button
let underlineEl = document.createElement("button");
underlineEl.setAttribute("type", "button");
underlineEl.setAttribute("data-trix-attribute", "underline");
underlineEl.setAttribute("data-trix-key", "u");
underlineEl.setAttribute("tabindex", -1);
underlineEl.setAttribute("title", "underline");
underlineEl.classList.add("trix-button", "trix-button--icon-underline");
underlineEl.innerHTML = "U";
// add button to toolbar - inside the text tools group
document.querySelector(".trix-button-group--text-tools").appendChild(underlineEl);
Your editor should look something like this now.
5. Remove buttons from the Toolbar
Use either css to hide buttons or javascript to completely remove buttons from the toolbar.
Hiding with css.
// @ assets/stylesheets/actiontext.scss
.trix-button--icon-strike,
.trix-button--icon-link,
.trix-button-group--block-tools,
.trix-button-group--file-tools,
.trix-button-group--history-tools {
display: none;
}
Or, removing with Javascript.
// @ assets/javascripts/controllers/trix-controller.js
// inside the class
static UNUSED_TOOLBAR_CLASSES = [
".trix-button--icon-strike",
".trix-button--icon-link",
".trix-button-group--block-tools",
".trix-button-group--file-tools",
".trix-button-group--history-tools"
];
// inside the 'trix-initialize' event listener
TrixController.UNUSED_TOOLBAR_CLASSES.forEach((cls) => {
document.querySelector(cls).remove();
});
Your editor should look something like this now.
6. Add custom icons to the Toolbar
Use javascript to alter the button’s HTML in the toolbar.
// @ assets/javascripts/controllers/trix-controller.js
// add to class
static TOOLBAR_BUTTON_ICONS = [
{ identifier: "trix-button--icon-bold", icon: "<svg ....></svg>"},
{ identifier: "trix-button--icon-italic", icon: "<svg ....></svg>"},
{ identifier: "trix-button--icon-underline", icon: "<svg ....></svg>"},
]
// update toolbar icons inside 'trix-initialize' event listener
TrixController.TOOLBAR_BUTTON_ICONS.forEach((group) => {
document.querySelector(group.identifier).innerHTML = group.icon;
});
// @ assets/stylesheets/actiontext.scss
.trix-button {
background-image: none; // you may need an !important
}
Your editor should look something like this now.
7. Make it pretty
Now that everything is working, you can start adding more styles, changing buttons, and playing around with your Trix Editor.
Leave a comment if you have any issues or suggestions!
Happy coding!
Alternatives
Alternatives to Action Text
Rails stores rich text in a action_text_rich_texts table, in a text field named body and handles and stores files and images into active_storage_attachments and active_storage_blobs.
You can forgo installing Action Text and Active Storage and directly add a text field to your model and store your HTML as a string. However, you will have to handle image and file uploads on your own.
Alternatives to the Trix Editor
There are other Rich Text Editors that come with more aesthetic themes and give you more granular access to the editors content.
Check out some guides I wrote for QuillJS.