Integrate Legalesign Signer into Your Website
The Signer component requires activation. Contact support to enable it for your team.
The Legalesign Signer is a platform-agnostic web component that provides a complete and seamless document signing experience from within your own app. It works with vanilla HTML, React, Vue, Angular, or any web framework.
Embed this component wherever your users need to sign documents — inside a CRM, client portal, or any internal application that renders HTML.
Installation
Load directly from the CDN (no install required):
<script type="module" src="https://cdn.legalesign.io/signer/latest/ls-signer.esm.js"></script>
React installation
Install via a package manager:
npm install legalesign-signer
# or
pnpm add legalesign-signer
Basic Integration
HTML & JavaScript
<ls-signer
recipient-id="abc123"
private-key="key"
session-id="session"
></ls-signer>
<script>
const signer = document.querySelector('ls-signer');
signer.addEventListener('signingSuccess', (e) => console.log('Signed:', e.detail));
signer.addEventListener('signingFail', (e) => console.error('Failed:', e.detail));
</script>
React
import { useEffect, useState } from 'react';
import { LsSigner } from 'legalesign-signer/react';
import 'legalesign-signer/react.css';
function SigningPage() {
const [signerData, setSignerData] = useState(null);
useEffect(() => {
fetch('/your-backend/to-get-token')
.then(res => res.json())
.then(setSignerData);
}, []);
if (!signerData) return <p>Loading...</p>;
return (
<LsSigner
recipientId={signerData.recipientId}
privateKey={signerData.token}
sessionId={signerData.sessionId}
onSuccess={({ documentId }) => console.log('Signed:', documentId)}
onFail={({ error }) => console.error('Failed:', error)}
/>
);
}
React requires react and react-dom (v18 or v19) as peer dependencies.
Vue
Use in your component:
<template>
<ls-signer
:recipient-id="recipientId"
:private-key="privateKey"
:session-id="sessionId"
@signingSuccess="handleSuccess"
@signingFail="handleFail"
/>
</template>
If using Vue with Vite, add isCustomElement: (tag) => tag.startsWith('ls-') to your Vue plugin config to suppress unknown element warnings.
Authentication
The signer component requires a short-lived token from your backend. There are two options:
- GraphQL
generateComponentToken— Call withcomponent: LS_SIGNERand either arecipientIdorsessionIdin the signer scope (provide one, not both). - REST API — Call
GET /signer/{signerId}/component-token/with your API key.
Both return the token and sessionId needed by the component. See Widget Authorization for the full server-side token flow.
Option 1: GraphQL (Node.js)
Using recipientId (most common — use when you know the recipient but don't yet have a session):
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 MintSignerToken($input: GenerateComponentTokenInput!) {
generateComponentToken(input: $input) {
token
tokenType
sessionId
expiresIn
expiresAt
}
}`,
variables: {
input: {
component: 'LS_SIGNER',
signer: { recipientId: '<recipient-id>' }
}
}
})
});
const { data } = await response.json();
const { token, sessionId } = data.generateComponentToken;
Alternatively, if you already have a sessionId from a previous call:
variables: {
input: {
component: 'LS_SIGNER',
signer: { sessionId: '<session-id>' }
}
}
Option 2: REST API
const response = await fetch(
`https://eu-api.legalesign.com/api/v1/signer/${signerId}/component-token/`,
{
headers: {
Authorization: `Bearer ${process.env.LEGALESIGN_API_KEY}`,
},
}
);
const { token, sessionId } = await response.json();
Pass token as private-key and sessionId as session-id to the component.
Required Attributes
| Attribute | Type | Description |
|---|---|---|
recipient-id | string | Recipient identifier (base64, rec prefix, or UUID) |
private-key | string | Token returned by generateComponentToken |
session-id | string | Session ID returned by generateComponentToken |
Optional Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
colour | string | blue | Theme colour name (see Theming) |
style | string | `` | Style alterations (see Customer CSS) |
branding | boolean | true | Remove Legalesign branding |
Events
| Event | Detail | Description |
|---|---|---|
signingSuccess | { documentId, recipientId } | Emitted when signing completes |
signingFail | { error, documentId?, recipientId } | Emitted on signing failure |
React Props
The React component uses camelCase props and callback props instead of DOM events:
| Prop | Type | Required | Description |
|---|---|---|---|
recipientId | string | ✅ | Recipient identifier |
privateKey | string | ✅ | Private key from the generateComponentToken mutation |
sessionId | string | ✅ | Session identifier |
colour | LsSignerColour | ❌ | Theme colour |
onSuccess | (data: { documentId: string; recipientId: string }) => void | ❌ | Called on successful signing |
onFail | (data: { error: string; documentId?: string; recipientId: string }) => void | ❌ | Called on signing failure |
Theming
Set a colour theme with the colour prop. All shades are derived automatically.
Available Colours
pink · blue · purple · indigo · teal · green · lightblue · burnt · aubergine · red · yellow · cyan · lime · trueGreen
Omit the prop for the default blue.
<ls-signer colour="pink" ...></ls-signer>
<LsSigner colour="pink" ... />
The colour prop sets a data-ls-theme attribute on the component root. CSS custom properties define a 10–100 shade scale for each colour:
| Shade | Usage |
|---|---|
| 10 | Light backgrounds, subtle fills |
| 20 | Subtle borders |
| 30 | Focus rings |
| 60 | Primary colour (buttons, links, active states) |
| 70 | Hover state |
| 80 | Dark/strong accents |
Custom CSS
The component exposes CSS custom properties that can be overridden to customise appearance beyond the colour theme. This set of properties is limited at present, contact us for more.
<ls-signer
style="--ls-font-family: 'Inter', sans-serif; --ls-color-primary-60: #e91e63;"
recipient-id="abc123"
private-key="key"
session-id="session"
></ls-signer>
Available Properties
| Property | Default | Description |
|---|---|---|
--ls-font-family | 'IBM Plex Sans', sans-serif | Primary font family |
--ls-color-primary-10 to --ls-color-primary-100 | — | Full primary colour scale (overrides theme) |
--ls-color-error | #f64a44 | Error state colour |
--ls-color-error-light | #fff0f0 | Error background |
--ls-color-success | #46dbaa | Success state colour |
--ls-color-success-light | #effff9 | Success background |
--ls-color-warning | #fad232 | Warning state colour |
--ls-color-warning-light | #fffcef | Warning background |
--ls-color-border | #d8d9dc | Default border colour |
--ls-color-border-subtle | #e0e2e5 | Subtle border colour |
--ls-color-bg-subtle | #f7f8fa | Subtle background colour |
Note: For full custom CSS injection (targeting internal elements directly, overriding font sizes, border radius, spacing, etc.), this is a planned future feature. Please get in touch if you're interested.
Complete Example
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document Signing</title>
<script type="module" src="https://cdn.legalesign.io/signer/latest/ls-signer.esm.js"></script>
</head>
<body>
<ls-signer
recipient-id="abc123"
private-key="key"
session-id="session"
colour="teal"
></ls-signer>
<script>
const signer = document.querySelector('ls-signer');
signer.addEventListener('signingSuccess', (event) => {
console.log('Document signed:', event.detail.documentId);
window.location.href = '/thank-you';
});
signer.addEventListener('signingFail', (event) => {
console.error('Signing failed:', event.detail.error);
});
</script>
</body>
</html>
Browser Support
- Chrome/Edge (latest)
- Firefox (latest)
- Safari (latest)
- Mobile browsers (iOS Safari, Chrome Mobile)