---
title: "Redacted content"
description: "Customize hidden-content placeholders and their clipboard and export behavior."
canonical_url: "https://tiptap.dev/docs/composable-docs/content-protection/api-reference/rendering"
---

# Redacted content

Customize hidden-content placeholders and their clipboard and export behavior.

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](https://tiptap.dev/docs/composable-docs/content-protection/api-reference/policy.md#read-restrictions).

```ts
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`](https://tiptap.dev/docs/composable-docs/content-protection/api-reference/commands.md#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`](https://tiptap.dev/docs/composable-docs/content-protection/api-reference/utilities.md#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.
