Form Embed
Use the code snippet to add the form to your website. Alternatively, you can share the direct link with your customer.
If you've read through the comparisons here and believe embedding a PandaDoc Form is best, let's get it done!
Still using the previous embed?If your integration loads forms from
https://eform.pandadoc.com, use the archived Form Embed (legacy) snippets.
Useful links
Embed Form Code Snippet
Full form embed
<div id='form-container-YOUR_FORM_ID'></div>
<script type="text/javascript">
(function () {
function buildIframeSrc(baseUrl, data) {
var url = new URL(baseUrl, window.location.href);
if (data) {
Object.keys(data).forEach(function (key) {
url.searchParams.set(key, JSON.stringify(data[key]));
});
}
return url.toString();
}
var config = {
nodeId: 'form-container-YOUR_FORM_ID',
width: '100%',
height: '700px',
url: 'https://form.pandadoc.com/form/YOUR_FORM_HASH?mode=embedded',
data: {
recipients: {
'Form Signer': {
Email: '[email protected]',
FirstName: 'Jane',
LastName: 'Doe'
}
},
metadata: {
source: 'iframe-test'
},
variables: {
'Form signer.FirstName': 'Jane'
},
fields: {
TextField1: 'Prefilled value',
Checkbox1: true,
Date1: '2026-09-18'
}
},
events: {
loaded: function (data) {
console.log('[PandaDoc] Form loaded', data);
},
started: function (data) {
console.log('[PandaDoc] Form submitted', data);
},
completed: function (data) {
console.log('[PandaDoc] Document signing completed', data);
},
redirect_requested: function (data) {
console.log('[PandaDoc] Redirect requested', data);
if (typeof data.redirectUrl === 'string' && data.redirectUrl) {
window.location.assign(data.redirectUrl);
}
},
exception: function (data) {
console.error('[PandaDoc] Form exception', data);
}
}
};
var iframe = document.createElement('iframe');
iframe.frameBorder = 0;
iframe.src = buildIframeSrc(config.url, config.data);
if (config.nodeId) {
var node = document.getElementById(config.nodeId);
node.style.height = config.height;
node.style.width = config.width;
iframe.height = '100%';
iframe.width = '100%';
node.append(iframe);
} else {
iframe.height = config.height;
iframe.width = config.width;
document.body.append(iframe);
}
var eventMethod = window.addEventListener ? 'addEventListener' : 'attachEvent';
var messageEvent = eventMethod === 'attachEvent' ? 'onmessage' : 'message';
window[eventMethod](messageEvent, function (e) {
if (e && e.data && config && iframe && e.source === iframe.contentWindow) {
try {
var message = JSON.parse(e.data);
if (message && message.event) {
var event = message.event.replace('embed.form.', '');
var callback = config.events ? config.events[event] : null;
if (callback) {
callback(message.data);
}
}
} catch (e) {}
}
}, false);
})();
</script>Simple form embed
<div id='form-container-YOUR_FORM_ID'></div>
<script type="text/javascript">
(function () {
function buildIframeSrc(baseUrl, data) {
var url = new URL(baseUrl, window.location.href);
if (data) {
Object.keys(data).forEach(function (key) {
url.searchParams.set(key, JSON.stringify(data[key]));
});
}
return url.toString();
}
var config = {
nodeId: 'form-container-YOUR_FORM_ID',
width: '100%',
height: '700px',
url: 'https://form.pandadoc.com/form/YOUR_FORM_HASH',
events: {
loaded: function () {},
started: function (data) {},
completed: function (data) {},
exception: function (data) {}
},
data: {},
};
var iframe = document.createElement('iframe');
iframe.frameBorder = 0;
iframe.src = buildIframeSrc(config.url, config.data);
if (config.nodeId) {
var node = document.getElementById(config.nodeId);
node.style.height = config.height;
node.style.width = config.width;
iframe.height = '100%';
iframe.width = '100%';
node.append(iframe);
} else {
iframe.height = config.height;
iframe.width = config.width;
document.body.append(iframe);
}
var eventMethod = window.addEventListener ? 'addEventListener' : 'attachEvent';
var messageEvent = eventMethod === 'attachEvent' ? 'onmessage' : 'message';
window[eventMethod](messageEvent, function (e) {
if (e && e.data && config && iframe && e.source === iframe.contentWindow) {
try {
var message = JSON.parse(e.data);
if (message && message.event) {
var event = message.event.replace('embed.form.', '');
var callback = config.events ? config.events[event] : null;
if (callback) {
callback(message.data);
}
}
} catch (e) {}
}
}, false);
})();
</script>Embed Form Config
* denotes a required parameter.
| Attribute | Description | |
|---|---|---|
text * | nodeId | id of the HTML element to which the form will be appended |
text * | width | The width of an element JavaScript embed will be rendered |
text * | height | The height of an element JavaScript embed will be rendered |
text * | url | URL of the form that will be rendered |
events | Capture events from an embedded form. You can subscribe to loaded, started, completed, exception, and redirect_requested | |
data | Pre-fill recipients data, metadata, variables, and fields |
Pre-fill values using JavaScript config
It is possible to pre-fill recipients data, metadata, variables, and fields.
recipients — pre-fill data in the authorization form. All role tokens are supported.
data: {
recipients: {
'Form Signer': {
Email: '[email protected]',
FirstName: 'John',
LastName: 'Doe',
}
}
}metadata — set metadata for the document generated from the form. Max limit is 10 key-value pairs.
data: {
metadata: {
test_metadata_key: 'test value',
}
}variables — set values for variables in the document. All variables (predefined and custom) are supported except Document.Value.
data: {
variables: {
'Form signer.FirstName': 'John',
custom_variable: 'custom variable value',
}
}fields — set values for fields in the document. Text field, Checkbox, Date, and Dropdown fields are supported.
data: {
fields: {
TextField1: 'TextField1 value',
Dropdown1: 'Dropdown selected value',
Checkbox1: true,
Date1: '2021-02-21T00:00:00.000Z'
}
}
Working with Date fieldsSpecify date formatting in PandaDoc template date field settings. Pass your date field value in the following ways:
fields: { Date1: '2021-02-21T00:00:00.000Z', // ISO 8601 date and time Date2: '2021-02-21', // ISO 8601 date, added with the UTC timezone Date3: '02/21/2021' // date, added with the UTC timezone }
Pre-fill values using direct web-link
It is possible to pre-fill recipients data, metadata, variables, and fields without embedding the form, by adding the data as a URL parameter:
&KEY=VALUEwhere
KEY is metadata, recipients, variables, or fields
and
VALUE is URL-encoded data that matches the JavaScript config.
Example
https://form.pandadoc.com/form/YOUR_FORM_HASH?variables=%7B%22test_field_id%22%3A%22test%20value%22%7Dis similar to this code in config:
data: {
variables: {
test_field_id: 'test value',
}
}To pre-fill recipient information in the form, all role tokens are supported.
Example
https://form.pandadoc.com/form/YOUR_FORM_HASH?recipients=%7B%22Client%22:%7B%22Email%22:%[email protected]%22,%22FirstName%22:%22Panda%22,%22LastName%22:%22Test%22%7D%7Dis similar to this code in config:
data: {
recipients: {
'Client': {
Email: '[email protected]',
FirstName: 'Panda',
LastName: 'Test',
}
}
}All possible role variables:
FirstName
LastName
Email
Company
Phone
Country
State
StreetAddress
City
PostalCode
TitleHandling events
It is possible to capture events from an embedded form. You can subscribe to these events:
loaded — the form is loaded and a user is asked to enter contact details (recipient names and emails).
started — a user has entered contact details for all recipients and pressed Review document to create a document from the form.
{
recipients: [{
first_name: 'John',
last_name: 'Doe',
email: '[email protected]'
}],
}completed — a user filled in the assigned fields and finalized the document.
{
document, // public document
}exception — an error occurred while a recipient tries to finish their part.
{
uuid, // document uuid
}redirect_requested — handle redirect requests.
When a template or form is configured to redirect after submission, the embedded form sends a redirect_requested event to the parent page. Subscribe to this event and redirect the visitor using the URL provided in the event payload.
events: {
redirect_requested: function (data) {
if (typeof data.redirectUrl === 'string' && data.redirectUrl) {
window.location.assign(data.redirectUrl);
}
}
}redirect_requested payload:
{
redirectUrl: 'https://example.com/thank-you'
}redirectUrl is the destination configured for the form. Validate that it is a non-empty string before navigating. The website that embeds the form handles the redirect. You can navigate the current page, open the link in a new tab, or perform another action.
Reload form after submission
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id='form-container-YOUR_FORM_ID'></div>
<script type="text/javascript">
(function () {
var config = {
nodeId: 'form-container-YOUR_FORM_ID',
width: '100%',
height: '700px',
url: 'https://form.pandadoc.com/form/YOUR_FORM_HASH',
events: {
loaded: function () {},
started: function (data) {},
completed: function (data) {
// Reload the page one second after the form is completed.
setTimeout(function () {
window.location.reload();
}, 1000);
},
exception: function (data) {}
},
data: {},
};
const dataQueryString = config.data ? Object.keys(config.data)
.map(function (key) {
return '&' + key + '=' + encodeURIComponent(JSON.stringify(config.data[key]));
})
.join('') : '';
var iframe = document.createElement('iframe');
iframe.frameBorder = 0;
iframe.src = config.url + dataQueryString;
if (config.nodeId) {
var node = document.getElementById(config.nodeId);
node.style.height = config.height;
node.style.width = config.width;
iframe.height = '100%';
iframe.width = '100%';
node.append(iframe);
} else {
iframe.height = config.height;
iframe.width = config.width;
document.body.append(iframe);
}
var eventMethod = window.addEventListener ? 'addEventListener' : 'attachEvent';
var messageEvent = eventMethod === 'attachEvent' ? 'onmessage' : 'message';
window[eventMethod](messageEvent, function (e) {
if (e && e.data && config && iframe && e.source === iframe.contentWindow) {
try {
var message = JSON.parse(e.data);
if (message && message.event) {
var event = message.event.replace('embed.form.', '');
var callback = config.events ? config.events[event] : null;
if (callback) {
callback(message.data);
}
}
} catch (e) {
console.log(e);
}
}
}, false);
})();
</script>
</body>
</html>Updated 13 days ago
