tag string, and can be discovered, updated, locked, or replaced from any surface that drives SuperDoc: the browser editor, the Node SDK, the CLI, an MCP tool, an AI agent.
In OOXML they are w:sdt elements (structured document tags). SuperDoc exposes the full surface under editor.doc.contentControls.* and editor.doc.create.contentControl.
Two patterns to start
Smart fields: one value, every occurrence
Wrap every occurrence of a template variable in an inline text content control sharing the sametag. Select by tag, then push the same value to each matching control.
examples/document-api/content-controls/tagged-inline-text.
Reusable sections: tagged blocks that know their version
Encode{ sectionId, version } in the tag of a block content control. The app reads the live version from contentControls.list and offers an in-place update when the document falls behind the section library.
contentControls.list for the sectionId instead of comparing versions, and lock each placed clause (contentLocked) so its prose is fixed. A clause can also carry nested smart fields - inline controls inside the block - that fill from one place.
The demos/contract-templates runtime composes the single-use approach: a clause library that inserts locked block clauses (some with nested fields), each filled by tag from a form.
Why tag, not nodeId
Two channels of identity exist on a content control:
Use
nodeId for in-session targeting. Use tag for durable identity that survives DOCX round-trips, including documents edited in Word and reopened. JSON-encode the tag when you need to carry structured metadata (kind, version, owner, group).
Cross-surface: same operations everywhere
Document API content controls are not editor-specific. The same operation IDs are available on every surface that drives SuperDoc.
A field updated by your backend job, a clause swapped by an agent, and a value typed by a user in the editor all hit the same engine.
When to use Template Builder vs Document API
Two valid paths. Both build on Word content controls.
The two paths are not mutually exclusive. A common pattern is Template Builder for authoring, Document API for runtime updates on the authored document.
Operation reference at a glance
Typed sub-APIs exist for
text.*, date.*, checkbox.*, choiceList.* (combo/dropdown), repeatingSection.*, and group.*. See the reference index for the full catalog.
Lock modes
SetlockMode when you create a control to govern which changes are allowed.
For controls your app drives freely with
text.setValue or replaceContent, use lockMode: 'unlocked'.
For a locked template - controls the user can’t touch, but your app still updates - keep them contentLocked and unlock around each write: setLockMode({ lockMode: 'unlocked' }), write, then setLockMode({ lockMode: 'contentLocked' }). Use try/finally so a failed write never leaves a control unlocked. setLockMode and patch are not blocked by contentLocked, so only the content write needs the unlock window. A smart field nested inside a locked block control needs the parent unlocked for the write too, since the parent’s content lock vetoes writes to anything inside it.
Data binding
Content controls can carry an OOXML<w:dataBinding> link to a custom XML data part. Read and write the binding metadata with contentControls.getBinding, setBinding, and clearBinding. The binding survives DOCX round-trips.
For runtime synchronization with backing data, drive the control directly with text.setValue or replaceContent.
Replacing content
contentControls.replaceContent accepts plain text. For richer fragments (paragraphs with formatting, tables, lists), use doc.insert to place the content, then create.contentControl({ at: range, ... }) to wrap the inserted range with a tag.
Next steps
Tagged inline text example
The smallest content-control workflow.
create.contentControl + selectByTag + text.setValue.Contract templates demo
Smart fields and versioned sections composed into one runtime app.
Template Builder
Ready-made React authoring component for content-control templates.
Reference: all operations
Every
contentControls.* operation with input, output, and failure codes.
