Extension
ContentProtection
Checks document edits against a policy and replaces redacted content with placeholders. The extension adds no Nodes, Marks or attributes to the schema.
import { ContentProtection } from '@tiptap-pro/extension-content-protection'
ContentProtection.configure({ policy })Options (ContentProtectionOptions)
policy(ContentProtectionPolicy): The active policy. Default:{ version: 1, rules: [] }, allowing all reads and edits.redactionText(string): Default placeholder text, accessible name and clipboard text. Default:'[Hidden content]'. Must be nonempty.renderRedaction(RedactionRenderer | null): Creates the UI that replaces content hidden by aread: falsepolicy. Receives safe placeholder props, including the text and accessible label fromredactionText, and returns a DOM element with optional lifecycle callbacks. Use it for custom labels or host-owned controls such as a request-access button; it receives no hidden content and cannot grant access. Default:null, using the built-in placeholder. See Redacted content.onRejected((event: ContentProtectionRejectedEvent) => void): Called after a policy refuses a document edit. The edit is not applied; useevent.violationsto show the user why, for example in a notification. This is the option form of thecontentProtectionRejectedevent, not a callback that decides whether to allow the edit. Default: no-op, so refused edits show no application notification.onPolicyUpdate((event: ContentProtectionPolicyUpdateEvent) => void): Listener forcontentProtectionPolicyUpdate. Default: no-op.onPolicyError((event: ContentProtectionPolicyErrorEvent) => void): Listener forcontentProtectionPolicyError. Default: no-op.
Invalid initial options throw ProtectionConfigurationError.
Storage (ContentProtectionStorage)
Available at editor.storage.contentProtection.
policy(ContentProtectionPolicy, readonly): The active policy.policyRevision(number, readonly): Starts at0; increments when the policy changes.documentRevision(number, readonly): Starts at0; increments for each applied content-changing transaction.
storage.checkTransaction
Checks a proposed transaction without applying it. Equivalent to checkProtectedTransaction.
Parameters
transaction(Transaction): A transaction created from the editor's current state, passed as{ transaction }.
Returns (ProtectionCheck)
The permission result, violations and current revisions. Throws ProtectionInputError if the transaction's starting document does not match.
storage.isReadable
Checks whether the entire range is readable under the active policy.
Accepts one options object: { document, range }.
Parameters
document(Node): The document to inspect.range({ from: number; to: number }): The document range to check.
Returns (boolean)
true if the whole range is readable; otherwise false.
Editor events
Register with editor.on(name, listener) and remove with editor.off(name, listener). Option callbacks receive the same payloads.
| Event | Payload | Emitted when |
|---|---|---|
contentProtectionRejected | ContentProtectionRejectedEvent | A transaction is refused. |
contentProtectionPolicyUpdate | ContentProtectionPolicyUpdateEvent | A different valid policy is installed. |
contentProtectionPolicyError | ContentProtectionPolicyErrorEvent | A policy replacement is invalid. |
See event payloads. Dry-run checks emit no events; renderRedaction is a factory, not an event listener.