Redacted content

Redacted content (content with reading disallowed by the policy) is replaced with a placeholder. Use renderRedaction to control its appearance and interactions.

Redacted Nodes are non-editable, including their type, attributes and content. This is enforced on transactions, not just through contenteditable="false". See read restrictions.

ContentProtection.configure({
  policy,
  renderRedaction: ({ inline, label }) => {
    const dom = document.createElement(inline ? 'span' : 'div')
    dom.className = 'restricted-content'
    dom.textContent = `🔒 ${label}`
    return { dom }
  },
})

Options

  • renderRedaction (RedactionRenderer | null): Placeholder factory. Default: null, using the built-in view.
  • redactionText (string): Default visible text, accessible name and neutral clipboard output. Default: '[Hidden content]'; must be nonempty.

RedactionRenderer

Synchronous factory with type (props: RedactionViewProps) => RedactionView.

Parameters (RedactionViewProps)

  • key (string): Opaque identity for the mounted region. Not a document ID, position or content lookup key.
  • inline (boolean): true when the view must fit inside a text line.
  • text (string): Configured redactionText.
  • label (string): Default accessible name; the same value as redactionText.

Props contain no original content, Nodes, positions, lengths, rule IDs or Editor instance.

Returns (RedactionView)

  • dom (HTMLElement): A fresh, detached root. Inline views must contain inline-compatible elements.
  • update? ((props: RedactionViewProps) => boolean): Updates an existing view. Return true to reuse it; false to recreate it. Without this method, updates recreate the view.
  • destroy? (() => void): Cleans up listeners, framework roots and portals when the view is removed, replaced or the editor is destroyed.

Rendering behavior

  • The extension attaches the root and sets contenteditable="false" and data-content-protection="redacted".
  • Set aria-label or aria-labelledby on a custom root to supply an accessible name. Otherwise the extension uses redactionText.
  • The root may contain buttons and other interactive controls. It must not provide editable document content or contentDOM.
  • Hidden Nodes do not mount their original NodeViews. Concealing a visible Node destroys its original view.
  • An inline/block context change recreates the placeholder.
  • Invalid views or renderer failures fall back to the default placeholder, never the original content.
  • Framework renderers use their normal mount/update/unmount APIs. Clean up in destroy; this is not a ReactNodeViewRenderer.
  • Access-request controls belong to the application. Change access with setContentProtectionPolicy.

Clipboard and export

  • Copy uses redactionText and neutral HTML, not the custom view's DOM, labels or controls.
  • Cut is refused if any selected content cannot be deleted; the clipboard is left unchanged.
  • Dragging checks source and destination permissions and uses readable clipboard output.
  • getReadableContent returns a presentation tree and text. It does not call renderRedaction; pass custom redactionText explicitly.
  • Partially hidden Slots omit their configuration from clipboard output.
  • editor.getJSON() and editor.getHTML() still include the complete document. Use the readable projection for outputs that must omit hidden content.

Custom rendering changes the view only. The complete source document remains in client memory; application sidebars and exports must apply the same read permissions.