Reference Field Reference
fields.html()
Rich-text (HTML) editor with configurable formatting/content availability, plus selectable image, callout, and custom-component presets.
Rich-text input. Maps to editor { name: 'str-textarea', type: 'html' }. Output is HTML-as-string — markup is stored verbatim; sanitization happens at render time (server-side renderers / SDKs), not at write time.
Example
fields.html({
label: 'Body',
localizable: true,
marks: ['bold', 'italic', 'link'],
nodes: [
'heading2',
'bulletList',
{
type: 'image',
sizes: [
{ label: 'Wide', width: 1200, height: 630, default: true },
{ label: 'Square', width: 800, height: 800 },
],
styles: [
{ label: 'Drop shadow', group: 'Effects', cssClass: 'shadow', imgproxyParams: ['sh:0.5'] },
],
quality: [{ label: 'High', quality: 90 }],
},
{
type: 'callout',
variants: [{ label: 'Highlighted', value: 'highlighted' }],
},
],
})Options
| Option | Type | Required | Description |
|---|---|---|---|
label | string | Yes | Label shown to editors in Strife Studio. |
description | string | No | Not shown in Studio's editor panel. |
localizable | boolean | No | When true, output is Record<string, string> instead of string. |
searchable | boolean | No | Stored on the template; nothing uses it today. |
filterable | boolean | No | Stored on the template; nothing uses it today. |
protected | boolean | No | Stops the field from being edited or removed in Studio's template designer. No effect in the editor panel. |
propertyName | string | No | Override the stored property name. |
placeholder | string | null | No | Hint text shown when the editor is empty. |
marks | HtmlMark[] | No | Inline-formatting tools the editor offers. |
nodes | HtmlNode[] | No | Block-level content the editor offers. image, callout, and customComponent entries can carry their own configuration — see below. |
documentSchema | { content?: string; placeholders?: Record<string, string> } | No | Forces a Tiptap content structure (e.g. 'heading paragraph+') and per-node-type placeholder text. |
HtmlMark is one of: bold, italic, underline, strike, link.
HtmlNode is either a bare HtmlNodeName — one of paragraph, heading1, heading2, heading3, blockquote, bulletList, orderedList, checkList, codeBlock, image, video, table, details — or a configured image/callout/customComponent object:
{ type: 'image', sizes?, styles?, quality? }— presets offered in the image toolbar once an image is inserted. These are selectable options, not enforced constraints — contrast withfields.image()'s mandatorywidth/height/format.sizes: { label, width, height, default? }[]— selectable dimension presets.height: 0keeps the source aspect ratio; mark one entrydefault: trueto auto-apply it when an image is inserted.styles: { label, group?, cssClass?, imgproxyParams? }[]— selectable visual-style presets.cssClasslands on the rendered<figure>;groupbuckets the picker dropdown;imgproxyParamsare server-side imgproxy processing operations.quality: { label, quality, imgproxyParams? }[]— selectable compression presets (qualityis 1–100).
{ type: 'callout', variants: { label, value }[] }— the callout block: a box around blocks, typed by a CSS class on its<div>.labelis the picker label (compiles to wirename);valuebecomes the CSS class token on the rendered callout. A bare'callout'node name isn't valid on its own — withoutvariantsit would be a silent no-op, so it must always be given in this configured form.- In Strife Studio today, an author can combine several variants on one callout. In the new interface a callout has one type. A stored callout with several classes keeps them until an author picks a type for it; the picked type then replaces every class that names a type, and other classes stay.
- The new interface also offers four built-in types, listed before your
variants: Info, Tip, Warning and Important, with the classescallout-info,callout-tip,callout-warningandcallout-important. Studio colours them while editing, but the published HTML carries no colour, only the class:<div data-callout-classes="callout-warning" data-callout="" class="callout callout-warning">. Style.calloutand each type's class on your site; Strife doesn't. See Styling callouts. - In the new interface,
valuemust be a single class name that doesn't start with a digit: letters, digits,-and_. A variant with any othervalue, such as'note wide', isn't offered there. - In the new interface, a field whose menu isn't restricted offers callouts with the built-in types, plus your
variantswhen it has this entry; the entry itself doesn't restrict the menu. Oncemarksornodesrestrict the menu, the field offers callouts only when it has this entry. - In the new interface, a callout keeps its classes and its
title,langanddirattributes. Any other attribute on a stored callout, such asid,styleor adata-attribute of your own, is dropped once the field is edited and saved there.
{ type: 'customComponent', components: { tag, label, attributes? }[] }— customer web components the editor may insert (e.g. a form embed distributed as a custom element,<lime-form form-id="...">). Likecallout, a bare'customComponent'node name isn't valid — withoutcomponentsit would be a silent no-op. Each entry:tagis the custom-element tag name;labelis the insert-menu label.attributes: { name, label?, default? }[]— what an author may fill in on each inserted instance.nameis the HTML attribute written to the markup,labelnames the field in the editor (defaults toname), anddefaultpre-fills it on insert. The placeholder renders one field per declared attribute, so a page with several of the same component gives each one its ownform-id— and an author fills in a value, never attribute syntax.- Declare an attribute with no
defaultto get an empty field. Leaving a field empty writes no attribute at all, rather thanname="". - The set is schema-owned: attributes you don't declare can't be added from the editor, and a component that declares none gets no editing affordance. Attributes already present on stored markup are preserved untouched whether or not the schema declares them.
defaultAttrs: Record<string, string>is the deprecated 0.11.0 spelling —{ 'form-id': 'x' }means the same as[{ name: 'form-id', default: 'x' }], minus the field label. Existing schemas keep working; new ones should useattributes.
Pilot-scoped today. tag must be one of a small set of element names the editor's parse-time allowlist already recognizes (currently Kalmar Energi's Lime forms, lime-form/simpli-form) — any other tag is dropped like any other unmodeled markup, same as an unrecognized HTML element pasted into the editor. Recognized elements always render as a static placeholder in Strife Studio — the editor never mounts or hydrates the real element, and never loads the customer's script — the real component only renders where the published HTML is actually rendered, on the customer's own site (which must already have its loader script installed there). There is no Strife Studio UI for customComponent yet — nodes (or hand-edited template JSON) is currently the only way to set it, same as quality under image above.
Not every nodes entry produces a visible toolbar button today — paragraph and table have no corresponding control yet (they're accepted for forward-compatibility). Every HtmlMark value and every other HtmlNodeName value does show one.
No Strife Studio UI for quality presets. sizes and styles can also be authored by hand in Strife Studio's field settings (as "Image Presets" / "Style Presets" tables), but quality has no equivalent point-and-click control — fields.html()'s nodes (or hand-edited template JSON) is currently the only way to set it.
Alignment, alt text, and crop/zoom/pan on an inserted image are purely interactive per-image state set by the editor in Strife Studio — there's no schema-level way to default or constrain those.
Styling callouts
Strife never styles a published callout; your site does. Give .callout a base rule that every callout gets, including your own variants and callouts without a type, and add a rule per type on top:
/* Every callout: your own variants and callouts without a type */
.callout {
padding: 1rem 1.25rem;
border-inline-start: 4px solid #94a3b8;
background: #f8fafc;
}
/* The built-in types of the new interface */
.callout.callout-info { border-color: #3b82f6; background: #eff6ff; }
.callout.callout-tip { border-color: #22c55e; background: #f0fdf4; }
.callout.callout-warning { border-color: #eab308; background: #fefce8; }
.callout.callout-important { border-color: #ef4444; background: #fef2f2; }
/* Your own variants, e.g. value: 'highlighted' */
.callout.highlighted { border-color: #a855f7; background: #faf5ff; }Keep the base rule. A site that styles only its own variants, such as .highlighted, shows a built-in type as plain text with no box. Studio's colours are for editing only, so choose your own.
Output type
string (HTML), or Record<string, string> when localizable: true.
See also
- Rich Content — the same editor, documented from the Strife Studio UI side.
fields.paragraph()— same underlying textarea component, but stores plain text instead of HTML.