Skip to main content
The @sajn/embed package provides two ways to embed the signing experience: a function API and a Web Component.

Installation

npm

npm install @sajn/embed

CDN

For projects without a build step, use the UMD bundle:
<script src="https://unpkg.com/@sajn/embed/dist/index.umd.js"></script>
This exposes the sajn global object with all exports.

Function API

The embedSignDocument function creates an iframe and handles all communication with the embedded signing interface.

Import

import { embedSignDocument } from '@sajn/embed';
Or with CDN:
const { embedSignDocument } = sajn;

Options Interface

interface EmbedSignDocumentOptions {
  // Required
  element: HTMLElement | string;  // Target element or CSS selector
  documentId: string;             // Document ID
  token: string;                  // Signer token

  // Optional
  host?: string;                  // Default: 'https://app.sajn.se'
  language?: 'sv' | 'en' | 'no' | 'da' | 'fi' | 'de' | 'is' | 'es' | 'fr' | 'it';
  className?: string;             // CSS class for iframe
  cssVars?: CssVars & Record<string, string>;
  allowDocumentRejection?: boolean;
  showScrollIndicator?: boolean;  // Default: true
  additionalProps?: Record<string, string | number | boolean>;

  // Callbacks
  onDocumentReady?: () => void;
  onSignerCompleted?: (data: SignerCompletedData) => void;
  onSignerRejected?: (data: SignerRejectedData) => void;
  onDocumentError?: (data: { code: string; message: string }) => void;
}

Return Type

interface EmbedSignDocumentInstance {
  iframe: HTMLIFrameElement;  // The created iframe element
  destroy: () => void;        // Cleanup function
}

Example

import { embedSignDocument } from '@sajn/embed';

const instance = embedSignDocument({
  element: '#signing-container',
  documentId: 'doc_abc123',
  token: 'signer_token_xyz',
  cssVars: {
    primary: '#2563eb',
    background: '#ffffff',
  },
  allowDocumentRejection: true,
  onDocumentReady: () => {
    console.log('Signing interface loaded');
  },
  onSignerCompleted: (data) => {
    console.log('Document signed!', data);
    // Redirect or show success message
  },
  onSignerRejected: (data) => {
    console.log('Document rejected:', data.reason);
  },
  onDocumentError: (error) => {
    console.error('Error:', error.code, error.message);
  },
});

// Later: cleanup when done
instance.destroy();

Web Component

The package also exports a custom element <sajn-sign-document> that auto-registers when imported.

Import

import '@sajn/embed';
Or with CDN, the component is automatically registered.

Attributes

AttributeTypeRequiredDescription
document-idstringYesDocument ID
tokenstringYesSigner token
hoststringNoCustom host URL
languagestringNoUI language (sv, en, no, da, fi, de, is, es, fr, it)
class-namestringNoCSS class for iframe
allow-document-rejectionbooleanNoEnable rejection
show-scroll-indicatorbooleanNoShow scroll indicator (default: true)

Events

The Web Component dispatches standard CustomEvents that you can listen to:
EventDetail
document-readyundefined
signer-completedSignerCompletedData
signer-rejectedSignerRejectedData
document-errorDocumentErrorData

Example

<div id="signing-wrapper" style="width: 100%; height: 600px;">
  <sajn-sign-document
    document-id="doc_abc123"
    token="signer_token_xyz"
    allow-document-rejection
  ></sajn-sign-document>
</div>

<script type="module">
  import '@sajn/embed';

  const signDocument = document.querySelector('sajn-sign-document');

  signDocument.addEventListener('document-ready', () => {
    console.log('Ready');
  });

  signDocument.addEventListener('signer-completed', (event) => {
    console.log('Signed!', event.detail);
  });

  signDocument.addEventListener('signer-rejected', (event) => {
    console.log('Rejected:', event.detail.reason);
  });

  signDocument.addEventListener('document-error', (event) => {
    console.error('Error:', event.detail.code);
  });
</script>

CDN Usage Example

Complete HTML page using the UMD bundle:
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Sign Document</title>
  <style>
    #signing-container {
      width: 100%;
      height: 100vh;
    }
  </style>
</head>
<body>
  <div id="signing-container"></div>

  <script src="https://unpkg.com/@sajn/embed/dist/index.umd.js"></script>
  <script>
    const { embedSignDocument } = sajn;

    const instance = embedSignDocument({
      element: '#signing-container',
      documentId: 'doc_abc123',
      token: 'signer_token_xyz',
      onSignerCompleted: (data) => {
        alert('Document signed successfully!');
        window.location.href = '/thank-you';
      },
      onDocumentError: (error) => {
        alert('An error occurred: ' + error.message);
      },
    });
  </script>
</body>
</html>

TypeScript Types

The package exports all types for TypeScript users:
import type {
  EmbedSignDocumentOptions,
  EmbedSignDocumentInstance,
  EmbedViewDocumentOptions,
  EmbedViewDocumentInstance,
  SignerCompletedData,
  SignerRejectedData,
  CssVars,
} from '@sajn/embed';

View Component

The package also includes embedViewDocument for displaying signed documents in read-only mode.

Function API

import { embedViewDocument } from '@sajn/embed';
Or with CDN:
const { embedViewDocument } = sajn;

Options Interface

interface EmbedViewDocumentOptions {
  // Required
  element: HTMLElement | string;  // Target element or CSS selector
  documentId: string;             // Document ID
  token: string;                  // Viewer token

  // Optional
  host?: string;                  // Default: 'https://app.sajn.se'
  language?: 'sv' | 'en' | 'no' | 'da' | 'fi' | 'de' | 'is' | 'es' | 'fr' | 'it';
  className?: string;             // CSS class for iframe
  cssVars?: CssVars & Record<string, string>;
  showScrollIndicator?: boolean;  // Default: true
  additionalProps?: Record<string, string | number | boolean>;

  // Callbacks
  onDocumentReady?: () => void;
  onDocumentError?: (data: { code: string; message: string }) => void;
}

Example

import { embedViewDocument } from '@sajn/embed';

const instance = embedViewDocument({
  element: '#viewer-container',
  documentId: 'doc_abc123',
  token: 'viewer_token_xyz',
  cssVars: {
    primary: '#2563eb',
    background: '#ffffff',
  },
  onDocumentReady: () => {
    console.log('Document loaded');
  },
  onDocumentError: (error) => {
    console.error('Error:', error.code, error.message);
  },
});

// Later: cleanup when done
instance.destroy();

Web Component

The package also exports a custom element <sajn-view-document>:
import '@sajn/embed';
<div id="viewer-wrapper" style="width: 100%; height: 600px;">
  <sajn-view-document
    document-id="doc_abc123"
    token="viewer_token_xyz"
  ></sajn-view-document>
</div>

<script type="module">
  import '@sajn/embed';

  const viewDocument = document.querySelector('sajn-view-document');

  viewDocument.addEventListener('document-ready', () => {
    console.log('Ready');
  });

  viewDocument.addEventListener('document-error', (event) => {
    console.error('Error:', event.detail.code);
  });
</script>