How can I help you?
How to search text and redact in React PDF Viewer
4 Mar 202611 minutes to read
Overview
This guide shows how to search for text inside a loaded PDF and add redaction annotations programmatically for every match. You will add two buttons: one to locate and mark matches with redaction annotations, and another to apply redactions (permanently remove the marked content).
Outcome: After following the steps you will have a working React sample where clicking “Search & Mark for Redaction” marks found text with redaction annotations and clicking “Apply Redaction” permanently removes the marked content.
Prerequisites
- EJ2 React PDF Viewer added to your project. See getting started guide.
- The viewer’s redaction feature enabled in your product version.
Steps
- Create a React component that includes the
PdfViewerComponentand Inject required services. - Add two buttons: one to perform the text search and add redaction annotations, and one to apply redactions.
- Use the viewer’s
findTextAsync()to get match bounds (returned in points), convert those bounds to pixels, and add aRedactionannotation for each bound usingaddAnnotation('Redaction', ...). - Call
redact()to apply redactions permanently when the user confirms.
Complete runnable example
import * as React from 'react';
import './index.css';
import {
PdfViewerComponent, Toolbar, Magnification, Navigation, LinkAnnotation, BookmarkView, ThumbnailView, Print, TextSelection, Annotation, TextSearch, FormFields, FormDesigner, Inject, ToolbarItem
} from '@syncfusion/ej2-react-pdfviewer';
export default function App() {
const viewerRef = React.useRef(null);
const toolbarSettings = {
toolbarItems: [
'OpenOption',
'UndoRedoTool',
'PageNavigationTool',
'MagnificationTool',
'PanTool',
'SelectionTool',
'CommentTool',
'SubmitForm',
'AnnotationEditTool',
'RedactionEditTool',
'FormDesignerEditTool',
'SearchOption',
'PrintOption',
'DownloadOption'
] as ToolbarItem[]
};
const px = (pt: number): number => (pt * 96) / 72;
const searchTextAndRedact = async () => {
if (!viewerRef.current || !viewerRef.current.textSearchModule) return;
const term = 'syncfusion'; // change to the term you want to redact
const results = await viewerRef.current.textSearchModule.findTextAsync(term, false);
if (!results || results.length === 0) {
console.warn('No matches found.');
return;
}
for (const pageResult of results) {
if (!pageResult?.bounds?.length) continue;
const pageNumber = (pageResult.pageIndex ?? -1) + 1; // convert 0-based to 1-based
if (pageNumber < 1) continue;
for (const bound of pageResult.bounds) {
viewerRef.current.annotation.addAnnotation('Redaction', {
bound: {
x: px(bound.x),
y: px(bound.y),
width: px(bound.width),
height: px(bound.height)
},
pageNumber,
overlayText: 'Confidential',
fillColor: '#000000',
fontColor: '#FFFFFF',
fontSize: 12,
fontFamily: 'Arial'
});
}
}
};
const applyRedaction = () => {
if (!viewerRef.current || !viewerRef.current.annotation) return;
// This permanently removes content marked by redaction annotations
viewerRef.current.annotation.redact();
};
return (
<div className='content-wrapper' style={{ padding: 12 }}>
<div style={{ marginBottom: 12, display: 'flex', gap: 8 }}>
<button id='searchTextRedact' type='button' onClick={searchTextAndRedact}>
Search "syncfusion" & Mark for Redaction
</button>
<button id='applyRedaction' type='button' onClick={applyRedaction}>
Apply Redaction
</button>
</div>
<PdfViewerComponent
ref={viewerRef}
id='container'
documentPath='https://cdn.syncfusion.com/content/pdf/pdf-succinctly.pdf'
resourceUrl='https://cdn.syncfusion.com/ej2/31.2.2/dist/ej2-pdfviewer-lib'
toolbarSettings={toolbarSettings}
isExtractText={true}
style={{ height: '640px', display: 'block' }}
>
<Inject services={[
Toolbar,
Magnification,
Navigation,
Annotation,
LinkAnnotation,
BookmarkView,
ThumbnailView,
Print,
TextSelection,
TextSearch,
FormFields,
FormDesigner
]} />
</PdfViewerComponent>
</div>
);
}Expected result
- The viewer loads the specified PDF.
- Clicking “Search "syncfusion" & Mark for Redaction” adds redaction annotations over the matched text.
- Clicking “Apply Redaction” permanently removes the marked content from the document; this operation is irreversible.
Troubleshooting
- Issue: “No matches found” even though text exists — Cause: PDF text extraction may not be ready. Solution: Wait for the document to finish loading or call search after the
documentLoadevent. - Issue: Bounds look misplaced — Cause:
findTextAsync()returns bounds in points (72 DPI). Ensure conversion to pixels using the providedpx()helper. - Issue:
textSearchModuleis undefined — Cause:TextSearchservice not injected. AddTextSearchto theInjectservices list. - Issue: Redactions not applied — Cause:
redact()requires redaction annotations present and viewer to support apply-redaction; ensureAnnotationservice andRedactionfeatures are available in your build.