JavaScript SDK

Client-side SDK for embedding and interacting with forms

JavaScript SDK

The Transactional Forms JavaScript SDK allows you to embed forms and interact with them programmatically.

Installation

Script Tag

Add the SDK script to your page:

<script src="https://cdn.usetransactional.com/sdk/forms.min.js"></script>

NPM Package

npm install @transactional/forms-sdk
import { TransactionalForms } from '@transactional/forms-sdk';

Quick Start

Basic Embedding

<div id="form-container"></div>
<script src="https://cdn.usetransactional.com/sdk/forms.min.js"></script>
<script>
  TransactionalForms.render({
    formId: 'your-form-uuid',
    container: '#form-container',
  });
</script>

With Options

TransactionalForms.render({
  formId: 'your-form-uuid',
  container: '#form-container',
  options: {
    prefill: {
      email: 'user@example.com',
      name: 'John Doe',
    },
    hideFields: ['hidden_source'],
    theme: {
      primaryColor: '#3B82F6',
    },
    onSubmit: (data) => {
      console.log('Form submitted:', data);
    },
  },
});

API Reference

TransactionalForms.render(config)

Renders a form in the specified container.

Parameters:

ParameterTypeRequiredDescription
formIdstringYesForm UUID
containerstring | ElementYesCSS selector or DOM element
optionsRenderOptionsNoConfiguration options

RenderOptions:

interface RenderOptions {
  // Pre-fill field values
  prefill?: Record<string, any>;
 
  // Hide specific fields
  hideFields?: string[];
 
  // Theme overrides
  theme?: {
    primaryColor?: string;
    backgroundColor?: string;
    textColor?: string;
    fontFamily?: string;
  };
 
  // Disable form submission (view only)
  readOnly?: boolean;
 
  // Auto-focus first field
  autoFocus?: boolean;
 
  // Show/hide branding
  showBranding?: boolean;
 
  // Callbacks
  onLoad?: () => void;
  onStart?: () => void;
  onSubmit?: (data: FormData) => void;
  onError?: (error: Error) => void;
  onFieldChange?: (fieldId: string, value: any) => void;
}

Returns: FormInstance

TransactionalForms.create(formId, options)

Creates a form instance without rendering.

const form = TransactionalForms.create('your-form-uuid', {
  prefill: { email: 'user@example.com' },
});
 
// Render later
form.render('#form-container');

FormInstance Methods

form.render(container)

Renders the form to a container.

form.render('#form-container');

form.destroy()

Removes the form from the DOM.

form.destroy();

form.reset()

Resets the form to its initial state.

form.reset();

form.setFieldValue(fieldId, value)

Sets a field value programmatically.

form.setFieldValue('email', 'user@example.com');

form.getFieldValue(fieldId)

Gets the current value of a field.

const email = form.getFieldValue('email');

form.getAllValues()

Gets all current form values.

const data = form.getAllValues();
// { name: 'John', email: 'john@example.com', ... }

form.validate()

Validates the form and returns errors.

const errors = form.validate();
// { email: 'Invalid email format' }

form.submit()

Submits the form programmatically.

await form.submit();

form.goToStep(stepIndex)

Navigates to a specific step (multi-page forms).

form.goToStep(2);

form.nextStep()

Goes to the next step.

form.nextStep();

form.previousStep()

Goes to the previous step.

form.previousStep();

Events

Listening to Events

const form = TransactionalForms.render({
  formId: 'your-form-uuid',
  container: '#form-container',
});
 
// Form loaded
form.on('load', () => {
  console.log('Form loaded');
});
 
// User started filling
form.on('start', () => {
  console.log('User started');
});
 
// Field value changed
form.on('fieldChange', ({ fieldId, value, isValid }) => {
  console.log(`Field ${fieldId} changed to:`, value);
});
 
// Step changed (multi-page forms)
form.on('stepChange', ({ from, to, direction }) => {
  console.log(`Moved from step ${from} to ${to}`);
});
 
// Validation error
form.on('validationError', ({ fieldId, error }) => {
  console.log(`Validation error on ${fieldId}:`, error);
});
 
// Form submitted
form.on('submit', ({ data, submissionId }) => {
  console.log('Submitted:', data);
});
 
// Submission error
form.on('error', (error) => {
  console.error('Error:', error);
});

Removing Event Listeners

const handler = () => console.log('submitted');
form.on('submit', handler);
 
// Later...
form.off('submit', handler);

Pre-filling Data

Static Pre-fill

TransactionalForms.render({
  formId: 'your-form-uuid',
  container: '#form-container',
  options: {
    prefill: {
      name: 'John Doe',
      email: 'john@example.com',
      company: 'Acme Inc',
    },
  },
});

Dynamic Pre-fill from URL

// URL: https://example.com/form?email=john@example.com&source=landing
 
const params = new URLSearchParams(window.location.search);
 
TransactionalForms.render({
  formId: 'your-form-uuid',
  container: '#form-container',
  options: {
    prefill: {
      email: params.get('email'),
      hidden_source: params.get('source'),
    },
  },
});

Pre-fill from User Data

// Assuming you have user data
const user = await getLoggedInUser();
 
TransactionalForms.render({
  formId: 'your-form-uuid',
  container: '#form-container',
  options: {
    prefill: {
      name: user.name,
      email: user.email,
      phone: user.phone,
    },
  },
});

Theme Customization

Override Colors

TransactionalForms.render({
  formId: 'your-form-uuid',
  container: '#form-container',
  options: {
    theme: {
      primaryColor: '#8B5CF6',
      backgroundColor: '#1F2937',
      textColor: '#F9FAFB',
      borderColor: '#374151',
      inputBackground: '#111827',
      fontFamily: 'Inter, sans-serif',
    },
  },
});

CSS Variables

You can also use CSS variables:

#form-container {
  --tf-primary: #8b5cf6;
  --tf-background: #1f2937;
  --tf-text: #f9fafb;
  --tf-border: #374151;
  --tf-input-bg: #111827;
  --tf-font-family: 'Inter', sans-serif;
}

Conditional Logic

Handle conditional field visibility:

const form = TransactionalForms.render({
  formId: 'your-form-uuid',
  container: '#form-container',
});
 
form.on('fieldChange', ({ fieldId, value }) => {
  if (fieldId === 'has_company' && value === 'yes') {
    form.showField('company_name');
    form.showField('company_size');
  } else if (fieldId === 'has_company' && value === 'no') {
    form.hideField('company_name');
    form.hideField('company_size');
  }
});

File Uploads

Handle file upload fields:

form.on('fileSelected', ({ fieldId, file }) => {
  console.log(`File selected for ${fieldId}:`, file.name);
});
 
form.on('fileUploaded', ({ fieldId, url }) => {
  console.log(`File uploaded to:`, url);
});
 
form.on('fileError', ({ fieldId, error }) => {
  console.error(`Upload error for ${fieldId}:`, error);
});

Error Handling

TransactionalForms.render({
  formId: 'your-form-uuid',
  container: '#form-container',
  options: {
    onError: (error) => {
      if (error.code === 'FORM_NOT_FOUND') {
        showMessage('This form is no longer available');
      } else if (error.code === 'SUBMISSION_FAILED') {
        showMessage('Failed to submit. Please try again.');
      } else {
        showMessage('Something went wrong');
      }
    },
  },
});

TypeScript Support

import {
  TransactionalForms,
  FormInstance,
  RenderOptions,
  FormData,
} from '@transactional/forms-sdk';
 
const options: RenderOptions = {
  prefill: {
    email: 'user@example.com',
  },
  onSubmit: (data: FormData) => {
    console.log(data);
  },
};
 
const form: FormInstance = TransactionalForms.render({
  formId: 'your-form-uuid',
  container: '#form-container',
  options,
});

React Integration

import { useEffect, useRef } from 'react';
import { TransactionalForms } from '@transactional/forms-sdk';
 
function FormEmbed({ formId, prefillData, onSubmit }) {
  const containerRef = useRef(null);
  const formRef = useRef(null);
 
  useEffect(() => {
    if (containerRef.current) {
      formRef.current = TransactionalForms.render({
        formId,
        container: containerRef.current,
        options: {
          prefill: prefillData,
          onSubmit,
        },
      });
    }
 
    return () => {
      formRef.current?.destroy();
    };
  }, [formId]);
 
  return <div ref={containerRef} />;
}

Next Steps