> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/salesforce/annotations/signature-tool.md).

# Signature Annotation in WebViewer Salesforce

Easily add custom signatures to PDFs in Salesforce with Apryse SDK. Draw, type, upload images, or import existing signatures. Explore the intuitive UI tool now! Salesforce WebViewer adds accurate, rel

Requiring signed documents isn't unfamiliar to Salesforce, Apryse SDK provides an intuitive UI tool for placing custom or hand-drawn signatures onto pdfs. Clicking the signature button in the header will open the signature dialog immediately. Users can also choose to save the signature and preview it before being drawn on the document.

Signatures can be created by:

* drawing

![](https://306473577-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfmJo9lQOEYOFBgOyFp26%2Fuploads%2Fgit-blob-410727c0e79a27787ec6b86809e10480627ec295%2Fa35eb5e147534734c7046c2b3d7b8f3d0774a4a7-640x370.gif?alt=media)

* typing

![](https://306473577-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfmJo9lQOEYOFBgOyFp26%2Fuploads%2Fgit-blob-75b6438c2b3934c6d4127010991fa179a675b366%2Fbf54d25fae996aa28c47dbd1b8c0067026dbb904-640x370.gif?alt=media)

* uploading an image

![](https://306473577-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfmJo9lQOEYOFBgOyFp26%2Fuploads%2Fgit-blob-1827089a1ff75d8586208b58054fc5dce916ae81%2F96d3a02c70ecbd40974787385c350ba0907d9ba0-640x370.gif?alt=media)

If there are any saved signatures, clicking the signature button will open an overlay in which signatures can be chosen and applied directly.

![](https://306473577-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfmJo9lQOEYOFBgOyFp26%2Fuploads%2Fgit-blob-28430dd09c5771c150942fd0c5f60d1702f1e5be%2Fae163c8118f3bc9f2b52b0c9b3ee70e21b5fa017-640x320.gif?alt=media)

## Importing existing signatures

If you already have a signature stored for the user, you can [import](https://sdk.apryse.com/api/web/Core.Tools.SignatureCreateTool.html#importSignatures) them into the signature tool:

{% tabs %}
{% tab title="JavaScript (SDK v8.0+)" %}
{% code lineNumbers="true" %}

```js
// Config file
const { documentViewer } = instance.Core;
const signatureTool = documentViewer.getTool('AnnotationCreateSignature');

documentViewer.addEventListener('documentLoaded', () => {
  signatureTool.importSignatures([base64Image]);
});
```

{% endcode %}
{% endtab %}

{% tab title="JavaScript (SDK v6.0+)" %}
{% code lineNumbers="true" %}

```js
// Config file
const { docViewer } = instance;
const signatureTool = docViewer.getTool('AnnotationCreateSignature');

docViewer.on('documentLoaded', () => {
  signatureTool.importSignatures([base64Image]);
});
```

{% endcode %}
{% endtab %}
{% endtabs %}

You can also save them by calling [exportSignatures](https://sdk.apryse.com/api/web/Core.Tools.SignatureCreateTool.html#exportSignatures__anchor).

## Adding custom fonts

By default `GreatVibes` is the only font that is available in the `Type` tab. More fonts can be added using the [setSignatureFonts](https://sdk.apryse.com/api/web/Core.Tools.SignatureCreateTool.html#importSignatures__anchor) API. Following is an example that adds [Tangerine](https://fonts.google.com/specimen/Tangerine/) from Google Fonts to the tab.

{% hint style="info" %}
Google recommends importing fonts in your index.html rather than via CSS for performance reasons. You can read more about Google's recommended methods here: <https://developers.google.com/fonts/docs/css2>
{% endhint %}

{% tabs %}
{% tab title="CSS" %}
{% code lineNumbers="true" %}

```css
/* inside <head> of index.html */

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

<link
  href="https://fonts.googleapis.com/css2?family=Tangerine&display=swap"
  rel="stylesheet">

```

{% endcode %}
{% endtab %}
{% endtabs %}

Or

{% tabs %}
{% tab title="CSS" %}
{% code lineNumbers="true" %}

```css
/* inside index.html */

<style>
@import url('https://fonts.googleapis.com/css2?family=Caveat:wght@400..700&display=swap');
</style>
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% tabs %}
{% tab title="JavaScript (SDK v8.0+)" %}
{% code lineNumbers="true" %}

```js
// WebViewer constructor
WebViewer({
  ...
  css: 'path/to/stylesheet.css'
})

// Config file
instance.UI.setSignatureFonts(currentFonts => [
  ...currentFonts,
  'Tangerine',
]);
```

{% endcode %}
{% endtab %}

{% tab title="JavaScript (SDK v6.0+)" %}
{% code lineNumbers="true" %}

```js
// WebViewer constructor
WebViewer({
  ...
  css: 'path/to/stylesheet.css'
})

// Config file
instance.setSignatureFonts(currentFonts => [
  ...currentFonts,
  'Tangerine',
]);
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Export a Signature to Blob Storage

If you have created a Signature and you would like to it store for later use, you can export the Signature as a blob and save it to an external storage solution.

{% tabs %}
{% tab title="JavaScript (SDK v8.0+)" %}
{% code lineNumbers="true" %}

```js
// Config file
const { annotationManager, documentViewer } = instance.Core;

documentViewer.addEventListener('annotationsLoaded', async () => {
    annotationManager.addEventListener('annotationSelected', async (annotationList) => {
        annotationList.forEach(annotation => {
            if (annotation.Subject === "Signature")
                extractAnnotationSignature(annotation, documentViewer);
        })
    })
});
```

{% endcode %}
{% endtab %}

{% tab title="JavaScript (SDK v6.0+)" %}
{% code lineNumbers="true" %}

```js
// Config file
const { annotManager, docViewer } = instance;

docViewer.on('annotationsLoaded', async () => {
    annotManager.on('annotationSelected', async (annotationList) => {
        annotationList.forEach(annotation => {
            if (annotation.Subject === "Signature")
                extractAnnotationSignature(annotation, docViewer);
        })
    })
});
```

{% endcode %}
{% endtab %}
{% endtabs %}

Sample Function to export the Signature

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
async function extractAnnotationSignature(annotation, docViewer) {
    // Create a new Canvas to draw the Annotation on
    const canvas = document.createElement('canvas');
    // Reference the annotation from the Document
    const pageMatrix = docViewer.getDocument().getPageMatrix(annotation.PageNumber);
    // Set the height & width of the canvas to match the annotation
    canvas.height = annotation.Height;
    canvas.width = annotation.Width;
    const ctx = canvas.getContext('2d');
    // Translate the Annotation to the top Top Left Corner of the Canvas ie (0, 0)
    ctx.translate(-annotation.X, -annotation.Y);
    // Draw the Annotation onto the Canvas
    annotation.draw(ctx, pageMatrix);
    // Convert the Canvas to a Blob Object for Upload
    canvas.toBlob((blob) => {
        // Call your Blob Storage Upload Function
    });
}
```

{% endcode %}
{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/salesforce/annotations/signature-tool.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
