Skip to content
Strife Docs

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

TypeScript
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

OptionTypeRequiredDescription
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 with fields.image()'s mandatory width/height/format.
    • sizes: { label, width, height, default? }[] — selectable dimension presets. height: 0 keeps the source aspect ratio; mark one entry default: true to auto-apply it when an image is inserted.
    • styles: { label, group?, cssClass?, imgproxyParams? }[] — selectable visual-style presets. cssClass lands on the rendered <figure>; group buckets the picker dropdown; imgproxyParams are server-side imgproxy processing operations.
    • quality: { label, quality, imgproxyParams? }[] — selectable compression presets (quality is 1–100).
  • { type: 'callout', variants: { label, value }[] } — the callout block: a box around blocks, typed by a CSS class on its <div>. label is the picker label (compiles to wire name); value becomes the CSS class token on the rendered callout. A bare 'callout' node name isn't valid on its own — without variants it 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 classes callout-info, callout-tip, callout-warning and callout-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 .callout and each type's class on your site; Strife doesn't. See Styling callouts.
    • In the new interface, value must be a single class name that doesn't start with a digit: letters, digits, - and _. A variant with any other value, 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 variants when it has this entry; the entry itself doesn't restrict the menu. Once marks or nodes restrict the menu, the field offers callouts only when it has this entry.
    • In the new interface, a callout keeps its classes and its title, lang and dir attributes. Any other attribute on a stored callout, such as id, style or a data- 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="...">). Like callout, a bare 'customComponent' node name isn't valid — without components it would be a silent no-op. Each entry: tag is the custom-element tag name; label is the insert-menu label.
    • attributes: { name, label?, default? }[] — what an author may fill in on each inserted instance. name is the HTML attribute written to the markup, label names the field in the editor (defaults to name), and default pre-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 own form-id — and an author fills in a value, never attribute syntax.
    • Declare an attribute with no default to get an empty field. Leaving a field empty writes no attribute at all, rather than name="".
    • 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 use attributes.
Warning:

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.

Note:

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.

Warning:

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:

CSS
/* 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.