Integrate Legalesign Document Viewer into Your Website
You can see this component in action as Quick Send in Console.
The Legalesign Document Viewer is a platform-agnostic web component that allows you to edit, preview, and customize templates for document signing. It works seamlessly in HTML with JavaScript, React, Vue, Angular, or any web framework.
This plug and play component is designed so that you can integrate key parts of document creation into your internal systems, such as a CRM or line of business application.
As long as your system can render and support HTML components, you can use the Document Viewer.
If you need additional help integrating the Document Viewer into your technical stack please get in touch with our support desk.
You can use these larger widgets with REST/GraphQL API integrations to provide seamless document signing processes for your staff and customers.
Installation
NPM Installation
npm install legalesign-document-viewer
# or
pnpm add legalesign-document-viewer
For React Projects
npm install legalesign-document-viewer-react
# or
pnpm add legalesign-document-viewer-react
Basic Integration
HTML/JavaScript
The HTML/Javascript version of this component can be used with any development stack, such as PHP, ASP .Net etc. You
can link to the component directly from npm if your environment doesn't allow it to be installed. You can try out a
demonstration page from the example repository here [https://github.com/legalesign/ls-viewer-demo].
Add the component scripts to your HTML:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="node_modules/legalesign-document-viewer/dist/ls-document-viewer/ls-document-viewer.css" />
<script type="module" src="node_modules/legalesign-document-viewer/dist/ls-document-viewer/ls-document-viewer.esm.js"></script>
<script nomodule src="node_modules/legalesign-document-viewer/dist/ls-document-viewer/ls-document-viewer.js"></script>
</head>
<body>
<ls-document-viewer
id="my-editor"
templateid="YOUR_TEMPLATE_ID"
token="YOUR_AUTH_TOKEN"
></ls-document-viewer>
</body>
</html>
Authentication - Get a token
You'll need to use server-side code to get YOUR_AUTH_TOKEN. There are three options:
- SRP JWT directly — If your backend already uses SRP authentication, pass the JWT access token directly to the widget.
- GraphQL
generateComponentToken— Call the mutation with your API key or SRP JWT to mint a short-lived, scoped component token. - REST API — Call
GET /templatepdf/{pdfId}/component-token/with your API key.
Option 2 (GraphQL):
const response = await fetch('https://graphql.uk.legalesign.com/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${process.env.LEGALESIGN_API_KEY}`,
},
body: JSON.stringify({
query: `mutation {
generateComponentToken(input: { component: LS_DOCUMENT_VIEWER }) {
token
expiresIn
expiresAt
}
}`,
}),
});
const { data } = await response.json();
const token = data.generateComponentToken.token;
Option 3 (REST):
const response = await fetch(
`https://eu-api.legalesign.com/api/v1/templatepdf/${pdfId}/component-token/`,
{
headers: {
Authorization: `Bearer ${process.env.LEGALESIGN_API_KEY}`,
},
}
);
const { token } = await response.json();
Pass the returned token (or your SRP JWT) to the widget. See Widget Authorization for more detail on token options.
React Integration
We have also generated a version of the component that integrates directly with React frameworks.
import { LsDocumentViewer } from 'legalesign-document-viewer-react';
function App() {
return (
<LsDocumentViewer
templateid="YOUR_TEMPLATE_ID"
token="YOUR_AUTH_TOKEN"
mode="compose"
/>
);
}
Required Attributes
token
Your security token for authentication. This can be either an SRP JWT access token or a short-lived component token from generateComponentToken. See Widget Authorization for the secure token flow.
token="eyJraWQiOiJBTkJIeT..."
templateid
The API ID of the template you want to present to users. You can find this by looking in the url when you are editing the template in the Web App.
templateid="dHBsYjQ5YTg5NWQtYWRhMy0xMWYwLWIxZGMtMDY5NzZlZmU0MzIx"
Widget Modes
Editor Mode
Full-featured template creation and editing with all available tools. This is intended for work flows where a highly reusable template with roles is helpful. If your intention is to only use your document once (perhaps your document generation system has already filled in all the client information) then you may want to consider compose mode instead.
<ls-document-viewer mode="editor" ...></ls-document-viewer>
Compose Mode
This mode is a 'recipient-first' method to streamline the user experience. In the Legalesign Web App this is the 'Quick send' function.
Add your recipients to the 'recipient' attribute and your user can quickly place their signatures and form fields, before sending. Ideal for integrated clients where recipients are already defined.
The typical workflow is clone or upload a PDF, then embed the viewer where the user can add signature and form fields, then offer a button to send the document.
Clone
Clone an existing template by using the copyTemplate mutation:
const response = await fetch('https://graphql.uk.legalesign.com/graphql', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
query: `
mutation CopyTemplate {
copyTemplate(input: {
groupId: "yourGroupId",
templateId: "yourTemplateId",
newTitle: "new document title",
copyFields: true|false
})
}
`
})
});
const { data } = await response.json();
const templateId = data.copyTemplate;
Or Upload
Create a template then upload it to the uploadUrl provided. Use title [deleted] if you do not want the pdf in your library. It will be deleted in the next 24 hours. Otherwise use any title of your choosing:
const response = await fetch('https://graphql.uk.legalesign.com/graphql', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
query: `
mutation CreateTemplate {
createTemplate(input: {groupId: "yourGroupid", title: "[deleted]"}) {
id
uploadUrl
}
}
`
})
});
const { data } = await response.json();
const templateId = data.createTemplate.id;
const uploadUrl = data.createTemplate.uploadUrl;
Now PUT your file to the uploadUrl. Content type must be application/pdf.
Embed viewer
The main attribute is 'recipients'. You will need additional details for approvers or witnesses - for more information see Recipients.
<ls-document-viewer
mode="compose"
recipients='[
{"email": "user@example.com", "firstname": "John", "lastname": "Doe", "signerIndex": 1},
{"email": "user2@example.com", "firstname": "Jane", "lastname": "Smith", "signerIndex": 2}
]'
...></ls-document-viewer>
Compose mode automatically:
- Detects pre-generated recipients
- Hides the sender from dropdown
- Hides document options
- Shows required fields by default
- Removes sender and sender fields from the editor
- Promotes quick selection of the required fields for each recipient
Preview Mode
A helpful document preview that shows the document with all the current fields and lets the user browse though pages.
<ls-document-viewer mode="preview" ...></ls-document-viewer>
Preview mode automatically:
- Hides the toolbar
- Hides document options
- Hides toolbox
- Makes participants and fields read-only
Advanced Configuration
Filter Toolbox
Restrict available field types using pipe-delimited values. If no value is provided then it is assumed the toolbox will be unfiltered and all options are available.
<ls-document-viewer
filtertoolbox="signature|initials|date|text"
...
></ls-document-viewer>
Available filter values:
| Value | Description |
|---|---|
signature | Signature field (signer only) |
auto sign | Auto-sign field (sender only) |
text | Free text input |
signing date | Date auto-filled at signing time (signer only) |
date | Date picker field |
email | Email input |
initials | Initials field |
number | Numeric input |
dropdown | Dropdown select |
checkbox | Checkbox |
regex | Regex-validated input (signer only) |
image | Image upload (signer only) |
file | File upload (signer only) |
drawn | Drawn/freehand field (signer only) |
Recipients
Define document recipients in JSON format.
The required elements for each recipient are firstname, lastname, email and signerIndex;
Optionally you can pass the role and phonenumber for each recipient. Omitting a role means that the recipient will be treated as a signer.
You can pass role "WITNESS" or "APPROVER". For role "WITNESS" add 100 to the signerIndex number of their signer. For example if you need a witness for signer 2 (signerIndex: 2), make the WITNESS signerIndex: 102.
<ls-document-viewer
recipients='[
{"email": "user@example.com", "firstname": "John", "lastname": "Doe", "signerIndex": 1},
{"email": "user2@example.com", "firstname": "Jane", "lastname": "Smith", "signerIndex": 2}
{"email": "user3@example.com", "firstname": "Joan", "lastname": "Mitchell", "signerIndex": 102, roleType: "WITNESS"}
]'
...
></ls-document-viewer>
Custom Buttons with Slots
Add custom buttons to the toolbar using slots. You will probably use these to either cancel the action or send the document.
<ls-document-viewer ...>
<style>
.custom-button {
padding: 2px 12px;
border-radius: 1rem;
background-color: #9df5d4;
color: #125241;
font-weight: 500;
}
</style>
<span slot="left-button">
<button class="custom-button">Cancel</button>
</span>
<span slot="right-button">
<button class="custom-button">Send Document</button>
</span>
</ls-document-viewer>
Event Handling
Listen to component events to track changes:
const editor = document.querySelector('ls-document-viewer');
editor.addEventListener('update', (event) => {
console.log('Template changed:', event.detail);
});
You can track whether a template have become valid or invalid using the validate event.
const editor = document.querySelector('ls-document-viewer');
editor.addEventListener('validate', (event) => {
console.log('Template validation changed:', event.detail.valid);
});
React Event Handling Example
Using an event in react prefixes it with the familiar on<EventName>.
<LsDocumentViewer
onUpdate={(event) => {
console.log('Template changed:', event.detail);
}}
...
/>
Event Types
update event
Fired when the document template is changed, such as adding or removing fields. Provides not only the event that caused it but also the updated state of the template object as JSON.
validate event
Fired when the document template is changed, the valid property in detail shows if the
template has become valid or invalid.
selectFields event
Fired when a field is selected in the editor.
addParticipant event
Fired when a participant role is added to the template.
Complete Example
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document Editor</title>
<link rel="stylesheet" href="https://unpkg.com/legalesign-document-viewer/ls-document-viewer.css" />
<script type="module" src="https://unpkg.com/legalesign-document-viewer"></script>
</head>
<body style="padding: 0; margin: 0">
<ls-document-viewer
id="my-editor"
templateid="dHBsYjQ5YTg5NWQtYWRhMy0xMWYwLWIxZGMtMDY5NzZlZmU0MzIx"
token="YOUR_TOKEN_HERE"
mode="compose"
recipients='[
{"email": "signer@example.com", "firstname": "John", "lastname": "Doe", "signerIndex": 1}
]'
filtertoolbox="signature|initials|date"
>
<span slot="left-button">
<button onclick="handleCancel()">Cancel</button>
</span>
<span slot="right-button">
<button onclick="handleSend()">Send</button>
</span>
</ls-document-viewer>
<script>
const editor = document.querySelector('ls-document-viewer');
editor.addEventListener('update', (event) => {
// shows the change event and the template details
console.log('Document updated:', event.detail);
});
function handleCancel() {
// Implement the cancel logic, e.g. go to a home page
window.location.href = '/cancelpage';
}
function handleSend() {
// Implement send logic if required.
console.log('Sending document...');
}
</script>
</body>
</html>
You can use the GraphQL send mutation client-side if using the SRP JWT token, but otherwise server-side using your API Key with either the GraphQL or REST interface.
- Send mutation — send a single document
- Send Input Schema — full input reference
- REST Send - REST send document reference
Trouble Shooting
If you encounter issues with the component, ensure that:
- you can access or have white listed the document storage domain at https://s3.amazonaws.com/*
Browser Support
The component uses modern web standards and supports:
- Chrome/Edge (latest)
- Firefox (latest)
- Safari (latest)
- Mobile browsers (iOS Safari, Chrome Mobile)
Resources
- GraphQL Integration Guide — how to connect the viewer to the GraphQL API for sending
- GraphQL API Documentation
- NPM Package
- React Package
- Support
Getting Help
For technical support or questions about integration, contact the Legalesign support team or visit the API documentation.