Skip to main content
All eSign options and customization

Document options

Control how the document is displayed and what’s required:
document={{
  // Required - the document to display
  source: File | Blob | string,

  // Display mode
  mode: 'full',        // 'full' (default) or 'download'

  // View options (recommended)
  viewOptions: { layout: 'web' },  // 'print' (default) or 'web'

  // Requirements
  validation: {
    scroll: { required: true }  // Must scroll to bottom
  }
}}

View options

Control how the document is displayed using viewOptions.layout:
  • print (default) - Fixed page width, displays document as it prints
  • web - Content reflows to fit container width (mobile/accessibility)
Use web when you want text to reflow to fit the container. This is recommended for mobile devices and WCAG AA reflow compliance (Success Criterion 1.4.10).
// Mobile-friendly responsive layout
document={{
  source: contractFile,
  viewOptions: { layout: 'web' }
}}
Deprecated options: layoutMode and layoutMargins are deprecated since v2.0. Use viewOptions instead:
  • layoutMode: 'responsive'viewOptions: { layout: 'web' }
  • layoutMode: 'paginated'viewOptions: { layout: 'print' }
  • layoutMargins is no longer supported. Use CSS to control margins.
When mode is set to download, the submit button is hidden.

Field system

Fields use a unique id system for identifying and updating content:
  • id - Unique identifier for the field

Document fields (injected values)

Document fields populate placeholders in your document. Three types are supported:

Text fields

Simple text replacement (type is optional, defaults to 'text'):
fields={{
  document: [
    { id: '1', value: 'Jane Smith' },
    { id: '2', value: '2024-01-15' },
    { id: '3', value: '$50,000' }
  ]
}}

Table fields

Populate table rows with a 2D array. The first row in the document serves as a template and is preserved, while new rows are appended with the same styling:
fields={{
  document: [
    {
      id: '1',
      type: 'table',
      value: [
        ['Item 1', '$100', '2'],
        ['Item 2', '$200', '1'],
        ['Item 3', '$150', '3']
      ]
    }
  ]
}}
These update fields with matching IDs in your document.
Signature fields from the signer are automatically converted to images when injected into the document. Use the textToImageDataUrl utility if you need to generate signature images programmatically.

Signer fields (interactive)

fields={{
  signer: [
    {
      id: '1',
      type: 'signature',
      label: 'Your Signature',
      validation: { required: true }
    },
    {
      id: '2',
      type: 'checkbox',
      label: 'I accept the terms',
      validation: { required: true }
    },
    {
      id: '3',
      type: 'checkbox',
      label: 'Send me updates',
      validation: { required: false }
    }
  ]
}}
Field types:
  • signature - Default text input (use a custom component for other UI)
  • checkbox - Checkbox field
  • text - Text input field

Custom components

Three levels of customization:

Level 1: Use defaults

<SuperDocESign document={{ source: "document.docx" }} onSubmit={handleSubmit} />

Level 2: Customize labels

submit={{ label: "I Agree" }}
download={{ label: "Save Copy", fileName: "agreement.pdf" }}

Level 3: Custom components

// Custom submit button
submit={{
  component: ({ onClick, isValid, isDisabled, isSubmitting }) => (
    <button
      onClick={onClick}
      disabled={!isValid || isDisabled}
      className="my-custom-button"
    >
      {isSubmitting ? <Spinner /> : 'Sign Document'}
    </button>
  )
}}

// Custom signature field
fields={{
  signer: [{
    id: '1',
    type: 'signature',
    component: ({ value, onChange, isDisabled, label }) => (
      <SignaturePad
        value={value}
        onComplete={onChange}
        disabled={isDisabled}
        title={label}
      />
    )
  }]
}}

Event handlers

// Main submission
onSubmit={async (data) => {
  // data.eventId - Your session ID
  // data.auditTrail - Complete interaction log
  // data.signerFields - User inputs
  await api.save(data);
}}

// Download handling
onDownload={async (data) => {
  // data.documentSource - Original .docx file
  // data.fileName - Suggested filename
  // Send to backend for PDF conversion
  const response = await fetch('/api/generate-pdf', {
    method: 'POST',
    body: JSON.stringify(data)
  });
  const blob = await response.blob();
  saveAs(blob, data.fileName);
}}

// State monitoring
onStateChange={(state) => {
  // state.scrolled - Has scrolled to bottom
  // state.fields - Current field values
  // state.isValid - Ready to submit
  console.log('Ready:', state.isValid);
}}

// Field changes
onFieldChange={(field) => {
  // field.id - Field identifier
  // field.value - New value
  // field.previousValue - Old value
  analytics.track('field_changed', field);
}}

// Document analysis
onFieldsDiscovered={(fields) => {
  // All fields found in document
  console.log('Document has fields:', fields);
}}

Styling

The component can be styled using standard CSS. Optionally import default styles:
// Optional: import default styles
import '@superdoc-dev/esign/styles.css';

<SuperDocESign
  className="my-esign-container"
  style={{ maxWidth: "800px" }}
  documentHeight="500px" // Height of document viewer
/>

CSS classes

Target these classes to customize appearance:
ClassDescription
.superdoc-esign-containerRoot container (also accepts className prop)
.superdoc-esign-documentDocument section wrapper
.superdoc-esign-document-toolbarToolbar with download button
.superdoc-esign-document-controlsControl buttons container
.superdoc-esign-document-viewerScroll container (SuperDoc mounts inside)
.superdoc-esign-controlsFields and buttons area
.superdoc-esign-fieldsField container
.superdoc-esign-actionsAction buttons container
.superdoc-esign-form-actionsForm submit button container

Customizing with CSS

Style the component using standard CSS - no special variables needed:
.superdoc-esign-document-viewer {
  background: #f8fafc;
}

.superdoc-esign-controls {
  margin-top: 0; /* Remove gap between viewer and controls */
  padding: 20px 24px;
  background: #ffffff;
  border-top: 1px solid #e2e8f0;
}

.superdoc-esign-fields {
  margin-bottom: 16px;
}

.superdoc-esign-actions {
  gap: 12px;
}

Themed example

Style the component to match your brand.

Structure

.superdoc-esign-container
├── .superdoc-esign-document
│   ├── .superdoc-esign-document-toolbar
│   │   └── .superdoc-esign-document-controls
│   └── .superdoc-esign-document-viewer
│       └── .super-editor (the document)
└── .superdoc-esign-controls
    ├── .superdoc-esign-fields
    └── .superdoc-esign-actions

CSS

/* Card-like container */
.brand-signer {
  border: 1px solid #e2e8f0;
  border-radius: 12px;
  overflow: hidden;
}

/* Document viewer background */
.brand-signer .superdoc-esign-document-viewer {
  background: #f8fafc;
}

/* Controls area styling */
.brand-signer .superdoc-esign-controls {
  margin-top: 0;
  padding: 20px 24px;
  background: #ffffff;
  border-top: 1px solid #e2e8f0;
}

/* Style the document editor */
.brand-signer .super-editor {
  border-radius: 12px 12px 0 0;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

Component

<SuperDocESign
  className="brand-signer"
  documentHeight="500px"
  // ... other props
/>

Complete example

<SuperDocESign
  eventId={`session-${Date.now()}`}
  document={{
    source: contractFile,
    mode: "full",
    viewOptions: { layout: "web" },
    validation: {
      scroll: { required: true },
    },
  }}
  fields={{
    document: [
      { id: "1", value: companyName },
      { id: "2", value: new Date().toLocaleDateString() },
    ],
    signer: [
      {
        id: "1",
        type: "signature",
        validation: { required: true },
        label: "Sign here",
      },
      {
        id: "2",
        type: "checkbox",
        validation: { required: true },
        label: "I accept all terms",
      },
    ],
  }}
  download={{
    fileName: "signed-contract.pdf",
    label: "Download Copy",
  }}
  submit={{
    label: "Complete Signing",
  }}
  onSubmit={handleSubmit}
  onStateChange={updateUI}
  className="contract-signer"
  documentHeight="600px"
/>