Vai al contenuto principale

Integra il Signer Legalesign nel tuo sito web

Attiva per il tuo team

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

Se usi Vue con Vite, aggiungi isCustomElement: (tag) => tag.startsWith('ls-') alla configurazione del plugin Vue per sopprimere i warning sugli elementi sconosciuti.

avvertimento

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.

Nuxt 3

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:

  1. GraphQL generateComponentToken — Chiamare con component: LS_SIGNER e o un recipientId o un sessionId nell’ambito signer (fornire uno solo, 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. 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

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

Attributi Opzionali

AttributoTipoDefaultDescrizione
colourstringblueNome del colore tema (vedi Tematizzazione)
stylestring``Modifiche allo stile (vedi CSS Personalizzato)
brandingbooleantrueRimuove il branding Legalesign
languagestringForza una lingua specifica e nasconde il selettore lingua (vedi Internazionalizzazione)

Eventi

Evento web componentProp ReacteventTypeQuando
signingSuccessonSuccess"success"Documento firmato con successo
signingFailonFail"failure"Firma fallita, rifiutata, scaduta, annullata, eliminata o rimossa
fieldChangeonChange"ready"Documento e immagini completamente caricati
fieldChangeonChange"save"Un valore di campo è stato salvato
fieldChangeonChange"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;
}
failureReasonCausa
documentExpiredIl documento è scaduto o la data di scadenza è nel passato
sessionExpiredAPI ha restituito 401 o 403
cancelledStato del documento è "cancelled"
deletedIl documento è stato eliminato
rejectedIl destinatario ha rifiutato il documento
removedAPI ha restituito 404
signingErrorQualsiasi 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:

PropTipoObbligatorioDescrizione
recipientIdstringIdentificatore destinatario
privateKeystringChiave privata dalla mutazione generateComponentToken
sessionIdstringIdentificatore sessione
colourLsSignerColourColore tema
brandingbooleanMostra branding Legalesign. Default true.
languagestringForza una lingua specifica (vedi Internazionalizzazione)
onSuccess(data: { eventType: 'success'; documentId: string; recipientId: string }) => voidChiamato in caso di firma riuscita
onFail(data: { eventType: 'failure'; failureReason: FailureReason; error: string; documentId?: string; recipientId: string }) => voidChiamato in caso di fallimento della firma
onChange(data: { eventType: 'ready' | 'save' | 'select'; document?: DocumentSummary; uuid?: string; saved?: boolean; field?: Record<string, any> }) => voidChiamato 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:

SfumaturaUso
10Sfondo chiaro, riempimenti discreti
20Bordi sottili
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. 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àPredefinitoDescrizione
--ls-font-family'IBM Plex Sans', sans-serifFamiglia di caratteri principale
--ls-color-primary-10 a --ls-color-primary-100Scala 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 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.

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

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

Video: Migrazione da iframe al componente Signer