Adobe-Style Green Tick: Signature Appearance Verification in Web Apps
When you open a signed PDF in Adobe Acrobat Reader, you see the verification result directly on the signature field — a green checkmark for valid, a red cross for invalid, a yellow question mark for unknown. Open the same file in almost any web PDF viewer and you get something else entirely: either no verdict at all, or a badge floated over the page in HTML, or — most misleading of all — the grey question mark the signing tool baked into the document, shown forever regardless of whether the signature is good.
VerifyKit brings the Acrobat behaviour to web applications: the status icon is drawn inside the PDF canvas, on the signature field itself, in the field's own rectangle at its scale and rotation, showing the verdict that signature actually got.
Why the placeholder is the wrong answer
A signature field's appearance is authored at signing time, before anyone has verified anything. The signing tool has no idea whether the document will still be intact when you open it, so it draws a neutral placeholder — usually a grey question mark, sometimes nothing.
A viewer that renders the document faithfully renders that placeholder. It is not a bug; it is what is in the file. But for a user it is worse than no icon: it looks like a verdict, and it is not one. A tampered document and a perfectly valid one look identical.
Showing the real result means the viewer has to draw the outcome of verification onto the field, the way Acrobat does.
How you switch it on
After verifyPdf() completes, VerifyKit produces a display copy of the document with the status icons applied:
import {
swapSignatureAppearances,
hasAcro6Appearances
} from '@trexolab/verifykit-react'
// After verification
const result = await verifier.verify(pdfBytes)
// Does this document have signature fields that can carry a status icon?
const hasAcro6 = await hasAcro6Appearances(pdfBytes)
if (hasAcro6 || result.signatures.some(s => s.isVisible)) {
// Returns display-only bytes — the original is untouched
const displayPdf = await swapSignatureAppearances(
pdfBytes,
result.signatures
)
// Render displayPdf in the viewer
}Three properties matter here, and they are the reason this is safe to switch on by default:
- Verification runs on the original, unmodified bytes. The returned bytes exist only to hand to the renderer. A download gives the user back the original file, byte for byte — which is essential, because a signed PDF that has been re-saved no longer verifies anywhere.
- Password-protected documents are supported. Encrypted signed PDFs are the case most implementations skip or, worse, corrupt in the attempt.
- Nothing is invented. Where a signature field cannot carry a status icon, VerifyKit leaves it exactly as the signer authored it rather than drawing something misleading over it.
If you use the React viewer with defaultLayoutPlugin, this is already wired up — the code above is what you need only if you are driving the pipeline yourself.
Adobe Reader parity
Matching Acrobat means matching more than the artwork; it means matching which verdict maps to which icon. Some of these are not obvious:
| Scenario | Adobe Reader Shows | VerifyKit Shows |
|---|---|---|
| All 8 checks pass | Green checkmark | Green checkmark |
| Integrity or signature fails | Red cross | Red cross |
| Revocation unknown (no online check) | Green checkmark | Green checkmark |
| Revocation attempted but failed | Yellow question mark | Yellow question mark |
| Certificate expired but integrity valid | Yellow question mark | Yellow question mark |
| Warning on non-critical check (EKU, timestamp) | Green checkmark | Green checkmark |
Note rows three and four in particular: a revocation check that was never attempted is not the same as one that was attempted and failed, and Acrobat treats them differently. VerifyKit's SignatureCheckResult carries an attempted flag for exactly this reason.
The same mapping is available on its own if you are building custom UI:
import { getDisplayStatus } from '@trexolab/verifykit-react'
const displayStatus = getDisplayStatus(sig)
// 'valid' | 'invalid' | 'unknown'Signature widget overlays
Beyond the in-canvas icon, the React viewer renders an interactive overlay on each signature field. Every overlay:
- Shows a coloured border matching the verification status
- Is clickable — opens the full signature details panel
- Covers multi-page PDFs where one signature field has widgets on several pages
- Handles documents where multiple widget annotations share a single signature value
Unsigned signature fields get an overlay too, so an empty signature block is visibly an empty signature block rather than a blank rectangle.
Document timestamps
Document timestamps (ETSI.RFC3161 sub-filter) are visually distinguished from regular signatures with a clock icon. They are archival timestamps for PAdES B-LTA compliance and cover the entire document rather than a single signature.
Why this matters
Users expect a signed PDF to look the same in your web app as it does in Adobe Reader. Without this, signature fields show the signer's placeholder no matter what verification found — which is not a neutral outcome, because a placeholder question mark reads as a verdict to everyone who sees it. Drawing the computed result closes the gap.
Next Steps
- Live Demo — Upload a signed PDF and watch the icons change
- Customization Guide — Theme the viewer
- Plugins Guide — Configure the signature panel and status bar
- Contact Us — Need help with integration?
Need PDF signature verification in production?
VerifyKit is a commercial SDK — try the live demo, then get in touch for a license.