Renders Tiptap/ProseMirror JSON documents to safe HTML on the server.
{:safe, _} = Tiptapex.Renderer.to_html(article.body)In HEEx just interpolate it — no raw/1 needed, and none should ever be
used with client-provided HTML:
<div class="ttx-prose">{Tiptapex.Renderer.to_html(@article.body)}</div>All text is escaped, attributes go through an allow-list per node, URLs
must be http(s)/mailto/relative, iframes are restricted to rebuilt
YouTube embed URLs, and inline CSS values must match a strict grammar
(see Tiptapex.Renderer.URL). Unknown node/mark types are dropped by
default.
Options
:nodes— map of"type" => renderermerged over the built-ins, where renderer is a(node, children_iodata, opts) -> iodatafun or a module implementingTiptapex.Renderer.Node.:marks— same for marks:(mark, children_iodata, opts) -> iodata.:on_unknown— what to do with unknown node/mark types::drop(default),:keep_children, or:raise.:ids— whether to emit headingidattributes (defaulttrue). Passfalsewhenever the rendered HTML appears on the same page as a live editor showing the same document (e.g. a preview panel): the editor's DOM carries the same ids, and LiveView's DOM patcher matches elements by id globally — it will steal nodes out of the editor (even insidephx-update="ignore"), deleting them from the document.
Custom nodes
defmodule MyApp.CalloutNode do
@behaviour Tiptapex.Renderer.Node
alias Tiptapex.Renderer.HTML
@impl true
def render(_node, children, _opts) do
HTML.tag("aside", [{"class", "callout"}], children)
end
end
Tiptapex.Renderer.to_html(doc, nodes: %{"callout" => MyApp.CalloutNode})
Summary
Functions
Lists the document's headings as %{level: 1..6, id: binary | nil, text: binary} — ready to build a table of contents. Ids come from the
UniqueID extension when present.
Converts a Tiptap JSON document (map, string or atom keys) to
{:safe, iodata}.
Extracts the document's plain text — for excerpts, search indexing, or emptiness checks. Blocks are separated by newlines; media nodes are skipped.
Functions
Lists the document's headings as %{level: 1..6, id: binary | nil, text: binary} — ready to build a table of contents. Ids come from the
UniqueID extension when present.
@spec to_html( map() | nil, keyword() ) :: Phoenix.HTML.safe()
Converts a Tiptap JSON document (map, string or atom keys) to
{:safe, iodata}.
Extracts the document's plain text — for excerpts, search indexing, or emptiness checks. Blocks are separated by newlines; media nodes are skipped.