GET parameters make it possible to pass information into an embedded Wizara form through the page URL. That means a form can open with useful context already in place instead of asking the visitor to start from scratch.
This is not limited to one form redirecting to another. The same pattern can be used when someone lands on the wrong form, scans a QR code on a tractor or trailer, clicks a link in an email, arrives from a campaign page, or follows a partner-specific link. In each case, the URL carries useful information into the embedded Wizara form so the experience feels faster, smarter, and more personalized.
Common examples include prefilling a company name, contact name, email address, equipment ID, service type, campaign source, referral code, or even a logo URL that can be used to personalize the page.
tractorId or trailerUnit, so the embedded form opens with the correct record already identified.campaignSource, serviceName, or productId so the destination form reflects what interested them.companyName, contactName, or logoUrl so the embedded form feels tailored to that organization or user.This guide explains the most reliable way to pass data into a Wizara form embedded on your website, especially when that form is running inside an iframe.
The core pattern is simple:
When a form is embedded on a website, it usually runs inside an iframe. Because of that, the embedded form may not be able to read the parent page URL directly. In other words, the page can see ?companyName=Acme, but the embedded form inside the iframe may not see it unless the parent page passes it in.
This is why a direct link to the raw Wizara embed URL may work, while the same query parameters on your website page do nothing until you wire the iframe communication correctly.
Any value that makes the next step easier or more relevant is a good candidate. Common examples include:
Some values are used to prefill visible fields. Others can be used behind the scenes for routing, personalization, or conditional logic. For example, a passed companyName can prefill a company field, while a passed logoUrl can be used by custom HTML or EJS to create a more personalized experience.
Before wiring this up, confirm these basics:
The cleanest setup is to use matching names wherever possible. For example:
firstName -> firstName
lastName -> lastName
email -> email
companyName -> companyName
message -> message
source -> source
logoUrl -> logoUrl
If your destination form uses different internal names, simply change the destination field names in the setValue() lines later in the process.
On the source page or source form, use URLSearchParams to create a clean redirect URL. This properly encodes special characters and keeps the logic readable.
const params = new URLSearchParams({
source: 'website-form',
firstName: String(values.firstName || ''),
lastName: String(values.lastName || ''),
email: String(values.email || ''),
companyName: String(values.companyName || ''),
message: String(values.message || ''),
logoUrl: String(values.logoUrl || '')
});
const redirectUrl =
`https://www.example.com/request-details.html?${params.toString()}`;
If the source form itself is embedded in an iframe and the redirect should open the full page instead of staying trapped inside the frame, use:
if (window.top) {
window.top.location.href = redirectUrl;
} else {
window.location.href = redirectUrl;
}
On the destination page, add one empty element where the embedded form should appear.
<div id="WZ--YOUR-FORM-ID"></div>
This step is intentionally simple. The page should contain the container, and your page-level JavaScript should handle the actual form rendering.
Important: render the form in one place only. If you render it once in inline page markup and again in site-level code, you can end up with two copies of the same form, two iframes competing for space, or one populated form and one blank form.
The parent page should render the form, read the query parameters from the page URL, and send those values into the embedded iframe. The safest pattern is to retry a few times because the iframe may exist before the embedded form inside it is fully ready to receive messages.
<script>
function onWizaraLoaded(Wizara) {
const containerId = 'WZ--YOUR-FORM-ID';
const formId = 'YOUR-FORM-ID';
const container = document.getElementById(containerId);
if (!container) return;
container.innerHTML = '';
Wizara.renderForm({
element: '#' + containerId,
formId: formId
});
const payload = (() => {
const urlParams = new URLSearchParams(window.location.search);
return {
wizaraPopulateForm: true,
firstName: urlParams.get('firstName') || '',
lastName: urlParams.get('lastName') || '',
email: urlParams.get('email') || '',
companyName: urlParams.get('companyName') || '',
message: urlParams.get('message') || '',
source: urlParams.get('source') || '',
logoUrl: urlParams.get('logoUrl') || ''
};
})();
const sendPayload = () => {
const iframe = container.querySelector('iframe');
if (!iframe || !iframe.contentWindow) return false;
iframe.contentWindow.postMessage(payload, '*');
return true;
};
const waitForIframe = setInterval(() => {
const iframe = container.querySelector('iframe');
if (!iframe) return;
clearInterval(waitForIframe);
iframe.addEventListener('load', () => {
let attempts = 0;
const maxAttempts = 12;
const retrySend = setInterval(() => {
sendPayload();
attempts += 1;
if (attempts >= maxAttempts) clearInterval(retrySend);
}, 400);
});
let bootAttempts = 0;
const bootMaxAttempts = 12;
const bootRetry = setInterval(() => {
sendPayload();
bootAttempts += 1;
if (bootAttempts >= bootMaxAttempts) clearInterval(bootRetry);
}, 400);
}, 100);
}
</script>
<script src="https://app.wizara.com/embed/js/index.browser.js" async></script>
Inside the destination Wizara form, add an On Form Load handler that listens for the message and maps the incoming values to the right fields.
async (setValue, setValues) => {
const applyValues = (data) => {
if (!data || typeof data !== 'object') return;
if (!data.wizaraPopulateForm) return;
const firstName = String(data.firstName || '').trim();
const lastName = String(data.lastName || '').trim();
const email = String(data.email || '').trim();
const companyName = String(data.companyName || '').trim();
const message = String(data.message || '').trim();
const source = String(data.source || '').trim();
const logoUrl = String(data.logoUrl || '').trim();
if (firstName) setValue('firstName', firstName);
if (lastName) setValue('lastName', lastName);
if (email) setValue('email', email);
if (companyName) setValue('companyName', companyName);
if (message) setValue('message', message);
if (source) setValue('source', source);
if (logoUrl) setValue('logoUrl', logoUrl);
};
window.addEventListener('message', (event) => {
applyValues(event.data);
});
const urlParams = new URLSearchParams(window.location.search);
applyValues({
wizaraPopulateForm: true,
firstName: urlParams.get('firstName'),
lastName: urlParams.get('lastName'),
email: urlParams.get('email'),
companyName: urlParams.get('companyName'),
message: urlParams.get('message'),
source: urlParams.get('source'),
logoUrl: urlParams.get('logoUrl')
});
};
The direct URL check at the bottom is optional but useful. It allows the same logic to work when you open the raw embed URL directly during testing.
Passing data into a form is not limited to visible inputs. It can also support a more customized experience.
For example:
companyName to prefill a company field.source to track where the visitor came from.productId or serviceName to tailor the form flow.logoUrl to show a visitor-specific logo in a custom HTML block.This is especially useful for quote flows, partner referrals, white-label experiences, personalized onboarding, targeted landing pages, and enterprise workflows.
Wizara.renderForm(...) is being called in more than one place. A very common mistake is rendering the form once in page markup and again in site-wide or end-of-body code. Another common cause is loading the same embed script twice.setValue() call, and the destination field name all match exactly.window.top.location.href or a link with target="_top" when the redirect must replace the whole browser page.src unless absolutely necessary. Changing the iframe URL manually can interfere with how the embed handles height updates and internal messaging.logoUrl only makes the value available. You still need a field, HTML block, or EJS-driven output that actually uses that value.companyName, before adding more values.For most websites, the most dependable setup is to let the parent page read the URL parameters, render the embedded Wizara form once, and pass those values into the iframe after load. That approach is flexible enough for simple prefills and powerful enough for more advanced experiences such as personalized branding, preselected services, campaign-aware forms, and guided multi-step workflows.
Done carefully, it removes friction, reduces duplicate typing, and makes separate pages feel like one smooth conversation.