- PDF Viewer
- PDF Toolbar
- PDF More Actions Menu
- PDF Floating Toolbar
- PDF Document Tabs
- PDF View
- PDF Document Grid
- PDF Document Info
- PDF Page Navigation
- PDF Zoom Controls
- PDF Undo/Redo Buttons
- PDF Keyboard Shortcuts
- PDF Bookmark Sidebar
- PDF Thumbnail Sidebar
- PDF Search Panel
- PDF Attachment List
- PDF Annotation Layer
- PDF Annotation Toolbar
- PDF Annotation Inspector
- PDF Annotation Selection Menu
- PDF Annotation Sidebar
- PDF Comment
- PDF Comment Draft
- PDF Comment Button
- PDF Comment Sidebar
- PDF Redaction Toolbar
- PDF Capture Button
- PDF Form Fill Toggle
- PDF Signature Button
- PDF Stamp Button
Every PDF carries a set of permission flags — whether it may be printed, copied, annotated, or edited. embedpdf reads those flags on open and enforces them at the source: the print plugin refuses to print a document that forbids it, the selection plugin refuses to copy, and so on. That enforcement is already in place; nothing needs installing to turn it on.
What the plugins don't do is tell the user. A button wired to a forbidden action still looks clickable, and clicking it just does nothing. pdfcn's chrome closes that gap — a control whose action the document forbids renders disabled, with a tooltip that says why.
Permission flags are the document's stated intent, not a security boundary. They live in the file and are enforced in the browser, so anyone with the bytes can lift them. Treat them as "respect the author's wishes," not "keep the content safe."
What reflects the flags#
These four controls read the active document's effective permissions and disable themselves when the matching flag is denied. Each is a standalone component, so this works whether you install them individually or through the viewer block.
| Control | Requires permission | Name in overrides |
|---|---|---|
PdfPrintButton | print | |
PdfCaptureButton | Copy contents | copyContents |
PdfAnnotationToolbar | Modify annotations | modifyAnnotations |
PdfRedactionToolbar | Modify contents | modifyContents |
There's nothing to wire up. A control disables itself when its permission is denied; when the flag is present, it behaves normally.
Here's the print button against a document whose print flag is denied — disabled, with a tooltip on hover. Download sits beside it untouched, since nothing gates it:
"use client";
import { PdfToolbar } from "@/components/pdf-toolbar";Each control's own page carries the same demo for its flag: copying, annotating, and editing.
Overriding a document's flags#
Permissions resolve in layers: a per-document override wins over the PDF's own flags. Pass a permissions config alongside a document to force a flag on or off, regardless of what the file says.
<PdfViewer
documents={[
{
url: "/sample.pdf",
permissions: {
// true = force allow, false = force deny.
overrides: { print: false, copyContents: false },
},
},
]}
className="h-[720px]"
>
<PdfViewerContent />
</PdfViewer>Use false to deny an action the PDF otherwise allows — a viewer that never prints, say. Use true to grant one the PDF withholds, which is what you'd reach for when your app is the authority on access and the file's own flags are noise.
An override left undefined falls through to the PDF's flag, so you only list the ones you mean to change.
Ignoring the PDF's flags entirely#
To start from "everything allowed" and layer overrides on top — rather than starting from what the file declares — set enforceDocumentPermissions to false:
permissions: {
// Ignore the PDF's flags; treat every action as allowed…
enforceDocumentPermissions: false,
// …except the ones you deny here.
overrides: { print: false },
}This is the escape hatch for documents whose flags are wrong or missing, when your own backend already decides who may do what.
Where the model comes from#
The flags, the layered resolution, and the plugin-level enforcement are embedpdf's, documented under Security. pdfcn adds the part a headless engine can't: chrome that shows the user which actions the document has taken off the table.