Sign a PDF document using JavaScript

Requirements
View Demo

To sign an existing approval signature field in a PDF Document:

1WebViewer({
2 fullAPI: true,
3 // ...Other config options
4}).then(async (instance) => {
5 /* This example assumes:
6 * - The certificates are hosted from `your-test-env.com/digital-sig/certificate_x.pfx` and `your-test-env.com/digital-sig/cert_x.pem`
7 * * - `.pem` files should contain public certificates
8 * → used to verify signatures
9 *
10 * - `.pfx` files contain private key + certificate (PKCS#12 bundle)
11 * → used to create digital signatures (requires password)
12 */
13
14 const { Annotations, documentViewer } = instance.Core;
15 const { VerificationOptions } = instance.UI;
16 const annotationManager = documentViewer.getAnnotationManager();
17 const fieldManager = annotationManager.getFieldManager();
18
19 // 1. Add trust certificates (PUBLIC certs only)
20 VerificationOptions.addTrustedCertificates([
21 '/digital-sig/cert_1.pem',
22 '/digital-sig/cert_2.pem',
23 '/digital-sig/cert_3.pem',
24 '/digital-sig/cert_4.pem',
25 '/digital-sig/cert_5.pem',
26 ]);
27 console.log('🔒 Trust certificates added');
28
29 // 2. Listen for signature application events
30 annotationManager.addEventListener('digitalSignatureApplied', (details) => {
31 console.log('SignatureWidgetInfo From Event: ', details);
32 });
33
34 // 3. Create signature fields
35 const sigConfigs = [
36 { name: 'Sig_1' + Math.random(), page: 1, x: 50, y: 50, w: 200, h: 50 },
37 { name: 'Sig_2' + Math.random(), page: 1, x: 300, y: 50, w: 200, h: 50 },
38 { name: 'Sig_3' + Math.random(), page: 1, x: 50, y: 120, w: 200, h: 50 },
39 { name: 'Sig_4' + Math.random(), page: 1, x: 300, y: 120, w: 200, h: 50 },
40 { name: 'Sig_5' + Math.random(), page: 1, x: 50, y: 190, w: 200, h: 50 },
41 ];
42
43 const widgets = [];
44 for (const cfg of sigConfigs) {
45 const field = new Annotations.Forms.Field(cfg.name, { type: 'Sig' });
46 fieldManager.addField(field);
47
48 const widget = new Annotations.SignatureWidgetAnnotation(field, {
49 appearance: '_DEFAULT',
50 appearances: { _DEFAULT: { Normal: { offset: {} } } },
51 });
52 widget.PageNumber = cfg.page;
53 widget.X = cfg.x;
54 widget.Y = cfg.y;
55 widget.Width = cfg.w;
56 widget.Height = cfg.h;
57 widgets.push(widget);
58 }
59 annotationManager.addAnnotations(widgets);
60 annotationManager.drawAnnotationsFromList(widgets);
61 console.log('📝 Created 5 signature fields');
62
63 // 4. Fetch the cryptographic PFX bundles
64 const certs = await Promise.all(
65 [1, 2, 3, 4, 5].map(async (i) => {
66 const resp = await fetch(`/digital-sig/certificate_${i}.pfx`);
67 const buf = await resp.arrayBuffer();
68 console.log(`📄 Loaded certificate_${i}.pfx (${buf.byteLength} bytes)`);
69 return buf;
70 })
71 );
72
73 // 5. Apply signatures sequentially
74 let signedData;
75 for (let i = 0; i < sigConfigs.length; i++) {
76 const fieldName = sigConfigs[i].name;
77 try {
78 console.log(`🖊️ Signing "${fieldName}" with certificate_${i + 1}.pfx...`);
79 signedData = await annotationManager.sign(fieldName, {
80 certificate: certs[i],
81 password: 'test123',
82 });
83 console.log(`"${fieldName}" signed!`);
84 } catch (err) {
85 console.error(`Failed to sign "${fieldName}":`, err);
86 break;
87 }
88 }
89
90 console.log('All 5 signatures applied!');
91
92 // 6. Save the signed document
93 // sign() resolves to { buffer, fieldName, widget }. Save the buffer —
94 // the document open in the viewer is not the signed file.
95 const blob = new Blob([signedData.buffer], { type: 'application/pdf' });
96 const url = URL.createObjectURL(blob);
97 const link = document.createElement('a');
98 link.href = url;
99 link.download = 'signed_doc.pdf';
100 link.click();
101 URL.revokeObjectURL(url);
102});

Info

The signed PDF is in the buffer returned by the signing call. Save or download this buffer, as shown in the code sample above. The document open in the viewer is not the signed file. Downloading the document from the viewer, for example with the Download button or downloadPdf(), produces a copy whose signatures fail validation.

For more advanced controls - including document permissions, custom signing for HSM integration, and LTV/time stamping - please refer to the sample below:
Digitally sign PDF files

About Adding An Approval Signature to a PDF Document

The Apryse SDK enables approval signatures in PDF documents using a Digital Certificate, in accordance with the latest PDF specification. By leveraging public key infrastructure (PKI) technology, with a certificate issued by a trusted certificate authority (CA), a signer can use a certificate-based digital ID to guarantee the authenticity of a signature. Placing a digital signature with a certificate can also guarantee that a document has not been modified since the signature was applied, ensuring its authenticity.

Apryse Docs Image

Image taken from Apryse WebViewer

Above is an example of a document containing a certified signature, guaranteed by a certificate generated by Apryse.com.

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales