Redaction
Redaction removes content from a document for good: the text, images and drawings under an area are taken out of the file, not just covered. It takes two steps. First you mark what to remove, then you apply the marks:
// 1. Mark: a redact annotation over the area
const { annotation } = await page.annotations.create({
subtype: 'redact',
rect: { x: 72, y: 132, width: 248, height: 20 },
interiorColor: '#000000',
});
// 2. Apply: remove what's under it
await doc.redaction.apply({ annotations: [annotation.ref] });
// 3. Save a file without the removed content
const bytes = await doc.download({ mode: 'rewrite' });Mark what to remove#
A mark is a redact annotation. It removes nothing yet: it shows as an outline, the text under it
can still be read and copied, and you can change or delete it like any other annotation. That
lets someone review the marks before anything is gone.
Mark an area with rect, in points. To mark text exactly, as it runs across lines or at an
angle, give its quadPoints instead, the same corners a highlight takes. Search results have
them:
const { matches } = await doc.search.query({ text: 'Jane Doe', wholeWord: true });
for (const match of matches) {
await doc.page(match.page).annotations.create({
subtype: 'redact',
quadPoints: match.segments.map((segment) => segment.quad),
interiorColor: '#000000',
});
}With quadPoints, the quads decide what’s removed, and rect (the box around them) is worked out
for you. A text selection gives you the same quads; see
Selection & geometry.
Choose what’s left in its place#
After the content is removed, the engine paints the area. These fields say what it paints:
| Field | What it is | Default |
|---|---|---|
interiorColor | The fill, '#rrggbb' | no fill |
overlayText | Text on top of the fill, such as 'REDACTED' | none |
repeat | Repeat overlayText to fill the whole area | false |
fontFamily | The font of overlayText, such as 'times-roman'; see Fonts | 'helvetica' |
fontSize | Its size in points; 0 fits the text to the area | 12 |
fontColor | Its color | black |
textAlign | 'left', 'center' or 'right' | 'left' |
color | The outline shown while the area is only marked | red |
Without a fill or text, the area is left blank: the content is gone and the page shows through. In PDF apps that support it, hovering a mark previews the fill and text it will leave.
Apply#
apply() removes the content under marks. Pass the marks to apply:
await doc.redaction.apply({ annotations: [markA.ref, markB.ref] });Or apply every mark on some pages:
const { pages } = await doc.pages.list();
await doc.redaction.apply({ pages: pages.map((page) => page.ref) });The result says what happened on each page:
const { results, removedAnnotationCount } = await doc.redaction.apply({ pages: [page.ref] });
// results: [{ page, status: 'applied', removedAnnotationCount: 1 }]A page’s status is 'applied', or 'unchanged' when it had no marks. The marks you applied are
removed from the page. Other annotations that overlap a marked area are removed too, because they
could reveal what was there; removedAnnotationCount counts those, so you can tell the user.
Passing a ref that isn’t a redact annotation fails with InvalidArg before anything changes.
What gets removed#
Under each marked area, applying removes:
- Text: the characters themselves, so they can’t be searched, selected or copied anymore. Text next to the area stays.
- Images: the pixels inside the area are erased from the image. For a slanted mark, that’s the box around it.
- Drawings: the parts of lines, shapes and fills inside the area.
- Annotations and form fields that overlap the area, even in part, with their popups. For a
mark with
quadPoints, the quads count, not the box around them.
This includes content the page draws from shared parts of the file, not only what the page draws itself. There’s no undo: once applied, the content is gone from the document. Applying also ends undo for every change made before it; see Changes & undo.
Save the redacted file#
Apply changes the document as it is now, but an incremental save still holds the version you
opened, with everything you removed. Anyone with a PDF tool can recover it. For a file you share,
save with mode: 'rewrite':
const bytes = await doc.download({ mode: 'rewrite' });A rewrite writes the document as it is now and nothing else. See Saving.
Permissions#
Marking is annotation work: creating a redact annotation needs the permission to create
annotations. Applying needs all three of doc.redact, doc.pages.modify and
doc.annotate.modify, because it changes the page and removes annotations. Without them,
apply() fails with Forbidden. See Permissions.
Give doc.redact to the people who decide what goes; others can still mark areas for them.
Good to know#
Marks from other apps#
A redact annotation made by another app (Acrobat, for example) applies the same way. When it carries its own finished overlay, the engine paints that; otherwise it paints the fill and text from the fields above.
When a page fails#
Apply is all or nothing. When a page fails, or the call is cancelled, no page changes and the call rejects with the error. Apply again to retry.
Events#
Other code can follow redactions with the redaction.applied event. See
Events.
Your feedback goes directly to the documentation team.