Intégrer le Signataire Legalesign à Votre Site Web
Le composant Signataire nécessite une activation. Contactez le support pour l’activer pour votre équipe.
Version actuelle : v1.1.7 — journal des modifications
Le Signataire Legalesign est un composant web indépendant de la plateforme qui offre une expérience complète et fluide de signature de documents directement depuis votre propre application. Il fonctionne avec du HTML vanilla, React, Vue, Angular ou tout autre framework web.
Intégrez ce composant partout où vos utilisateurs doivent signer des documents — dans un CRM, un portail client ou toute application interne qui rend du HTML.
Installation
Chargement direct depuis le CDN (pas d’installation requise) :
<script type="module" src="https://cdn.legalesign.io/signer/latest/ls-signer.esm.js"></script>
Installation React
Installation via un gestionnaire de paquets :
npm install legalesign-signer
# or
pnpm add legalesign-signer
Intégration basique
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.eventType, e.detail.documentId));
signer.addEventListener('signingFail', (e) => console.error('Failed:', e.detail.failureReason, e.detail.error));
signer.addEventListener('fieldChange', (e) => console.log('Field event:', e.detail.eventType));
</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={({ eventType, documentId }) => console.log(eventType, documentId)}
onFail={({ eventType, failureReason, error }) => console.error(eventType, failureReason, error)}
onChange={({ eventType, uuid, saved, field, document }) => console.log('Event:', eventType)}
/>
);
}
React requiert react et react-dom (v18 ou v19) en peer dependencies.
Vue
<template>
<ls-signer
ref="signer"
:recipient-id="recipientId"
:private-key="privateKey"
:session-id="sessionId"
/>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
const signer = ref(null);
function handleSuccess(e) {
console.log('Signed:', e.detail);
}
function handleFail(e) {
console.error('Failed:', e.detail);
}
onMounted(() => {
signer.value.addEventListener('signingSuccess', handleSuccess);
signer.value.addEventListener('signingFail', handleFail);
});
onBeforeUnmount(() => {
signer.value?.removeEventListener('signingSuccess', handleSuccess);
signer.value?.removeEventListener('signingFail', handleFail);
});
</script>
Si vous utilisez Vue avec Vite, ajoutez isCustomElement: (tag) => tag.startsWith('ls-') à la configuration de votre plugin Vue pour supprimer les avertissements d’éléments inconnus.
Vue 3 met les noms d’événements en minuscules sur les éléments personnalisés, donc @signingSuccess ne fonctionnera pas. Utilisez addEventListener sur la référence de l’élément comme montré ci-dessus.
Encapsulez <ls-signer> dans <ClientOnly> pour éviter les erreurs SSR. Ajoutez la configuration d’élément personnalisé dans nuxt.config.ts :
export default defineNuxtConfig({
vue: {
compilerOptions: {
isCustomElement: (tag) => tag.startsWith('ls-'),
},
},
});
Authentification
Le composant signataire nécessite un jeton à courte durée de vie provenant de votre backend. Deux options s’offrent à vous :
- GraphQL
generateComponentToken— Appelez aveccomponent: LS_SIGNERet soit unrecipientIdsoit unsessionIddans le scope signataire (fournissez un seul, pas les deux). - API REST — Appelez
GET /signer/{signerId}/component-token/avec votre clé API.
Les deux retournent le token et sessionId nécessaires au composant. Voir Autorisation du widget pour le flux complet de jeton côté serveur.
Option 1 : GraphQL (Node.js)
Utilisation de recipientId (le plus courant — utilisez quand vous connaissez le destinataire mais n’avez pas encore de 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;
Sinon, si vous avez déjà un sessionId d’un appel précédent :
variables: {
input: {
component: 'LS_SIGNER',
signer: { sessionId: '<session-id>' }
}
}
Option 2 : API REST
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();
Passez token en tant que private-key et sessionId en tant que session-id au composant.
Attributs requis
| Attribut | Type | Description |
|---|---|---|
recipient-id | string | Identifiant du destinataire (base64, préfixe rec, ou UUID) |
private-key | string | Jeton retourné par generateComponentToken |
session-id | string | Identifiant de session retourné par generateComponentToken |
Attributs optionnels
| Attribut | Type | Par défaut | Description |
|---|---|---|---|
colour | string | blue | Nom de la couleur du thème (voir Thématisation) |
style | string | `` | Modifications de style (voir CSS personnalisé) |
branding | boolean | true | Afficher la marque Legalesign. Mettez à false pour la retirer. |
language | string | — | Forcer une langue spécifique et masquer le sélecteur de langue (voir Internationalisation) |
Événements
| Prop React | Événement composant web | eventType | Quand |
|---|---|---|---|
onSuccess | signingSuccess | "success" | Document signé avec succès |
onFail | signingFail | "failure" | Échec de signature du document, rejeté, expiré, annulé, supprimé, retiré ou déjà signé ailleurs |
onChange | fieldChange | "ready" | Document et images entièrement chargés |
onChange | fieldChange | "save" | Une valeur de champ a été sauvegardée |
onChange | fieldChange | "select" | Un champ a été sélectionné ou focusé |
onSuccess / signingSuccess
Déclenché lorsque le destinataire signe avec succès le document.
{
eventType: 'success';
documentId: string; // UUID of the signed document
recipientId: string; // UUID of the recipient
}
React :
<LsSigner
onSuccess={({ eventType, documentId, recipientId }) => {
console.log(eventType); // "success"
console.log(documentId);
console.log(recipientId);
}}
/>
Composant web :
signer.addEventListener('signingSuccess', (e) => {
console.log(e.detail.eventType); // "success"
console.log(e.detail.documentId);
console.log(e.detail.recipientId);
});
onFail / signingFail
Déclenché en cas d’échec de la signature — soit à cause d’un rejet du document, soit d’une erreur lors du processus de signature (ex. erreur réseau, session expirée, conflit d’état du document).
{
eventType: 'failure';
failureReason: FailureReason;
error: string; // Human-readable error message
documentId?: string; // UUID of the document (if available)
recipientId: string; // UUID of the recipient
}
failureReason | Cause |
|---|---|
documentExpired | L'état du document est "expired" ou la date d'expiration est passée |
sessionExpired | L’API a renvoyé 401 ou 403 lors du chargement du document |
cancelled | L'état du document est "cancelled" |
deleted | Le flag is_deleted du document est true |
rejected | Le destinataire a rejeté le document (is_rejected est true) |
removed | L’API a renvoyé 404 — le document n’existe plus |
documentCompleted | L’API de signature a renvoyé completed — le document a déjà été signé, probablement dans un autre navigateur ou appareil. Le composant affiche un message d’information au lieu d’une erreur. |
signingError | Toute autre erreur durant le chargement ou la signature |
React :
<LsSigner
onFail={({ eventType, failureReason, error, documentId, recipientId }) => {
console.log(eventType); // "failure"
console.log(failureReason); // e.g. "documentExpired"
console.log(error);
}}
/>
Composant web :
signer.addEventListener('signingFail', (e) => {
console.log(e.detail.eventType); // "failure"
console.log(e.detail.failureReason); // e.g. "documentExpired"
console.log(e.detail.error);
});
onChange / fieldChange
Les trois valeurs eventType partagent le même événement. Utilisez eventType pour faire la différence.
eventType: "ready"
Déclenché une fois que le document et toutes les images des pages sont entièrement chargés et que l’interface de signature est prête à l’interaction.
{
eventType: 'ready';
document: {
documentId: string; // UUID of the document
name: string; // Document name
state: string; // Document state (e.g. "signing")
recipientId: string; // UUID of the recipient
recipientRole?: string; // Role of the recipient (e.g. "witness")
pageCount: number; // Number of pages
expires?: string; // Expiry date (ISO string, if set)
isApprover: boolean; // Whether the recipient is an approver
isWitness: boolean; // Whether the recipient is a witness
canReassign: boolean; // Whether the recipient can reassign
doOfferReject: boolean; // Whether the reject option is shown
};
}
React :
<LsSigner
onChange={({ eventType, document }) => {
if (eventType === 'ready') {
console.log('Ready to sign:', document.documentId, document.name);
console.log('Pages:', document.pageCount);
console.log('Expires:', document.expires);
}
}}
/>
Composant web :
signer.addEventListener('fieldChange', (e) => {
if (e.detail.eventType === 'ready') {
console.log('Ready to sign:', e.detail.document.documentId, e.detail.document.name);
}
});
eventType: "save"
Déclenché après qu’une valeur de champ a été sauvegardée sur le serveur.
{
eventType: 'save';
uuid: string; // UUID of the field
saved: boolean; // Whether the save was successful
field: Record<string, any>; // Full field object (see Field Properties below)
}
React :
<LsSigner
onChange={({ eventType, uuid, saved, field }) => {
if (eventType === 'save') {
console.log(uuid, saved, field.value);
}
}}
/>
Composant web :
signer.addEventListener('fieldChange', (e) => {
if (e.detail.eventType === 'save') {
console.log(e.detail.uuid, e.detail.saved, e.detail.field.value);
}
});
eventType: "select"
Déclenché lorsqu’un champ est sélectionné ou a le focus – provoqué par un clic utilisateur, navigation clavier, avance automatique ou interaction avec la barre latérale.
{
eventType: 'select';
uuid: string; // UUID of the selected field
field: Record<string, any>; // Full field object (see Field Properties below)
}
React :
<LsSigner
onChange={({ eventType, uuid, field }) => {
if (eventType === 'select') {
console.log('selected', uuid, field.fieldtype);
}
}}
/>
Composant web :
signer.addEventListener('fieldChange', (e) => {
if (e.detail.eventType === 'select') {
console.log('selected', e.detail.uuid, e.detail.field.fieldtype);
}
});
Propriétés des champs
L’objet field inclus dans les événements save et select contient les propriétés suivantes :
| Propriété | Type | Description |
|---|---|---|
uuid | string | Identifiant unique du champ |
fieldtype | string | Type de champ (ex. "text", "signature", "date", "checkbox") |
value | string | Valeur actuelle du champ |
state | boolean | Si le champ a été sauvegardé avec succès |
optional | boolean | Si le champ est optionnel |
page | number | Numéro de page où se trouve le champ |
label | string | Libellé du champ (si défini) |
validation | number | Code du type de validation |
logicaction | string | Type d’action logique ("1" = radio, "2" = somme, "3" = conditionnelle) |
logicgroup | string | Identifiant du groupe logique |
mapto | string | Groupe cible pour la logique (champs contrôleurs) |
auto | boolean | Si le champ est auto-rempli |
dirty | boolean | Si le champ a des modifications locales non sauvegardées |
Props React
Le composant React utilise des props en camelCase et des callback props au lieu d’événements DOM :
| Prop | Type | Obligatoire | Description |
|---|---|---|---|
recipientId | string | ✅ | Identifiant du destinataire |
privateKey | string | ✅ | Clé privée issue de la mutation generateComponentToken |
sessionId | string | ✅ | Identifiant de session |
colour | LsSignerColour | ❌ | Couleur du thème |
branding | boolean | ❌ | Afficher la marque Legalesign. Par défaut true. |
language | string | ❌ | Forcer une langue spécifique (voir Internationalisation) |
onSuccess | (data: { eventType: 'success'; documentId: string; recipientId: string }) => void | ❌ | Appelé lors d’une signature réussie |
onFail | (data: { eventType: 'failure'; failureReason: FailureReason; error: string; documentId?: string; recipientId: string }) => void | ❌ | Appelé en cas d’échec de la signature |
onChange | (data: { eventType: 'ready' | 'save' | 'select'; document?: DocumentSummary; uuid?: string; saved?: boolean; field?: Record<string, any> }) => void | ❌ | Appelé lors d’événements sur champs et document prêt |
Gestionnaire global (debug & prototypage)
Chaque événement incluant eventType, vous pouvez connecter une seule fonction à tous les événements :
React :
const handleSignerEvent = (e) => {
switch (e.eventType) {
case 'success': console.log('Signed:', e.documentId); break;
case 'failure': console.log('Failed:', e.failureReason, e.error); break;
case 'ready': console.log('Ready:', e.document?.name); break;
case 'save': console.log('Saved field:', e.uuid, e.saved); break;
case 'select': console.log('Selected field:', e.uuid); break;
}
};
<LsSigner
onSuccess={handleSignerEvent}
onFail={handleSignerEvent}
onChange={handleSignerEvent}
/>
Composant web :
const handleSignerEvent = (e) => {
switch (e.detail.eventType) {
case 'success': console.log('Signed:', e.detail.documentId); break;
case 'failure': console.log('Failed:', e.detail.failureReason, e.detail.error); break;
case 'ready': console.log('Ready:', e.detail.document?.name); break;
case 'save': console.log('Saved field:', e.detail.uuid, e.detail.saved); break;
case 'select': console.log('Selected field:', e.detail.uuid); break;
}
};
signer.addEventListener('signingSuccess', handleSignerEvent);
signer.addEventListener('signingFail', handleSignerEvent);
signer.addEventListener('fieldChange', handleSignerEvent);
Thématisation
Définissez un thème de couleur avec la prop colour. Toutes les nuances sont générées automatiquement.
Couleurs disponibles
pink · blue · purple · indigo · teal · green · lightblue · burnt · aubergine · red · yellow · cyan · lime · trueGreen
Omettez la prop pour la couleur bleue par défaut.
<ls-signer colour="pink" ...></ls-signer>
<LsSigner colour="pink" ... />
La prop colour définit un attribut data-ls-theme sur la racine du composant. Les propriétés CSS personnalisées définissent une échelle de nuances de 10 à 100 pour chaque couleur :
| Nuance | Utilisation |
|---|---|
| 10 | Fonds clairs, remplissages subtils |
| 20 | Bordures subtiles |
| 30 | Anneaux de focus |
| 60 | Couleur principale (boutons, liens, états actifs) |
| 70 | État au survol |
| 80 | Accents foncés/forts |
CSS personnalisé
Le composant expose des propriétés CSS personnalisées qui peuvent être surchargées pour personnaliser l’apparence au-delà du thème de couleur. Ce jeu de propriétés est limité pour l’instant, contactez-nous pour plus d’informations.
<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>
Propriétés disponibles
| Propriété | Par défaut | Description |
|---|---|---|
--ls-font-family | 'IBM Plex Sans', sans-serif | Police principale |
--ls-color-primary-10 à --ls-color-primary-100 | — | Échelle complète des couleurs principales (remplace le thème) |
--ls-color-error | #f64a44 | Couleur d’état erreur |
--ls-color-error-light | #fff0f0 | Fond d’erreur |
--ls-color-success | #46dbaa | Couleur d’état réussite |
--ls-color-success-light | #effff9 | Fond de réussite |
--ls-color-warning | #fad232 | Couleur d’état avertissement |
--ls-color-warning-light | #fffcef | Fond d’avertissement |
--ls-color-border | #d8d9dc | Couleur de bordure par défaut |
--ls-color-border-subtle | #e0e2e5 | Couleur de bordure subtile |
--ls-color-bg-subtle | #f7f8fa | Couleur de fond subtile |
Note : Pour une injection complète de CSS personnalisé (ciblant directement les éléments internes, surchargeant tailles de police, rayons de bordure, espacements, etc.), c’est une fonctionnalité prévue pour l’avenir. Merci de nous contacter si vous êtes intéressé.
Internationalisation
Le composant supporte 17 langues avec les traductions intégrées dans la compilation. La langue est détectée automatiquement depuis le navigateur. Un sélecteur de langue intégré dans l’interface de signature permet au destinataire de changer la langue à tout moment.
Définissez l’attribut language pour forcer une langue spécifique. Si cette prop est fournie, le sélecteur de langue interne est masqué et la détection du navigateur est ignorée.
<ls-signer language="fr" recipient-id="abc123" private-key="key" session-id="session"></ls-signer>
<LsSigner language="fr" recipientId="abc123" privateKey="key" sessionId="session" />
Ordre de priorité : prop language → langue du navigateur → anglais par défaut.
| Code | Langue | Code | Langue |
|---|---|---|---|
en | Anglais | nl | Néerlandais |
fr | Français | fi | Finnois |
bg | Bulgare | it | Italien |
es | Espagnol | he | Hébreu |
de | Allemand | sv | Suédois |
gs | Gaélique écossais | cy | Gallois |
ar | Arabe | is | Islandais |
el | Grec | iw | Hébreu (legacy) |
pt | Portugais | ||
ro | Roumain |
Versionnage CDN
L’URL du CDN accepte à la fois latest et des numéros de version figés :
<!-- Always get the most recent version (recommended) -->
<script type="module" src="https://cdn.legalesign.io/signer/latest/ls-signer.esm.js"></script>
<!-- Pin to a specific version -->
<script type="module" src="https://cdn.legalesign.io/signer/v1.1.7/ls-signer.esm.js"></script>
Nous recommandons d’utiliser latest — cela garantit que votre intégration reçoit automatiquement les correctifs de bugs, mises à jour de sécurité et nouvelles fonctionnalités. Utilisez une version figée si vous devez verrouiller une version stable lors d’un gel QA ou déploiement contrôlé. Voir l’historique complet des versions sur npm pour les versions disponibles.
Exemple complet
<!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.failureReason, event.detail.error);
});
signer.addEventListener('fieldChange', (event) => {
if (event.detail.eventType === 'ready') {
console.log('Ready to sign:', event.detail.document.name);
}
});
</script>
</body>
</html>
Support des navigateurs
- Chrome/Edge (dernière version)
- Firefox (dernière version)
- Safari (dernière version)
- Navigateurs mobiles (iOS Safari, Chrome Mobile)
Journal des modifications
| Version | Date | Résumé |
|---|---|---|
| v1.1.7 | 20 oct. 2026 | Raison échec documentCompleted ; améliorations sauvegarde champs ; corrections de positionnement ; meilleure capture des échecs |
| v1.1.0 | 22 juil. 2026 | Événement onChange / fieldChange ; prop language ; champs conditionnels ; saut automatique ; QES |
| v1.0.12 | 20 juil. 2026 | Événement onChange / fieldChange avec ready, save, select ; valeurs de failureReason ; validation regex |
| v1.0.11 | 15 juil. 2026 | Prop language ; champs conditionnels, dropdown, checkbox ; entrée téléphone ; ordre des champs |
| v1.0.6 | 9 juin 2026 | Prop branding ajoutée |
| v1.0.3 | 15 mai 2026 | Prop colour ; propriétés CSS personnalisées ; corrections de bugs |
| v1.0.0 | 11 mai 2026 | Première version stable |
Ressources
- Paquet NPM
- Autorisation des widgets
- Documentation API GraphQL
- Migration depuis la signature iframe
- Support