Integra il Signer Legalesign nel tuo sito web
Il componente Signer richiede l’attivazione. Contatta il supporto per abilitarlo al tuo team.
Il Signer Legalesign è un componente web indipendente dalla piattaforma che offre un'esperienza completa e fluida di firma di documenti direttamente 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, un portale clienti o qualsiasi applicazione interna che renda HTML.
Installazione
Caricalo 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 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>
Se usi Vue con Vite, aggiungi isCustomElement: (tag) => tag.startsWith('ls-') alla configurazione del plugin Vue per sopprimere i warning sugli elementi sconosciuti.
Vue 3 trasforma in minuscolo i nomi degli eventi sugli elementi personalizzati, quindi @signingSuccess non funzionerà. Usa addEventListener sul riferimento all'elemento come mostrato sopra.
Racchiudi <ls-signer> in <ClientOnly> per evitare errori SSR. Aggiungi la configurazione per l’elemento personalizzato in nuxt.config.ts:
export default defineNuxtConfig({
vue: {
compilerOptions: {
isCustomElement: (tag) => tag.startsWith('ls-'),
},
},
});
Autenticazione
Il componente signer richiede un token a breve durata proveniente dal tuo backend. Ci sono due opzioni:
- GraphQL
generateComponentToken— Chiamare concomponent: LS_SIGNERe o unrecipientIdo unsessionIdnell’ambito signer (fornire uno solo, non entrambi). - REST API — Chiamare
GET /signer/{signerId}/component-token/con la tua API key.
Entrambi restituiscono il token e il sessionId necessari al componente. Vedi Autorizzazione Widget per il flusso token completo lato server.
Opzione 1: GraphQL (Node.js)
Usando recipientId (il più comune — usare 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 precedente chiamata:
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 Richiesti
| Attributo | Tipo | Descrizione |
|---|---|---|
recipient-id | string | Identificativo destinatario (base64, prefisso rec, o UUID) |
private-key | string | Token restituito da generateComponentToken |
session-id | string | ID sessione restituito da generateComponentToken |
Attributi Opzionali
| Attributo | Tipo | Default | Descrizione |
|---|---|---|---|
colour | string | blue | Nome del colore tema (vedi Tematizzazione) |
style | string | `` | Modifiche allo stile (vedi CSS Personalizzato) |
branding | boolean | true | Rimuove il branding Legalesign |
language | string | — | Forza una lingua specifica e nasconde il selettore lingua (vedi Internazionalizzazione) |
Eventi
| Evento web component | Prop React | eventType | Quando |
|---|---|---|---|
signingSuccess | onSuccess | "success" | Documento firmato con successo |
signingFail | onFail | "failure" | Firma fallita, rifiutata, scaduta, annullata, eliminata o rimossa |
fieldChange | onChange | "ready" | Documento e immagini completamente caricati |
fieldChange | onChange | "save" | Un valore di campo è stato salvato |
fieldChange | onChange | "select" | Un campo è stato selezionato o ha ricevuto focus |
signingSuccess / onSuccess
{
eventType: 'success';
documentId: string;
recipientId: string;
}
signingFail / onFail
{
eventType: 'failure';
failureReason: FailureReason;
error: string;
documentId?: string;
recipientId: string;
}
failureReason | Causa |
|---|---|
documentExpired | Il documento è scaduto o la data di scadenza è nel passato |
sessionExpired | API ha restituito 401 o 403 |
cancelled | Stato del documento è "cancelled" |
deleted | Il documento è stato eliminato |
rejected | Il destinatario ha rifiutato il documento |
removed | API ha restituito 404 |
signingError | Qualsiasi altro errore durante caricamento o firma |
fieldChange / onChange
Tutti e tre i valori eventType condividono lo stesso evento. Usa eventType per distinguerli:
// eventType: 'ready' — document fully loaded
{ eventType: 'ready'; document: { documentId, name, state, recipientId, pageCount, expires?, isApprover, isWitness, canReassign, doOfferReject } }
// eventType: 'save' — field value saved
{ eventType: 'save'; uuid: string; saved: boolean; field: Record<string, any> }
// eventType: 'select' — field selected or focused
{ eventType: 'select'; uuid: string; field: Record<string, any> }
Props React
Il componente React utilizza props in camelCase e callback props invece di eventi DOM:
| Prop | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
recipientId | string | ✅ | Identificatore destinatario |
privateKey | string | ✅ | Chiave privata dalla mutazione generateComponentToken |
sessionId | string | ✅ | Identificatore sessione |
colour | LsSignerColour | ❌ | Colore tema |
branding | boolean | ❌ | Mostra branding Legalesign. Default true. |
language | string | ❌ | Forza una lingua specifica (vedi Internazionalizzazione) |
onSuccess | (data: { eventType: 'success'; documentId: string; recipientId: string }) => void | ❌ | Chiamato in caso di firma riuscita |
onFail | (data: { eventType: 'failure'; failureReason: FailureReason; error: string; documentId?: string; recipientId: string }) => void | ❌ | Chiamato in caso di fallimento della firma |
onChange | (data: { eventType: 'ready' | 'save' | 'select'; document?: DocumentSummary; uuid?: string; saved?: boolean; field?: Record<string, any> }) => void | ❌ | Chiamato sugli eventi di campo e quando il documento è pronto |
Handler universale (debugging & prototipazione)
Poiché ogni evento include eventType, puoi associare 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);
Tematizzazione
Imposta un tema colore con la prop colour. Tutte le sfumature 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 di default.
<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 sfumature da 10 a 100 per ogni colore:
| Sfumatura | Uso |
|---|---|
| 10 | Sfondo chiaro, riempimenti discreti |
| 20 | Bordi sottili |
| 30 | Anelli di focus |
| 60 | Colore primario (pulsanti, link, stati attivi) |
| 70 | Stato hover |
| 80 | Accenti scuri/forti |
CSS Personalizzato
Il componente espone proprietà CSS personalizzate che possono essere sovrascritte per personalizzare l'aspetto oltre il tema colore. Questa serie di proprietà è al momento limitata, 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à | Predefinito | Descrizione |
|---|---|---|
--ls-font-family | 'IBM Plex Sans', sans-serif | Famiglia di caratteri principale |
--ls-color-primary-10 a --ls-color-primary-100 | — | Scala completa del colore primario (sovrascrive il tema) |
--ls-color-error | #f64a44 | Colore stato errore |
--ls-color-error-light | #fff0f0 | Sfondo errore |
--ls-color-success | #46dbaa | Colore stato successo |
--ls-color-success-light | #effff9 | Sfondo successo |
--ls-color-warning | #fad232 | Colore stato avviso |
--ls-color-warning-light | #fffcef | Sfondo avviso |
--ls-color-border | #d8d9dc | Colore bordo predefinito |
--ls-color-border-subtle | #e0e2e5 | Colore bordo sottile |
--ls-color-bg-subtle | #f7f8fa | Colore sfondo sottile |
Nota: Per l'iniezione completa di CSS personalizzato (mirata agli elementi interni direttamente, sovrascrivendo dimensioni font, border-radius, spaziature, ecc.) è una funzionalità pianificata per il futuro. Per favore contattaci se interessato.
Internazionalizzazione
Il componente supporta 17 lingue con traduzioni incluse nel build. La lingua è rilevata automaticamente dal browser. Un selettore lingua integrato nell’UI di firma permette al destinatario di cambiare lingua in qualsiasi momento.
Imposta l’attributo language per forzare una lingua specifica. Se fornito, il selettore lingua integrato è nascosto e il rilevamento browser viene ignorato.
<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 → fallback inglese.
| Codice | Lingua | Codice | Lingua |
|---|---|---|---|
en | Inglese | nl | Olandese |
fr | Francese | fi | Finlandese |
bg | Bulgaro | it | Italiano |
es | Spagnolo | he | Ebraico |
de | Tedesco | sv | Svedese |
gs | Gaelico scozzese | cy | Gallese |
ar | Arabo | is | Islandese |
el | Greco | iw | Ebraico (legacy) |
pt | Portoghese | ||
ro | Rumeno |
Versionamento CDN
L’URL CDN supporta sia latest che versioni specifiche appuntate:
<!-- 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.0/ls-signer.esm.js"></script>
Consigliamo l’uso di latest — ciò garantisce che la tua integrazione riceva automaticamente correzioni di bug, patch di sicurezza e nuove funzionalità. Usa una versione appuntata se devi bloccare una release nota durante un freeze QA o rollout controllato. Consulta la cronologia 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 (ultima versione)
- Firefox (ultima versione)
- Safari (ultima versione)
- Browser mobili (iOS Safari, Chrome Mobile)
Risorse
- Pacchetto NPM
- Autorizzazione Widget
- Documentazione API GraphQL
- Migrazione dalla firma iframe
- Supporto