Why this listener exists
Squarespace’s form block has no public success event, and its class names are hashed and change between deploys, so most recipes either break quietly or fall back to a thank-you page.
This listener confirms success from the form API’s own 2xx response and reads the form ID, field titles and button text from the block’s context JSON, so nothing depends on hashed class names.
Most form tracking fires on a button click or a thank-you page view. Clicks count validation failures and repeat clicks. Thank-you page views count refreshes, back-button visits and bookmarked links. This listener waits for Squarespace’s own success signal, so the event is much closer to a real lead.
How it detects a real submission
squarespace_form_success fires on the first of these success paths:
- A 2xx response from Squarespace’s
/api/form/endpoint (fetch or XHR) - The block’s submission message rendering
- A post-submit redirect: page unload on the form page, then same-domain recall on arrival
squarespace_form_failed fires when Squarespace marks a field invalid after the visitor has interacted with the form.
Every event carries ec_detection_method, so you can segment reports by how each lead was detected.
| ec_detection_method | Event | What it means |
|---|---|---|
confirmation_event |
Success | The platform’s own success event fired |
confirmation_class |
Success | The form gained the platform’s success class |
stored_recall |
Success | Same-domain thank-you page, matched to data stored at submit |
pagehide |
Success | The page unloaded inside the submit window with no error showing (fallback) |
error_class |
Failure | The form gained the platform’s error class |
Install it in Google Tag Manager
- Download the GTM tag above, or copy
squarespace-form-tracker.gtm.htmlfrom the GitHub repository. - In GTM, create a Custom HTML tag and paste the file in. It already includes the
<script>wrapper and a production config block (debug: false,rawFields: false). - Trigger it on All Pages (Page View), or on Consent Initialization if your consent setup needs the tracker available early. Load it as early as you can: the network check must be in place before the first submission.
- Create a Custom Event trigger for
squarespace_form_success. Use the regex^squarespace_form_(success|failed)$if you also want failures. - Create Data Layer Variables for the keys you need, then attach your GA4, Google Ads, Meta or server-side GTM tags to the trigger.
- Open Preview, submit a real test form and confirm one
squarespace_form_success. Then publish.
Retire any old click or thank-you page conversion for the same form, otherwise each lead is counted twice. Do not run this listener and the Universal tag on the same page.
Platform notes
- Only requests to
/api/form/are inspected. Other network calls pass straight through. - Third-party embeds on Squarespace (Typeform, Jotform, HubSpot) are not covered. Use the Jotform listener for Jotform.
- Storage is namespaced (
ec_squarespace_form_data), so it can run next to the other single-platform listeners.
Events and dataLayer keys
| Key | What it holds |
|---|---|
event |
squarespace_form_success, squarespace_form_failed, ec_form_interaction (first real input) or ec_tracker_initialized (script loaded) |
ec_event_id |
UUID per event. Pass it to Meta as the event ID so browser and CAPI events deduplicate |
ec_detection_method |
Which success or failure path fired (see above) |
ec_email, ec_phone |
Email lowercased and validated, phone in E.164. Removed when PII consent is denied |
ec_name, ec_first_name, ec_last_name |
Name, split into first and last where possible |
ec_company, ec_street, ec_city, ec_region, ec_postal_code, ec_country |
Address and company fields for Enhanced Conversions, when the form has them |
form_id, form_platform, form_cta |
Form identifier, platform name and submit button text |
ec_submit_attempt, ec_time_to_submit_s, ec_fast_submit |
Attempt number, time from first input to submit, and a bot hint for very fast submits |
ec_failed_fields |
On failure events: which fields failed validation |
ec_first_source, ec_last_source, ec_click_id |
First and last touch attribution with gclid, gbraid, wbraid, fbclid, msclkid or ttclid |
ec_pii_redacted |
true when PII consent is denied and PII keys were stripped |
Using it for Enhanced Conversions and Meta CAPI
- Google Ads Enhanced Conversions: map
ec_email,ec_phoneand the name and address keys into a User-Provided Data variable on your conversion tag. - Meta Pixel and CAPI: send
ec_event_idas the event ID on both the browser and server event so Meta counts the lead once. - GA4: do not send
ec_*PII to GA4. Its terms prohibit PII in event parameters. Sendform_id,form_platformandec_detection_methodinstead.
Configuration and consent
Edit the config block at the top of the tag:
| Key | Default | Notes |
|---|---|---|
debug |
false |
Console logs. Testing only |
hashPii |
false |
Adds ec_email_sha256 and ec_phone_sha256 (needs HTTPS) |
rawFields |
false |
Leaves ec_raw_fields out of the payload |
dedupe |
true |
Suppresses a repeat success for the same form and person within 5 minutes |
strictSuccess |
false |
true drops inferred successes (pagehide, form_removed) |
defaultCountryCode |
'1' |
Phone E.164 fallback. A country field on the form takes priority |
countryCodeField |
'' |
Exact field name that holds an ISO2 or dial code |
redactFields |
[] |
Extra field names to strip. Password, card, SSN and IBAN fields are always stripped |
The tracker auto-detects Google Consent Mode v2, OneTrust and Cookiebot. With analytics consent denied, nothing fires and nothing is stored, and events raised in the meantime are replayed if consent is granted. With PII consent denied, events fire without contact data. Any other CMP can be wired in with window.EC_FORM_CONSENT_CHECK. If no CMP or override is found, the tracker assumes full consent, so match it to your own legal requirements.
Test it before you publish
- Submit a valid form. Expect one
squarespace_form_success. - Submit with a required field empty. Expect
squarespace_form_failedand no success event. - Fix the error and resubmit. Expect one success.
- Refresh the confirmation or thank-you page. Expect nothing new.
- Run
window._ecFormTrackers.squarespace.status()in the console to see version, consent state, attached forms and the last event.
Known limitations
- Squarespace can change its form endpoint or markup. Test after major platform updates.
- A redirect to a different domain cannot use same-domain recall.
- Bot or spam submissions that pass the platform’s own validation still count as success.
- Phone normalization is best-effort.
Changelog
- 3.3.0: first public standalone release, cut from the Universal tracker v3.3.0. Same core: consent gate with replay, PII redaction, optional SHA-256 hashing, 5-minute dedupe,
ec_event_id, attribution, failure diagnostics andstrictSuccess.