Vai al contenuto principale

Integrare il Signer di Legalesign nel tuo sito web

Abilita per il tuo team

Il componente Signer richiede l'attivazione. Contatta il supporto per abilitarlo per il tuo team.

Versione corrente: v1.1.7 — changelog

Il Legalesign Signer è un componente web indipendente dalla piattaforma che offre un'esperienza completa e senza interruzioni per la firma dei documenti all'interno della tua app. Funziona con HTML vanilla, React, Vue, Angular o qualsiasi framework web.

Incorpora questo componente ovunque i tuoi utenti debbano firmare documenti — all'interno di un CRM, di un portale clienti o di qualsiasi applicazione interna che renderizza HTML.

Installazione​

Carica direttamente dal CDN (nessuna installazione richiesta):

<script type="module" src="https://cdn.legalesign.io/signer/latest/ls-signer.esm.js"></script>

Installazione React​

Installa tramite un package manager:

npm install legalesign-signer
# or
pnpm add legalesign-signer

Integrazione base​

HTML e 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 richiede react e react-dom (v18 o v19) come dipendenze peer.

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>
suggerimento

Se usi Vue con Vite, aggiungi isCustomElement: (tag) => tag.startsWith('ls-') nella configurazione del plugin Vue per sopprimere gli avvisi di elementi sconosciuti.

avvertimento

Vue 3 trasforma in minuscolo i nomi degli eventi sugli elementi custom, quindi @signingSuccess non funzionerà. Usa addEventListener sul riferimento all'elemento come mostrato sopra.

Nuxt 3

Racchiudi <ls-signer> in <ClientOnly> per evitare errori SSR. Aggiungi la configurazione per l'elemento custom in nuxt.config.ts:

export default defineNuxtConfig({
vue: {
compilerOptions: {
isCustomElement: (tag) => tag.startsWith('ls-'),
},
},
});

Autenticazione​

Il componente signer richiede un token a breve termine dal tuo backend. Ci sono due opzioni:

  1. GraphQL generateComponentToken — Chiamare con component: LS_SIGNER e uno tra recipientId o sessionId nell'ambito del signer (fornire uno, non entrambi).
  2. REST API — Chiamare GET /signer/{signerId}/component-token/ con la tua API key.

Entrambi restituiscono il token e il sessionId necessari al componente. Consulta Widget Authorization per il flusso completo del token lato server.

Opzione 1: GraphQL (Node.js)​

Usando recipientId (il più comune — usalo quando conosci il destinatario ma non hai ancora una sessione):

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;

In alternativa, se hai già un sessionId da una chiamata precedente:

variables: {
input: {
component: 'LS_SIGNER',
signer: { sessionId: '<session-id>' }
}
}

Opzione 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();

Passa token come private-key e sessionId come session-id al componente.

Attributi obbligatori​

AttributoTipoDescrizione
recipient-idstringIdentificatore del destinatario (base64, prefisso rec, o UUID)
private-keystringToken restituito da generateComponentToken
session-idstringID sessione restituito da generateComponentToken

Attributi opzionali​

AttributoTipoPredefinitoDescrizione
colourstringblueNome del tema colore (vedi Theming)
stylestring``Modifiche di stile (vedi Customer CSS)
brandingbooleantrueMostra il branding Legalesign. Impostare su false per rimuoverlo.
languagestring—Forza una lingua specifica e nasconde il selettore di lingua (vedi Internazionalizzazione)

Eventi​

Prop ReactEvento componente webeventTypeQuando
onSuccesssigningSuccess"success"Documento firmato con successo
onFailsigningFail"failure"Firma del documento fallita, rifiutata, scaduta, cancellata, eliminata, rimossa o già completata altrove
onChangefieldChange"ready"Documento e immagini completamente caricate
onChangefieldChange"save"Un valore del campo è stato salvato
onChangefieldChange"select"Un campo è stato selezionato o ha ricevuto il focus

onSuccess / signingSuccess​

Attivato quando il destinatario firma correttamente il documento.

{
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);
}}
/>

Componente web:

signer.addEventListener('signingSuccess', (e) => {
console.log(e.detail.eventType); // "success"
console.log(e.detail.documentId);
console.log(e.detail.recipientId);
});

onFail / signingFail​

Attivato quando la firma fallisce — sia per rifiuto del documento sia per errore durante il processo di firma (es. errore di rete, sessione scaduta, conflitto di stato del documento).

{
eventType: 'failure';
failureReason: FailureReason;
error: string; // Human-readable error message
documentId?: string; // UUID of the document (if available)
recipientId: string; // UUID of the recipient
}
failureReasonCausa
documentExpiredStato del documento state è "expired" oppure la data expires è passata
sessionExpiredAPI ha restituito 401 o 403 durante il caricamento del documento
cancelledStato del documento state è "cancelled"
deletedFlag is_deleted del documento è true
rejectedIl destinatario ha rifiutato il documento (is_rejected è true)
removedAPI ha restituito 404 — il documento non esiste più
documentCompletedL'API di firma ha restituito completed — il documento era già firmato, probabilmente su un altro browser o dispositivo. Il componente mostra un messaggio informativo al destinatario invece di un errore.
signingErrorQualsiasi altro errore durante il caricamento o la firma

React:

<LsSigner
onFail={({ eventType, failureReason, error, documentId, recipientId }) => {
console.log(eventType); // "failure"
console.log(failureReason); // e.g. "documentExpired"
console.log(error);
}}
/>

Componente 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​

I tre valori di eventType condividono lo stesso evento. Usa eventType per distinguere.

eventType: "ready"​

Attivato una volta quando il documento e tutte le immagini delle pagine sono completamente caricate e l'interfaccia di firma è pronta per l'interazione.

{
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);
}
}}
/>

Componente 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"​

Attivato dopo che un valore di campo è stato salvato sul server.

{
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);
}
}}
/>

Componente web:

signer.addEventListener('fieldChange', (e) => {
if (e.detail.eventType === 'save') {
console.log(e.detail.uuid, e.detail.saved, e.detail.field.value);
}
});

eventType: "select"​

Attivato quando un campo viene selezionato o riceve il focus — scatenato da click utente, navigazione da tastiera, auto-inoltro o interazione con la sidebar.

{
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);
}
}}
/>

Componente web:

signer.addEventListener('fieldChange', (e) => {
if (e.detail.eventType === 'select') {
console.log('selected', e.detail.uuid, e.detail.field.fieldtype);
}
});

Proprietà del campo​

L'oggetto field incluso negli eventi save e select contiene le seguenti proprietà:

ProprietàTipoDescrizione
uuidstringIdentificatore unico del campo
fieldtypestringTipo di campo (es. "text", "signature", "date", "checkbox")
valuestringValore corrente del campo
statebooleanSe il campo è stato salvato con successo
optionalbooleanSe il campo è opzionale
pagenumberNumero della pagina su cui il campo appare
labelstringEtichetta del campo (se impostata)
validationnumberCodice tipo di validazione
logicactionstringTipo azione logica ("1" = radio, "2" = somma, "3" = condizionale)
logicgroupstringIdentificatore del gruppo logico
maptostringGruppo target per la logica (campi controller)
autobooleanSe il campo è auto-popolato
dirtybooleanSe il campo ha modifiche locali non salvate

Props React​

Il componente React usa props camelCase e callback invece di eventi DOM:

PropTipoObbligatorioDescrizione
recipientIdstring✅Identificatore del destinatario
privateKeystring✅Chiave privata dalla mutation generateComponentToken
sessionIdstring✅Identificatore della sessione
colourLsSignerColour❌Colore del tema
brandingboolean❌Mostra branding Legalesign. Default true.
languagestring❌Forza una lingua specifica (vedi Internazionalizzazione)
onSuccess(data: { eventType: 'success'; documentId: string; recipientId: string }) => void❌Chiamato al successo della firma
onFail(data: { eventType: 'failure'; failureReason: FailureReason; error: string; documentId?: string; recipientId: string }) => void❌Chiamato al fallimento della firma
onChange(data: { eventType: 'ready' | 'save' | 'select'; document?: DocumentSummary; uuid?: string; saved?: boolean; field?: Record<string, any> }) => void❌Chiamato per eventi di campo e al caricamento del documento

Gestore generico (debug & prototipazione)​

Poiché ogni evento include eventType, puoi collegare una singola funzione a tutti gli eventi:

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}
/>

Componente 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);

Theming​

Imposta il tema colore con la prop colour. Tutte le tonalità sono derivate automaticamente.

Colori disponibili​

pink · blue · purple · indigo · teal · green · lightblue · burnt · aubergine · red · yellow · cyan · lime · trueGreen

Ommetti la prop per il blu predefinito.

<ls-signer colour="pink" ...></ls-signer>
<LsSigner colour="pink" ... />

La prop colour imposta un attributo data-ls-theme sulla radice del componente. Le proprietà CSS personalizzate definiscono una scala di tonalità da 10 a 100 per ogni colore:

TonalitàUso
10Sfondo chiaro, riempimenti delicati
20Bordi delicati
30Anelli di focus
60Colore primario (pulsanti, link, stati attivi)
70Stato hover
80Accenti scuri/forti

CSS personalizzato​

Il componente espone proprietà CSS personalizzate che possono essere sovrascritte per personalizzare l'aspetto oltre il tema colore. Questo set di proprietà è attualmente limitato, contattaci per maggiori informazioni.

<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>

Proprietà disponibili​

ProprietàPredefinitoDescrizione
--ls-font-family'IBM Plex Sans', sans-serifFamiglia di font principale
--ls-color-primary-10 a --ls-color-primary-100—Scala completa del colore primario (sovrascrive il tema)
--ls-color-error#f64a44Colore stato errore
--ls-color-error-light#fff0f0Sfondo errore
--ls-color-success#46dbaaColore stato successo
--ls-color-success-light#effff9Sfondo successo
--ls-color-warning#fad232Colore stato avviso
--ls-color-warning-light#fffcefSfondo avviso
--ls-color-border#d8d9dcColore bordo predefinito
--ls-color-border-subtle#e0e2e5Colore bordo sottile
--ls-color-bg-subtle#f7f8faColore sfondo sottile

Nota: Per iniezione completa di CSS personalizzato (mirato agli elementi interni, sovrascrittura di dimensioni font, bordi arrotondati, spaziature, ecc.), è una funzionalità pianificata per il futuro. Per favore contattaci se sei interessato.

Internazionalizzazione​

Il componente supporta 17 lingue con traduzioni incluse nel build. La lingua viene rilevata automaticamente dal browser. Un selettore di lingua integrato nell’interfaccia di firma permette al destinatario di cambiare lingua in qualsiasi momento.

Imposta l'attributo language per forzare una lingua specifica. Quando è fornito, il selettore di lingua integrato viene nascosto e il rilevamento browser viene bypassato.

<ls-signer language="fr" recipient-id="abc123" private-key="key" session-id="session"></ls-signer>
<LsSigner language="fr" recipientId="abc123" privateKey="key" sessionId="session" />

Ordine di priorità: prop language → lingua browser → inglese di fallback.

CodiceLinguaCodiceLingua
enInglesenlOlandese
frFrancesefiFinlandese
bgBulgaroitItaliano
esSpagnoloheEbraico
deTedescosvSvedese
gsGaelico scozzesecyGallese
arAraboisIslandese
elGrecoiwEbraico (legacy)
ptPortoghese
roRomeno

Versionamento CDN​

L'URL CDN supporta sia latest che versioni bloccate:

<!-- 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>

Consigliamo di usare latest — così la tua integrazione riceve automaticamente fix di bug, patch di sicurezza e nuove funzionalità. Usa una versione bloccata se devi fissarti su una release conosciuta durante un freeze QA o un rollout controllato. Vedi la storia completa delle versioni su npm per le versioni disponibili.

Esempio completo​

<!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>

Supporto browser​

  • Chrome/Edge (ultime versioni)
  • Firefox (ultime versioni)
  • Safari (ultime versioni)
  • Browser mobile (iOS Safari, Chrome Mobile)

Changelog​

VersioneDataSommario
v1.1.720 Ott 2026Motivo documentCompleted; miglioramenti salvataggio campi; correzioni di posizionamento; migliorata cattura eventi failure
v1.1.022 Lug 2026Evento onChange / fieldChange; prop language; campi condizionali; salto automatico; QES
v1.0.1220 Lug 2026Evento onChange / fieldChange con ready, save, select; valori failureReason; validazione regex
v1.0.1115 Lug 2026Prop language; campi condizionali, dropdown, checkbox; input telefono; ordinamento campi
v1.0.69 Giu 2026Aggiunta prop branding
v1.0.315 Mag 2026Prop colour; proprietà CSS personalizzate; correzioni bug
v1.0.011 Mag 2026Prima release stabile

Risorse​

Video: Migrazione da iframe al componente Signer​