Skip to content

RichText

RichText is formatted text, such as the content of a Note or a user’s Profile bio. It is a string of HTML, using the elements and attributes listed on this page and no others.

Fields that hold short labels, such as a User’s display_name, are plain strings instead.

{
    "content": "<p>Hello, <a href=\"https://b.example/@joe\" data-mention=\"b.example:034de9r4fr006\">@joe</a>! The notes from Tuesday:</p><ul><li>Ship the <code>0.7</code> release</li><li>Write the changelog</li></ul>"
}

Definition

A RichText value is an HTML fragment, parsed as the HTML standard parses a fragment in the context of a body element. Senders MUST only use the elements and attributes on this page, plus the extension attributes of extensions they implement. Senders SHOULD send well-formed HTML, with every element closed. Short values, such as the keys of a Profile’s fields or a poll option, can be text with no elements at all.

Mentions and custom emojis are written in the text as described below. Neither needs markup of its own for a receiver to find it.

Elements

Receivers that display RichText MUST show the content of every element below. They SHOULD render each element as the HTML standard defines it. When a receiver cannot, it MAY use the fallback listed, which keeps the element’s meaning.

Blocks

ElementFallback
p, div
h1, h2, h3, h4, h5, h6A paragraph in bold.
blockquote
pre
hrA blank line.
ul, ol, li
dl, dt, ddEach dt in bold, on its own line, followed by its dd elements.
table, caption, thead, tbody, tfoot, tr, th, tdEach row on its own line, with its cells separated by tabs.
details, summaryShown open.
figure, figcaption

Text

ElementFallback
a
br
span
strong, em, b, i, u, s, del, ins, mark, small
code, kbd, samp, var
sub, sup
abbr, cite, dfn, q, time
ruby, rt, rpThe base text, followed by its rt text in parentheses.
bdi, bdo, wbr

Media

img, video and audio place an entity’s attachments inside its text, such as the images of a blog post. They are only allowed in fields whose definition allows them, such as a Note’s content, and their src MUST be the url of one of that entity’s attachments. Their description, size and dimensions come from that attachment, so these elements carry no other attributes. A receiver MAY show them as the attachments they point to.

Attributes

Any element in the list can have lang, dir and title. Besides those, these attributes are allowed:

ElementAttributes
ahref, data-mention
olstart, reversed, type
livalue
thcolspan, rowspan, scope
tdcolspan, rowspan
timedatetime
del, insdatetime, cite
blockquote, qcite
detailsopen
code, preclass, only with values that start with language-, such as language-rust
img, video, audiosrc
span, divExtension attributes

A receiver that renders ol MUST honor its start, reversed and type, and the value of its li elements, so that numbers referred to in the text stay correct.

A link’s href MUST be an absolute URL with one of these schemes: http, https, mailto, web+versia, dat, dweb, ipfs, ipns, ssb, gopher, xmpp, magnet or gemini. A web+versia link is a Versia Link.

Mentions

A mention of a User is a link with a data-mention attribute, which holds the user’s Reference. Its href SHOULD be the user’s url, or another address of their profile on their instance, and its text is up to the sender, usually the user address.

<a href="https://b.example/@joe" data-mention="b.example:034de9r4fr006">@joe@b.example</a>

A mention in RichText does not notify anyone. An entity that notifies the users it mentions lists them in a field of its own, as a Note does in mentions. A receiver MAY point the link at its own copy of the user instead of the href.

Extension Attributes

Extensions can add effects to text, such as animation or color, with attributes on span and div. Each attribute is named data- followed by a short prefix that the extension states on its page, a hyphen and a name, such as data-mfm-fn. The prefix mention is reserved.

<span data-mfm-fn="tada">hello</span>

An extension attribute MUST NOT change what text a receiver that does not implement the extension shows: without the attribute, the element and its content still read correctly. Receivers ignore the attributes of extensions they do not implement.

An extension that defines attributes MUST state on its page how a receiver renders them safely. For example, an extension that animates text has to honor a reader’s reduced-motion setting.

Other Elements and Attributes

A receiver SHOULD sanitize RichText before rendering it. When it does:

  • script, style, template, iframe, object, embed, svg and math are removed, with their content.
  • Any other element not listed on this page is removed, and its content is kept in its place.
  • Attributes not listed on this page are removed, as are extension attributes of extensions the receiver does not implement.
  • A link whose href is not allowed is removed, and its text is kept.
  • img, video and audio whose src does not match an attachment are removed.

Plain Text

Some places can only show plain text, such as notifications and link previews. To turn RichText into plain text, receivers SHOULD:

  • End each block element, br and li with a line break, and separate paragraphs with a blank line.
  • Start each li of a ul with - , and each li of an ol with its number and . .
  • Separate table cells with a tab, and put each row on its own line.
  • Replace each link with its text.
  • Leave out rt, rp, img, video and audio.
  • Collapse whitespace as HTML rendering does, except inside pre.

Nothing in federation depends on the result.