Engineering

Forays in Fancy Formatting

At incident.io, our raison d’etre is making it as easy as possible to handle incidents. So we want to make it as easy as possible to communicate in a rich way in incident summaries and updates. If you can emphasise certain things, or create a list, or @mention people, it’ll be easier for people to take in important information and easier to get that information to the people who need to see it.

We’ve long supported markdown in incident summaries and updates, but this isn’t necessarily intuitive for users to write. Recently Slack shipped a new rich text input element that allows us to accept rich text input in our Slack UI, and we jumped at the opportunity to adopt it.

Rich text is simple, right?

Yes! No - rich text is deceptively complex, especially when you have to interact with several different systems, all of which have different levels of support for rich text. As our product is accessible through both Slack and our web dashboard, we need to support at least two formats - Slack’s rich text and ProseMirror, which is a component we use for rich text in the incident.io dashboard. Even between these two systems we have differences. As an example, ProseMirror supports nested lists, whereas Slack only supports lists that are one level deep.

In this situation, we had a couple of options. We could allow you to write nested lists in the dashboard and then flatten them when we display them in Slack, or restrict lists in the dashboard to be only one level deep. We decided to restrict lists in the dashboard so that we have a consistent experience across Slack and the dashboard as they are the primary places summaries/updates are written and read.

Beyond Slack and the dashboard

Outside of Slack and our dashboard there are even more places where we send rich text to other systems:

  • Syncing incidents to Jira
  • Exporting debrief documents to Confluence, Notion, or Google Docs
  • Sending incident updates via email

Each of these systems has their own rules around rich text, and to get the best experience in each place we had to come up with a way to transform the text we had in to a compatible format. Our job here was made easier by only needing to support these systems one-way - we needed to export to them but didn’t need to import from them.

Debrief document templates

I’m going to focus on debrief templates for a bit as they were quite tricky to update to work with rich text summaries and updates.

Our debrief templates allow a lot of flexibility. Want to put your incident summary in a heading or in a table? Go ahead! Want to put it as an item in a list? Feel free!

So much regret

The difficulty here comes from embedding one piece of rich text in another. It’s valid to have a heading in a template, and it’s valid to have a list in an incident summary, but what happens when you put the incident summary in to a heading in the template? Is it ok to have a list inside a heading? The answer to this depends on the destination system and what rich text it supports.

So what did we do?

Our approach to solving this was to “downgrade” the formatting of text when a particular combination wasn’t supported. For example:

  • If lists aren’t supported inside tables, we can fake them by using the character
  • If headings aren’t supported inside a list, we can fake them by making the text bold
  • If code blocks aren’t supported inside quote blocks, we can use inline code instead

By taking the time to understand each destination’s rich text rules, we were able to come up with transformations that maintained as much fidelity from the original rich text as possible.

Was the complexity worth it?

It can sometimes be difficult to understand if a complex change such as this was worth it, especially when the functional change can feel small. But this change was definitely worth the effort. We’re seeing good adoption from users, and anecdotally from using it ourselves it’s making summaries and updates easier to read and to write.

Picture of Pip Taylor
Pip Taylor
Product Engineer

Operational excellence starts here