Skip to content

Form Prefill: Cascade & Precedence

RocketLead forms can have field values prefilled from four different sources. This document explains the precedence between them, what each source can and cannot do, and how to pin values that visitors must not be able to override.

When the widget mounts, it walks four prefill sources in order. Each layer can fill empty slots; higher-priority layers blindly overwrite lower-priority ones. Final priority, from highest to lowest:

#SourceWins overAuthored by
1Embed prefill optionURL params, persistence, defaultsThe page that hosts the embed (developer JS)
2URL query paramsPersistence, defaultsThe visitor’s URL bar / inbound link
3localStorage persistenceDefaultsThe visitor (return-visit autofill)
4Field defaultValue(bottom)The form editor (config)

Mental model: most-explicit-context wins. Code beats URL bar beats local storage beats static config.

A field that no source provides a value for stays empty.


Source 1 — Embed prefill (highest priority)

Section titled “Source 1 — Embed prefill (highest priority)”

Set when calling window.rocketlead.forms.create() from your page’s JavaScript:

<div id="rl-form"></div>
<script src="https://cdn.rocketlead.io/static/forms/widget.js" defer></script>
<script>
window.rocketlead.forms.create({
target: '#rl-form',
formId: 'shared-form-id',
// keys are field IDs (grab them from the editor's developer panel)
prefill: { '<location-field-id>': 'studio-uuid-for-this-page' },
hideFields: ['<location-field-id>']
});
</script>

Keys must be field IDs. Embed prefill and hideFields resolve only against fieldId. The fieldMappingKey (the field’s stable name) is not honored here — even though it is on the URL-params source. Unknown keys are dropped silently.

Grab the fieldId from the editor: open the field’s settings, expand the developer panel, copy the ID. Field IDs are stable across publishes; renaming the field’s label doesn’t change them.

Because embed prefill is the highest-priority source, this is how you pin a value that visitors cannot override — even with a crafted URL. See Hidden fields below.

Skipped in the editor’s preview. The console preview renders defaults but does not simulate the embed surface.


The visitor’s URL automatically prefills matching fields. Two key conventions:

https://your-site.com/contact?fieldId=value
https://your-site.com/contact?yourMappingKey=value

fieldId wins on collision with another field’s mappingKey.

Multi-value (checkbox) fields: repeat the key.

?days=mon&days=wed

Booking-calendar fields are special — a URL value is interpreted as an appointment-type id to preselect inside the calendar, not a slot. Slots are always picked interactively against live availability.

Privacy and captcha fields can never be prefilled from URL params (consent must be explicit, captcha tokens come from the third-party provider at submit time).


If the form has persistence enabled in the editor, listed sharedFields are read from localStorage on mount and written on every change. This is the “return visitor autofill” mechanism — surveys, multi-step funnels, abandoned-and-returned flows.

The persistence bucket is keyed by formId, so two embeds of the same form on the same domain share their bucket.


Source 4 — Field defaultValue (lowest priority)

Section titled “Source 4 — Field defaultValue (lowest priority)”

A static fallback authored in the form editor. Only fills slots no other source filled.

Field typedefaultValue shapeValidation
text / email / telstringrespects maxLength; truncated silently at runtime, rejected at publish
select / locationstringmust match one of field.options[].value
checkboxstring[] (non-empty)every entry must match an option
booking-calendarnot supported
appointment-typenot supported (planned)
captcha / privacynot supported

Defaults run in the editor’s preview, so the editor reflects what visitors will see.


The embed-level hideFields option removes a field from the rendered form while keeping its value in the submission payload. Combined with prefill, this is the multi-instance pattern — one published form, N embeds, each pinning a different value.

window.rocketlead.forms.create({
target: '#rl-form',
formId: 'lead-form',
prefill: {
'<location-field-id>': 'studio-uuid',
'<utm-source-field-id>': 'google'
},
hideFields: ['<location-field-id>', '<utm-source-field-id>']
});

Behaviour:

  • The renderer skips hidden fields. They never appear in step bodies or in the review/summary step.
  • Their values stay in formValues, so studio routing (location), validation, and submission all still see them.
  • URL params targeting a hidden field are silently dropped. A crafted ?location=other-studio link cannot override what the embedder pinned. The embed prefill itself is allowed because the embedder is the source of authority.
  • Validation is unchanged. A hidden required field without a matching prefill will fail at submit — the visitor sees a generic error with nothing to fix. The widget logs console.warn on mount when this is the case.

Every prefill source applies the same defensive rules; mismatches are dropped silently rather than crashing the form.

  • Sanitisation — text inputs (text/email/tel) and option keys are stripped of <, >, and ASCII control characters (U+0000–U+001F and U+007F) before further processing. Values that become empty after stripping are dropped.
  • Option matchselect, location, and checkbox values must match one of the field’s published options[].value. Stale or unknown values are dropped.
  • maxLength — text values exceeding the field’s maxLength are truncated silently at the widget; the publish API rejects them outright (the only chance to surface the error is at publish time).
  • Type shape — non-string passed to a string field, or non-array to a checkbox, is dropped.

Quick reference — what each field type accepts

Section titled “Quick reference — what each field type accepts”
Field typeEmbed prefillURL paramsPersistencedefaultValueNotes
text / email / telsanitised, maxLength-capped
select / locationmust match options[]
checkboxarray, must match options[]
booking-calendar✓¹URL value preselects appointment type, not slot
appointment-typeper-calendar default planned
captchatoken issued by provider at submit
privacyGDPR — explicit consent only

¹ URL ?bookingCalendarFieldId=appointmentTypeUuid is captured into initialAppointmentTypeIds and applied after the appointment-types fetch resolves.


A franchise with five WordPress sites embeds the same form on each site, pinning a different studio per page:

studio1.example.com/contact
<div id="rl-form"></div>
<script>
window.rocketlead.forms.create({
target: '#rl-form',
formId: 'shared-lead-form',
prefill: { '<location-field-id>': 'studio-1-uuid' },
hideFields: ['<location-field-id>']
});
</script>
<!-- studio2.example.com/contact — same form, different studio -->
<script>
window.rocketlead.forms.create({
target: '#rl-form',
formId: 'shared-lead-form',
prefill: { '<location-field-id>': 'studio-2-uuid' },
hideFields: ['<location-field-id>']
});
</script>

Submissions land on each studio’s correct calendar / lead-pool table automatically — the location field drives studio resolution under the hood, even when hidden.

A tracking field (configured as a hidden text field at the form-config level when that’s available — for now, use the embed-level hideFields pattern below) carries the utm_source from inbound campaign links:

https://your-site.com/contact?utm_source=google&utm_campaign=spring2026

Until config-level hidden ships, you can replicate the pattern at the embed level:

const params = new URLSearchParams(window.location.search);
window.rocketlead.forms.create({
target: '#rl-form',
formId: 'lead-form',
prefill: {
'<utm-source-field-id>': params.get('utm_source') ?? 'direct',
'<utm-campaign-field-id>': params.get('utm_campaign') ?? ''
},
hideFields: ['<utm-source-field-id>', '<utm-campaign-field-id>']
});

The form’s email_subject field has a defaultValue of "Anfrage Probetraining" set in the editor. A campaign page links visitors with a custom subject:

https://your-site.com/landing?email_subject=Sommer-Aktion

Result: "Sommer-Aktion" (URL beats default). If the visitor returns later without the URL parameter, persistence (if enabled) shows their last-typed value, otherwise the editor default reappears.


  • “My default isn’t showing in the published form” — make sure no other source is filling the slot. URL params and persistence both override defaults. Test in an incognito window without query strings to confirm.
  • “My embed prefill isn’t applying” — the key didn’t resolve. Embed prefill and hideFields accept only fieldId, not fieldMappingKey. Grab the ID from the field’s settings (developer panel). If you were keying off the mapping name, that’s why nothing applied.
  • “Validation says my form is incomplete but I can’t see why” — a hidden required field has no matching prefill. Open devtools — the widget logs a console.warn at mount listing each affected field.
  • “My select/location prefill is ignored” — the value isn’t in the field’s options[]. Check the editor’s option list against what your embed/URL is sending.
  • Embedding — the widget script and the SPA create() API that takes prefill.
  • Field Types — what each type accepts as a prefill value (and what types can’t be prefilled).
  • Eventsrl:form:prefill fires when prefill is applied at mount.