EmbedPDF

Redaction Plugin

The Redaction Plugin provides the tools to permanently remove sensitive content from a PDF document. Unlike annotations which are simply layered on top, redaction is a destructive process that alters the underlying PDF content, making it unrecoverable.

The process involves two main stages:

  1. Marking: Users mark content for redaction by selecting text or drawing a rectangle over an area. These marks are called “pending redactions.”
  2. Committing: Users apply the pending redactions, which permanently removes the marked content from the document in the viewer’s memory and, optionally, draws black boxes in its place.
⚠️

Redaction is an irreversible process. Once committed, the original content is removed and cannot be restored from the document.

Operating Modes

The Redaction Plugin supports two operating modes:

ModeDescription
Legacy ModePending redactions are stored in internal state. Simple setup, suitable for single-session workflows where one user marks and applies redactions immediately.
Annotation ModePending redactions are stored as PDF REDACT annotations. Enables collaborative workflows, customizable colors, and undo/redo support.

Choose the mode that best fits your use case before implementing.

Installation

The plugin has optional but highly recommended dependencies on the Selection and Interaction Manager plugins, which are required for marking text and areas, respectively.

npm install @embedpdf/plugin-redaction @embedpdf/plugin-selection @embedpdf/plugin-interaction-manager

Registration

Import RedactionPluginPackage and its dependencies, then add them to the plugins array. The dependencies should be registered first.

import { createPluginRegistration } from '@embedpdf/core' import { EmbedPDF } from '@embedpdf/core/react' // ... other imports import { InteractionManagerPluginPackage } from '@embedpdf/plugin-interaction-manager/react' import { SelectionPluginPackage } from '@embedpdf/plugin-selection/react' import { RedactionPluginPackage } from '@embedpdf/plugin-redaction/react' const plugins = [ // ... other essential plugins createPluginRegistration(DocumentManagerPluginPackage, { /* ... */ }), createPluginRegistration(RenderPluginPackage), // Register dependencies first createPluginRegistration(InteractionManagerPluginPackage), createPluginRegistration(SelectionPluginPackage), // Register and configure the redaction plugin createPluginRegistration(RedactionPluginPackage, { drawBlackBoxes: true, // Draw black boxes over redacted content }), ]

Usage

The plugin’s functionality is primarily managed through the <RedactionLayer /> component and the useRedaction hook.

1. Add the <RedactionLayer />

This component is responsible for rendering all redaction-related UI, including the text selection highlights, area selection marquee, and all pending redaction marks. It must be placed inside your Scroller’s renderPage prop and be a child of the <PagePointerProvider>.

import { PagePointerProvider } from '@embedpdf/plugin-interaction-manager/react'; import { RedactionLayer } from '@embedpdf/plugin-redaction/react'; // ... <Scroller documentId={activeDocumentId} renderPage={({ pageIndex }) => ( <PagePointerProvider documentId={activeDocumentId} pageIndex={pageIndex}> <RenderLayer documentId={activeDocumentId} pageIndex={pageIndex} /> <SelectionLayer documentId={activeDocumentId} pageIndex={pageIndex} /> <RedactionLayer documentId={activeDocumentId} pageIndex={pageIndex} /> </PagePointerProvider> )} />

2. Build a Redaction Toolbar

The useRedaction hook provides the state of the redaction process (e.g., how many marks are pending) and a provides object with methods to control it for a specific document. You can build a toolbar to allow users to switch between redaction modes and apply their changes.

import { useRedaction, RedactionMode } from '@embedpdf/plugin-redaction/react'; const RedactionToolbar = ({ documentId }) => { const { state, provides } = useRedaction(documentId); return ( <div> <button onClick={() => provides?.toggleRedactSelection()}>Mark Text</button> <button onClick={() => provides?.toggleMarqueeRedact()}>Mark Area</button> <span>{state.pendingCount} pending marks</span> <button onClick={() => provides?.commitAllPending()} disabled={state.pendingCount === 0} > Apply All Redactions </button> </div> ); };

3. Create a Menu for Pending Marks

You can provide a selectionMenu render prop to the <RedactionLayer /> to display a custom UI when a user clicks on a pending redaction mark. This is useful for allowing users to apply or remove individual marks.

import { RedactionSelectionMenuProps, useRedaction } from '@embedpdf/plugin-redaction/react'; // A custom menu component const RedactionMenu = ({ documentId, // Pass documentId to use the hook context, selected, menuWrapperProps, rect }: RedactionSelectionMenuProps & { documentId: string }) => { const { provides } = useRedaction(documentId); if (!selected) return null; return ( <div {...menuWrapperProps}> <div style={{ position: 'absolute', top: rect.size.height + 10, left: 0, pointerEvents: 'auto' }} > <button onClick={() => provides?.removePending(context.item.page, context.item.id)}>Remove</button> </div> </div> ); }; // Pass it to the layer <RedactionLayer documentId={activeDocumentId} pageIndex={pageIndex} selectionMenu={(props) => ( <RedactionMenu documentId={activeDocumentId} {...props} /> )} />

Live Example

This example demonstrates the full redaction workflow in legacy mode. Use the “Mark Text” and “Mark Area” buttons to queue redactions. Click a pending mark to see the option to remove it. Finally, click “Apply All” to permanently redact the content.

Loading PDF Engine...

Annotation Mode

The Redaction Plugin supports an alternative annotation mode where pending redactions are stored as PDF REDACT annotations instead of internal state. This integrates with the Annotation Plugin and provides:

  • Customizable colors: Change the mark and overlay colors for each redaction
  • Collaborative workflows: One user can prepare redactions, save the PDF, and send it to another user for review. The reviewer can inspect, modify, or apply the redactions
  • Undo/redo support: Integrates with the History Plugin for full undo/redo functionality
  • Persistent state: Redaction marks are saved as part of the PDF and persist across sessions
ℹ️

Use annotation mode when you need collaborative review workflows, customizable colors, or want redaction marks to be saved into the PDF for later review.

Enabling Annotation Mode

To enable annotation mode, register AnnotationPluginPackage and set useAnnotationMode: true:

import { createPluginRegistration } from '@embedpdf/core' import { InteractionManagerPluginPackage } from '@embedpdf/plugin-interaction-manager/react' import { SelectionPluginPackage } from '@embedpdf/plugin-selection/react' import { AnnotationPluginPackage } from '@embedpdf/plugin-annotation/react' import { RedactionPluginPackage } from '@embedpdf/plugin-redaction/react' import { HistoryPluginPackage } from '@embedpdf/plugin-history/react' const plugins = [ // ... other essential plugins createPluginRegistration(DocumentManagerPluginPackage, { /* ... */ }), createPluginRegistration(RenderPluginPackage), createPluginRegistration(InteractionManagerPluginPackage), createPluginRegistration(SelectionPluginPackage), createPluginRegistration(HistoryPluginPackage), createPluginRegistration(AnnotationPluginPackage), createPluginRegistration(RedactionPluginPackage, { useAnnotationMode: true, }), ]

Required Layers

In annotation mode, you need both the AnnotationLayer and RedactionLayer:

  • AnnotationLayer: Renders the REDACT annotations (pending redactions)
  • RedactionLayer: Renders the marquee drawing UI and text selection highlights during marking
import { AnnotationLayer } from '@embedpdf/plugin-annotation/react'; import { RedactionLayer } from '@embedpdf/plugin-redaction/react'; <Scroller documentId={activeDocumentId} renderPage={({ pageIndex }) => ( <PagePointerProvider documentId={activeDocumentId} pageIndex={pageIndex}> <RenderLayer documentId={activeDocumentId} pageIndex={pageIndex} /> <SelectionLayer documentId={activeDocumentId} pageIndex={pageIndex} /> {/* AnnotationLayer renders REDACT annotations */} <AnnotationLayer documentId={activeDocumentId} pageIndex={pageIndex} /> {/* RedactionLayer renders marquee/selection UI during marking */} <RedactionLayer documentId={activeDocumentId} pageIndex={pageIndex} /> </PagePointerProvider> )} />

Unified Redact Mode

Use toggleRedact() for a unified mode that supports both text selection and area marquee in a single mode:

const { state, provides } = useRedaction(documentId); // Toggle unified redact mode (supports both text and area) provides?.toggleRedact(); // Check if redact mode is active const isActive = state.activeType === RedactionMode.Redact;

This unified mode works in both legacy and annotation modes.

Customizing Colors

In annotation mode, redaction colors can be customized. Use the useAnnotation hook to access the annotation state and update colors on selected annotations:

import { useAnnotation } from '@embedpdf/plugin-annotation/react'; import { PdfAnnotationSubtype, PdfRedactAnnoObject } from '@embedpdf/models'; const { state: annotationState, provides: annotationApi } = useAnnotation(documentId); // Get the selected REDACT annotation const selectedRedact = (() => { if (!annotationState.selectedUid) return null; const tracked = annotationState.byUid[annotationState.selectedUid]; if (!tracked || tracked.object.type !== PdfAnnotationSubtype.REDACT) return null; return tracked.object as PdfRedactAnnoObject; })(); // Update colors on the selected annotation if (selectedRedact && annotationApi) { annotationApi.updateAnnotation(selectedRedact.pageIndex, selectedRedact.id, { strokeColor: '#2563EB', // Blue mark border color: '#2563EB', // Blue overlay when applied }); }

Annotation Mode Live Example

This example demonstrates annotation mode with a color picker. Click the “Redact” button to enable marking mode, then select text or draw rectangles. Click on a pending redaction to select it, then use the color swatches to change its color.

Loading PDF Engine...

API Reference

Configuration (RedactionPluginConfig)

OptionTypeDefaultDescription
drawBlackBoxesbooleantrueIf true, a black rectangle is drawn over the redacted content after committing. Only applies in legacy mode. In annotation mode, the overlay color is controlled by the annotation’s color property.
useAnnotationModebooleanfalseWhen true, pending redactions are stored as PDF REDACT annotations (requires AnnotationPluginPackage). When false, uses internal pending state (legacy mode).

Component: <RedactionLayer />

Renders all UI related to marking and managing redactions.

PropTypeDescription
documentIdstring(Required) The ID of the document.
pageIndexnumber(Required) The page index this layer corresponds to.
selectionMenu(props: RedactionSelectionMenuProps) => JSX.ElementA render prop for a custom menu that appears when a pending redaction is selected.

Hook: useRedaction(documentId)

Connects your components to the redaction plugin’s state and methods for a specific document.

Returns

PropertyTypeDescription
stateRedactionStateAn object containing the current state of the redaction process.
providesRedactionScope | nullAn object with methods to control the plugin, or null if not ready.

RedactionState Properties

PropertyTypeDescription
isRedactingbooleantrue when any redaction mode is active.
activeTypeRedactionMode | nullThe currently active mode: 'redact' (unified), 'redactSelection' (text only), or 'marqueeRedact' (area only).
pendingobjectA map of pending redactions, keyed by page number.
pendingCountnumberThe total number of pending redactions across all pages.
selectedobject | nullThe currently selected pending redaction, if any.

RedactionScope Methods

A selection of key methods available on the provides object:

MethodDescription
toggleRedact()Toggles the unified redact mode (supports both text selection and area marquee).
enableRedact()Enables the unified redact mode.
isRedactActive()Returns true if the unified redact mode is active.
toggleRedactSelection()Toggles the text-only redaction mode.
toggleMarqueeRedact()Toggles the area-only redaction mode.
addPending(items)Programmatically adds new RedactionItems to the pending queue.
removePending(page, id)Removes a specific pending redaction mark.
clearPending()Removes all pending redaction marks.
commitAllPending()(Destructive) Applies all pending redactions to the document. Returns a Task.
commitPending(page, id)(Destructive) Applies a single pending redaction. Returns a Task.
onStateChange(cb)Subscribes to any change in the RedactionState.
onRedactionEvent(cb)Subscribes to events like adding, removing, or committing redactions.
Last updated on February 3, 2026

Need Help?

Join our community for support, discussions, and to contribute to EmbedPDF's development.