Saltar al contenido principal

Integra el componente Legalesign Signer en tu sitio web

Habilitar para tu equipo

El componente Signer requiere activación. Contacta con soporte para habilitarlo para tu equipo.

El Legalesign Signer es un componente web agnóstico de plataforma que proporciona una experiencia completa y fluida de firma de documentos desde tu propia aplicación. Funciona con HTML vanilla, React, Vue, Angular o cualquier framework web.

Inserta este componente donde tus usuarios necesiten firmar documentos: dentro de un CRM, portal de clientes o cualquier aplicación interna que renderice HTML.

Instalación​

Carga directamente desde el CDN (no requiere instalación):

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

Instalación en React​

Instala mediante un gestor de paquetes:

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

Integración básica​

HTML y 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 requiere react y react-dom (v18 o v19) como dependencias 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>
sugerencia

Si usas Vue con Vite, añade isCustomElement: (tag) => tag.startsWith('ls-') a la configuración del plugin Vue para suprimir las advertencias de elementos desconocidos.

aviso

Vue 3 convierte a minúsculas los nombres de eventos en elementos personalizados, por lo que @signingSuccess no funcionará. Usa addEventListener en la referencia del elemento como se muestra arriba.

Nuxt 3

Envuelve <ls-signer> en <ClientOnly> para evitar errores SSR. Añade la configuración de elementos personalizados en nuxt.config.ts:

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

Autenticación​

El componente signer requiere un token de corta duración desde tu backend. Hay dos opciones:

  1. GraphQL generateComponentToken — Llama con component: LS_SIGNER y ya sea un recipientId o sessionId en el scope del signer (proporciona uno, no ambos).
  2. REST API — Llama a GET /signer/{signerId}/component-token/ con tu clave API.

Ambos retornan el token y sessionId que el componente necesita. Consulta Widget Authorization para el flujo completo del token del lado servidor.

Opción 1: GraphQL (Node.js)​

Usando recipientId (más común — usar cuando conoces al destinatario pero aún no tienes sesión):

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;

Alternativamente, si ya tienes un sessionId de una llamada previa:

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

Opción 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();

Pasa token como private-key y sessionId como session-id al componente.

Atributos requeridos​

AtributoTipoDescripción
recipient-idstringIdentificador del destinatario (base64, prefijo rec o UUID)
private-keystringToken retornado por generateComponentToken
session-idstringID de sesión retornado por generateComponentToken

Atributos opcionales​

AtributoTipoPredeterminadoDescripción
colourstringblueNombre del color del tema (ver Theming)
stylestring``Alteraciones de estilo (ver Customer CSS)
brandingbooleantrueRemover la marca Legalesign
languagestring—Forzar un idioma específico y ocultar el selector de idioma (ver Internationalisation)

Eventos​

Evento componente webPropiedad ReacteventTypeCuándo
signingSuccessonSuccess"success"Documento firmado con éxito
signingFailonFail"failure"Firma fallida, rechazada, expirada, cancelada, eliminada o removida
fieldChangeonChange"ready"Documento e imágenes cargadas completamente
fieldChangeonChange"save"Se guardó un valor de campo
fieldChangeonChange"select"Se seleccionó o enfocó un campo

signingSuccess / onSuccess​

{
eventType: 'success';
documentId: string;
recipientId: string;
}

signingFail / onFail​

{
eventType: 'failure';
failureReason: FailureReason;
error: string;
documentId?: string;
recipientId: string;
}
failureReasonCausa
documentExpiredDocumento expirado o fecha de expiración pasada
sessionExpiredAPI devolvió 401 o 403
cancelledEstado del documento es "cancelled"
deletedDocumento ha sido eliminado
rejectedDestinatario rechazó el documento
removedAPI devolvió 404
signingErrorCualquier otro error durante la carga o firma

fieldChange / onChange​

Los tres valores eventType comparten el mismo evento. Usa eventType para distinguir:

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

Propiedades React​

El componente React usa props en camelCase y callbacks en lugar de eventos DOM:

PropTipoRequeridoDescripción
recipientIdstring✅Identificador del destinatario
privateKeystring✅Clave privada del mutation generateComponentToken
sessionIdstring✅Identificador de sesión
colourLsSignerColour❌Color del tema
brandingboolean❌Mostrar marca Legalesign. Por defecto true.
languagestring❌Forzar un idioma específico (ver Internationalisation)
onSuccess(data: { eventType: 'success'; documentId: string; recipientId: string }) => void❌Llamado tras firma exitosa
onFail(data: { eventType: 'failure'; failureReason: FailureReason; error: string; documentId?: string; recipientId: string }) => void❌Llamado tras fallo en la firma
onChange(data: { eventType: 'ready' | 'save' | 'select'; document?: DocumentSummary; uuid?: string; saved?: boolean; field?: Record<string, any> }) => void❌Llamado en eventos de campos y carga del documento

Manejo global (depuración y prototipado)​

Como cada evento incluye eventType, puedes enlazar una única función a todos los eventos:

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

Tematización​

Define un tema de color con la prop colour. Todos los tonos se derivan automáticamente.

Colores disponibles​

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

Omitir la prop para el azul por defecto.

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

La prop colour establece un atributo data-ls-theme en la raíz del componente. Las propiedades CSS personalizadas definen una escala de tonos de 10 a 100 para cada color:

TonoUso
10Fondos claros, rellenos sutiles
20Bordes sutiles
30Anillos de enfoque
60Color primario (botones, enlaces, estados activos)
70Estado hover
80Acentos oscuros/fuertes

CSS personalizado​

El componente expone propiedades CSS personalizadas que pueden ser sobrescritas para personalizar la apariencia más allá del tema de color. Este conjunto de propiedades es limitado actualmente, contáctanos para más detalles.

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

Propiedades disponibles​

PropiedadValor predeterminadoDescripción
--ls-font-family'IBM Plex Sans', sans-serifFamilia de fuente principal
--ls-color-primary-10 a --ls-color-primary-100—Escala completa del color primario (sobrescribe el tema)
--ls-color-error#f64a44Color para estado de error
--ls-color-error-light#fff0f0Fondo para error
--ls-color-success#46dbaaColor para estado de éxito
--ls-color-success-light#effff9Fondo para éxito
--ls-color-warning#fad232Color para estado de advertencia
--ls-color-warning-light#fffcefFondo para advertencia
--ls-color-border#d8d9dcColor de borde por defecto
--ls-color-border-subtle#e0e2e5Color de borde sutil
--ls-color-bg-subtle#f7f8faColor de fondo sutil

Nota: Para inyección completa de CSS personalizado (dirigido a elementos internos directamente, sobrescribir tamaños de fuente, radio de bordes, espaciados, etc.), esta es una función planeada a futuro. Por favor contáctanos si estás interesado.

Internacionalización​

El componente soporta 17 idiomas con traducciones incluidas en el build. El idioma se detecta automáticamente desde el navegador. Un selector de idioma integrado en la UI de firma permite al destinatario cambiar el idioma en cualquier momento.

Establece el atributo language para forzar un idioma específico. Cuando se proporciona, el selector integrado se oculta y se ignora la detección del navegador.

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

Orden de prioridad: prop language → idioma del navegador → inglés por defecto.

CódigoIdiomaCódigoIdioma
enInglésnlNeerlandés
frFrancésfiFinés
bgBúlgaroitItaliano
esEspañolheHebreo
deAlemánsvSueco
gsGaélico escocéscyGalés
arÁrabeisIslandés
elGriegoiwHebreo (legado)
ptPortugués
roRumano

Versionado CDN​

La URL del CDN soporta tanto latest como números de versión fijos:

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

Recomendamos usar latest — esto asegura que tu integración reciba automáticamente correcciones de errores, parches de seguridad y nuevas funcionalidades. Usa una versión fija si necesitas bloquear una versión conocida durante una congelación de QA o despliegue controlado. Consulta el historial completo de versiones en npm para versiones disponibles.

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

Soporte de navegadores​

  • Chrome/Edge (últimas versiones)
  • Firefox (últimas versiones)
  • Safari (últimas versiones)
  • Navegadores móviles (iOS Safari, Chrome Mobile)

Recursos​

Vídeo: Migrar de iframe al componente Signer​