Skip to content
Start free

Web Forms JavaScript API

Open in ClaudeOpen in ChatGPT

Web Forms JS embeds a template’s web form on your website. People fill in the form’s fields, and the submission fills in your PDF or HTML template.

Load the library
<link
rel="stylesheet"
href="https://cdn.docspring.com/embed/web_form.v3.0.0.css"
/>
<script src="https://cdn.docspring.com/embed/web_form.v3.0.0.js"></script>

Draws a template’s web form inside an element on your page.

DocSpring.createWebForm(selector, templateId, options);
ParameterTypeRequiredDescription
selectorstring or elementNoA CSS selector for the element to draw the form in, or the element itself. The form replaces what’s inside it. Defaults to ".dsp-form".
templateIdstringYesThe template’s ID, such as "tpl_123456"
optionsobjectNoOptions and callbacks

createWebForm looks for the element straight away, so put it on the page before you call it: it throws an error when nothing on the page matches selector. It returns nothing: the form loads the template, then draws itself.

OptionTypeDefaultDescription
templateVersionstringNoneThe template version to show and submit, such as "1.2.3" or "draft". Defaults to the latest published version, or the draft if no version is published.
defaultDataobject{}Values for the form’s fields, as nested JSON: the field person/name is { person: { name: "..." } }. An empty string leaves a field blank. If someone has already started filling in the form in this browser, their saved values are restored instead.
metadataobject{}Metadata for the submission. It’s in API responses and webhooks, not in the PDF.
showButtonsbooleantruefalse hides the Clear and submit buttons
showClearButtonbooleantruefalse hides the Clear button
showSubmitButtonbooleantruefalse hides the submit button
clearButtonLabelstring"Clear"The Clear button’s text
submitButtonLabelstring"Submit Form"The submit button’s text
submitButtonSavingLabelstring"Saving..."The submit button’s text while the form saves
submitButtonProcessingLabelstring"Generating PDF..."The submit button’s text while the form waits for the PDF ("Generating document..." for a Word template that makes Word documents or OpenDocument files)
redirectURLstringNoneWhere to send people after they submit the form, instead of the template’s redirect URL. See Redirects. It can have variables after its ? or #.
waitForPDFbooleantruefalse stops the form from waiting for the PDF once it’s saved: the success screen has no link to it, the form redirects straight away (if there’s a redirect URL), and onProcessed isn’t called. Has no effect when “Submission Privacy” is “Private”.
showSuccessScreenbooleantruefalse keeps the form on the page once it’s submitted, as 2.x did, instead of showing the success screen
successTitlestring or functionThe template’s settingThe success screen’s title, instead of the template’s. It can have variables, or be a function (see Success screen).
successMessagestring or functionThe template’s settingThe success screen’s message, as plain text, instead of the template’s. "" shows no message. It can have variables, or be a function (see Success screen).
showFillAgainButtonbooleanThe template’s settingWhether the success screen has a Fill out again button
sectionListstring"left"Where a form with sections shows the list of sections: "left" beside the form (above it when the form is narrower than 720px), or "top" above it at any width.
themeobjectNoneValues for the form’s custom properties, without the --dsp- prefix: { primary: "#0b6e4f", radius: "4px" }
darkModeboolean or stringfalsetrue shows the form’s dark theme, and "auto" follows the visitor’s system setting. See Dark theme.
CallbackArgumentsDescription
processTemplateSchemajsonSchemaCalled before the form is drawn, with the template’s JSON schema. Change it in place, or return a new schema. To hide a field, delete it from properties and from required.
onClearFormNoneCalled when the Clear button is pressed
onSubmitformData (object)Called when someone submits the form and every answer is valid, before the form saves it. formData is the data the form will send. Return false to stop the submission.
onSavesubmission (object)Called when the submission is saved
onProcessedsubmission (object)Called when the PDF is ready. Only called when “Submission Privacy” is “Public” and waitForPDF isn’t false. A redirect follows one second later, so you have time to finish a short request.
onSuccesssubmission (object)Called when the PDF is ready, just before onProcessed, with the same submission. It’s there for pages written for 2.x: use onProcessed.
onErrorerror (object)Called when something goes wrong. See Errors.

The form loads the template from app.docspring.com. If your account is in the EU region, set DocSpring.appHost before you create the form:

DocSpring.appHost = "app-eu.docspring.com";
DocSpring.createWebForm(".dsp-form", "tpl_123456");

DocSpring Enterprise deployments set DocSpring.appHost to their own DocSpring domain.

DocSpring.createWebForm(".dsp-form", "tpl_123456");
DocSpring.createWebForm(".dsp-form", "tpl_123456", {
defaultData: {
name: "John Smith",
date: "2024-01-15",
},
});
DocSpring.createWebForm(".dsp-form", "tpl_123456", {
// Options
templateVersion: "1.2.3",
defaultData: {
name: "John Smith",
},
metadata: {
userId: "12345",
source: "website",
},
showButtons: true,
showClearButton: true,
showSubmitButton: true,
clearButtonLabel: "Reset",
submitButtonLabel: "Generate My PDF",
submitButtonSavingLabel: "Please wait...",
submitButtonProcessingLabel: "Creating your PDF...",
// A form that redirects shows no success screen, so the success options below
// apply only when neither this nor the template sets a redirect URL
redirectURL: "https://example.com/success",
waitForPDF: true,
showSuccessScreen: true,
successTitle: "Application received",
successMessage: "We'll email you within two working days.",
showFillAgainButton: false,
sectionList: "top",
theme: {
primary: "#0b6e4f",
radius: "4px",
},
darkMode: "auto",
// Callbacks
processTemplateSchema: function (jsonSchema) {
// Hide the internal_notes field
delete jsonSchema.properties.internal_notes;
jsonSchema.required = (jsonSchema.required || []).filter(function (name) {
return name !== "internal_notes";
});
},
onClearForm: function () {
console.log("Form cleared");
},
onSubmit: function (formData) {
console.log("Form submitted:", formData);
},
onSave: function (submission) {
console.log("Submission saved:", submission.id);
},
onProcessed: function (submission) {
console.log("PDF ready:", submission.download_url);
},
// Kept from 2.x: called just before onProcessed
onSuccess: function (submission) {},
onError: function (error) {
console.error(error.error, error.message);
},
});

When a template has sections, the form shows one section at a time: its title, with “Step 1 of 3” beside it, its description, then its fields. Next checks the section’s answers before it moves on, Back returns to the section before, and the submit button is on the last section. A list of the sections sits beside the form when the form is at least 720px wide, and above it when it’s narrower. sectionList: "top" keeps it above the form at any width. People can go back to any section they’ve already been to from the list. A section whose fields conditional logic hides is skipped.

The sections are in the template’s JSON schema, as x-form-sections: a list of { id, title, description, properties }, where properties names the schema’s top-level properties in that section. processTemplateSchema can change them. A property that no section lists goes in the last section.

The form saves what people enter in the browser’s localStorage, under docspring-web-form:<template ID>, and restores it the next time the form loads in that browser, instead of defaultData. A form with sections opens on the section the visitor was on, and they can go back to the sections they’d reached. Submitting the form, or pressing Clear or Fill out again, removes it.

When one browser fills in the same template for different people or records, remove the saved values before you create the form. The form then starts at its first section, too:

localStorage.removeItem("docspring-web-form:tpl_123456");
DocSpring.createWebForm(".dsp-form", "tpl_123456", { defaultData: record });

An image field has an Add an image button, which opens a dialog. There the visitor chooses an image file, drops one on it or pastes one, or gives the web address of an image. Dropping or pasting an image on the field itself adds it straight away. The field then shows the image, with Change and Remove buttons.

The form sends a file as { "base64": "..." }. It draws the image again in the browser, at most 2,400 pixels on its longest side: a JPEG stays a JPEG, a PNG stays a PNG, and a GIF or WebP image becomes a PNG if it has transparent pixels and a JPEG if it doesn’t. A web address is sent as { "url": "..." }, and DocSpring downloads the image when it makes the PDF. The form shows a preview of the address while the visitor types it, if your page’s Content Security Policy allows it.

Saved progress keeps the images too, unless they don’t fit in localStorage (about 5 MB for your whole site): then it keeps the other answers.

Signatures come only from signature requests, which record who signed and when. A web form with a signature or initials field says at the top that it can’t be signed as soon as it loads, even when the field is in a later section. Its signature pads, its Next button and its submit button are turned off, and DocSpring rejects a live submission with a signature or initials value. To print an image or a name on the PDF, use an Image or Text field instead.

On your template’s hosted form, the Test switch (which only you see, signed in) turns the signature pads on for test submissions, with a warning at the top that they’re for testing.

On a DocSpring Enterprise install, signature pads work in live forms too, and DocSpring accepts live submissions with a signature.

Once the submission is saved, the form’s place on your page shows a success screen: a check mark, a title, the template’s message, and a Fill out again button. When “Submission Privacy” is “Public”, it says the PDF is being generated, then shows a Download PDF button once it’s ready (for a Word template, a button for its Word document or OpenDocument file).

Set the title, the message and the button in the template editor’s Forms settings, or override them with the successTitle, successMessage and showFillAgainButton options. The title defaults to “Thanks for filling out” and the template’s name. The message is plain text: line breaks show, and web addresses become links. One short paragraph (up to 90 characters) is centred under the title, and a longer message is shown in a shaded box, aligned left. Fill out again clears the form, and its saved progress, and starts it again with defaultData. If that happens before the first PDF is ready, the first submission still calls onProcessed (or onError) when it finishes.

The title and the message can have variables such as {{ data.first_name }}, which show the person’s answers. successTitle and successMessage can also be functions, which get the data and metadata the form submitted and the submission, and return the text:

successTitle: function (details) {
return "Thanks, " + details.data.first_name + "!";
},

A function’s text has no variables: build it from details instead.

If the PDF can’t be generated, the screen says why, with a button back to the form and its answers, so the visitor can fix an image’s web address, say, and submit it again.

The success screen doesn’t show when the form redirects. showSuccessScreen: false keeps the form on the page after it’s submitted, as 2.x did, so you can show your own message from onSave or onProcessed.

After someone submits the form, it goes to redirectURL, or to the template’s redirect URL when you don’t pass one. redirectURL: null doesn’t clear the template’s redirect URL: to handle the submission in JavaScript instead, leave the template’s setting blank.

After its ? or #, the URL can have variables such as ?name={{ data.first_name }}. Each value is URL-encoded, as the submission’s data has it.

The form adds the submission’s details to the URL as query parameters, replacing any parameter of the same name:

https://example.com/thank-you?submission_id=sub_123&template_name=My%20Template&template_version=latest&template_id=tpl_123

When “Submission Privacy” is “Private”, or waitForPDF is false, the form redirects as soon as it’s saved. When it’s “Public”, the form waits for the PDF, calls onProcessed, then redirects one second later. If the PDF can’t be generated, the form doesn’t redirect: it says why above its buttons and calls onError. A form that redirects shows no success screen.

The submission object passed to onSave and onProcessed contains:

PropertyTypeDescription
idstringThe submission’s ID
statestringIts state, such as "pending" or "processed"
download_urlstringA URL to download the PDF. null until the PDF is processed.
expires_atstringWhen download_url expires (ISO 8601). null until the PDF is processed.

onError receives an object with an error code and a message:

errorDescription
failed_requestThe template couldn’t be loaded (for example, “Online Form Privacy” is “Private”), the form couldn’t be saved, or a request for the PDF’s status failed. status is the HTTP status when there was a response, and errors DocSpring’s messages.
invalid_dataDocSpring rejected the form’s data. The form also shows the errors at the fields they’re about. errors lists DocSpring’s messages, and submission is the submission.
submission_timeoutThe PDF wasn’t processed within 60 seconds
invalid_statusThe PDF couldn’t be generated. submission is the submission.

When the form can’t be saved, it also shows what went wrong above its buttons. When the PDF fails, the success screen says why.

onError: function (error) {
if (error.error === "invalid_data") {
console.error("Validation failed:", error.errors);
} else {
console.error(error.error, error.message);
}
}

The form draws a .dsp-web-form element inside your container. Its styles apply only inside that element, so your page’s styles don’t change, and its classes start with dsp-.

Set these CSS custom properties to change the form’s colors, font and sizes:

PropertyDefaultWhat it styles
--dsp-font-familyinherit (your page’s font)All text
--dsp-font-size15pxThe base text size. Labels, hints and headings are sized from it.
--dsp-textNear blackText, labels and answers
--dsp-text-secondaryGrayDescriptions, hints, the section step and inactive sections
--dsp-placeholderGrayPlaceholder text, and a dropdown with nothing chosen
--dsp-backgroundtransparentThe form’s background
--dsp-surfaceWhiteThe date picker’s calendar, the image dialog, and its drop area while an image is dragged over it
--dsp-surface-sunkenPale blue-grayHovered buttons and sections, read-only fields and input prefixes
--dsp-borderLight grayGroups, list items, section numbers, icon buttons, uploaded images and the calendar
--dsp-input-backgroundWhiteText fields, dropdowns, icon buttons and secondary buttons (signature pads stay white)
--dsp-input-borderGrayThe borders of text fields, dropdowns, signature pads and secondary buttons
--dsp-primaryDocSpring blueThe submit and Next buttons, the current section, checkboxes and radio buttons, links and the selected date
--dsp-primary-hoverDarker blueThe submit and Next buttons and links on hover
--dsp-primary-textWhiteText on --dsp-primary
--dsp-dangerRedErrors, the asterisk on required fields, and the message at the top of a live form with a signature field
--dsp-danger-backgroundPale redThe error message above the buttons, sections with errors, and the circle behind a failed PDF’s icon
--dsp-successGreenFinished sections in the sections list, and the success screen’s check mark
--dsp-success-backgroundPale greenThe circle behind the success screen’s check mark
--dsp-warningAmberThe warning at the top of a form with a signature field in test mode
--dsp-warning-backgroundPale amberIts background
--dsp-focusBlueFocus rings
--dsp-radius6pxCorners of fields, buttons and groups
--dsp-control-height40pxThe height of text fields, dropdowns and buttons
--dsp-spacing16pxThe space between fields. Other gaps are sized from it.

Set them in your CSS, on .dsp-web-form. Your rule wins over the form’s defaults whichever stylesheet loads first:

.dsp-web-form {
--dsp-font-family: "Inter", sans-serif;
--dsp-primary: #0b6e4f;
--dsp-primary-hover: #08563d;
--dsp-radius: 4px;
}

Or pass them with the theme option, without the --dsp- prefix:

DocSpring.createWebForm(".dsp-form", "tpl_123456", {
theme: {
"font-family": '"Inter", sans-serif',
primary: "#0b6e4f",
"primary-hover": "#08563d",
radius: "4px",
},
});

darkMode: true shows the form’s dark theme, and darkMode: "auto" shows it when the visitor’s system is set to dark mode. The form’s background is transparent, so use the dark theme on a dark page, or set --dsp-background.

The .dsp-web-form element’s data-dsp-theme attribute is light, dark or auto. Values from the theme option apply in both themes. To give the dark theme its own colors, set the properties in your CSS:

.dsp-web-form[data-dsp-theme="dark"] {
--dsp-primary: #4ea8de;
}
@media (prefers-color-scheme: dark) {
.dsp-web-form[data-dsp-theme="auto"] {
--dsp-primary: #4ea8de;
}
}

For anything the custom properties don’t cover, style the form’s classes, inside .dsp-web-form:

ClassElement
.dsp-fieldA field, with its label, description and error
.dsp-label, .dsp-descriptionA field’s label and description
.dsp-input, .dsp-select, .dsp-textareaText fields, dropdowns and multi-line text fields
.dsp-field-errorA field’s error
.dsp-group, .dsp-list-itemA group of fields, and an item in a list
.dsp-sectionsThe list of sections
.dsp-section-title, .dsp-section-descriptionThe current section’s title and description
.dsp-section-step“Step 1 of 3”
.dsp-form-errorThe message above the buttons
.dsp-signature-noticeThe message at the top of a form with a signature field. Test mode’s warning also has .dsp-signature-notice-test.
.dsp-actionsThe buttons
.dsp-button-submit, .dsp-button-clearThe submit and Clear buttons, which also have the 2.x classes .alpaca-form-button-submit and .alpaca-form-button-clear
.dsp-button-next, .dsp-button-backThe Next and Back buttons
.dsp-successThe success screen. Its data-state is none (no PDF), generating, ready or failed.
.dsp-success-title, .dsp-success-messageThe success screen’s title and message. A longer message also has .dsp-success-message-card.
.dsp-button-download, .dsp-button-fill-againThe Download PDF and Fill out again buttons
.dsp-image-add, .dsp-image-cardAn image field’s Add an image button, and the image once it’s added
.dsp-dialog, .dsp-image-dialogThe dialog that adds an image
.dsp-web-form .dsp-label {
text-transform: uppercase;
letter-spacing: 0.04em;
}

Web Forms JS works under a strict Content-Security-Policy, without 'unsafe-inline' or 'unsafe-eval'. Give the <script> tag that loads it a nonce your style-src allows: a form with a date field adds one <style> element, which carries that nonce. See Content Security Policy for the hosts to allow. It doesn’t include jQuery, and its only global is DocSpring, apart from the polyfills it includes for JavaScript features a browser lacks (Globals).

To show an image field’s image from a web address, allow https: in img-src. Without it, the field says it has no preview, and still sends the address.

Web Forms JS 3.x supports current versions of Chrome, Edge, Firefox and Safari, on desktop and mobile. It doesn’t support Internet Explorer.