Formulaires HubSpot

Un formulaire Webflow natif, dessiné et stylé dans le Designer, envoie ses soumissions à un formulaire HubSpot : tous les types de champs (texte, e-mail, téléphone, texte multiligne, liste, boutons radio, cases à cocher), propriétés de contact ou d'entreprise, et les UTM. Sans iframe, sans surcharge CSS, sans l'app HubSpot de Webflow.

Principes d'intégration

  • Une ligne de script, une fois par site (Site settings → Custom code → Footer). Il est hébergé par opendata : ses évolutions arrivent avec chaque déploiement, sans rien recoller dans Webflow. Seuls les formulaires qui portent data-hs-form sont concernés : les autres ne changent pas.
  • Le formulaire : sur le Form Block (ou l'élément Form), un attribut personnalisé data-hs-form dont la valeur est le GUID du formulaire HubSpot, visible dans l'URL de son éditeur (…/forms/7214011/…/<GUID>).
  • Les champs : un champ dont le Name Webflow est dans la liste ci-dessous part tout seul. Sinon, un attribut data-hs-property nomme la propriété HubSpot, comme HubSpot l'écrit : 0-1/… pour un contact, 0-2/name pour le nom d'entreprise. Pour un groupe de boutons radio, il se pose sur le bloc qui les contient. Les champs sans correspondance ne sont pas envoyés.
  • Listes et boutons radio : la valeur de chaque option (Value d'une option de Select, Choice value d'un bouton radio) doit être exactement la valeur interne HubSpot, accents compris (75 - Paris, Oui…). Une case seule envoie true ; plusieurs cases pour une même propriété envoient leurs data-hs-value séparées par ;.
  • Les UTM : rien à ajouter dans le formulaire. Le script envoie les UTM de l'URL de la page, sinon les derniers mémorisés par le site (localStorage['utm'], comme sur iroko.eu). Un champ caché utm_* déjà présent dans un formulaire reste prioritaire.
  • Côté HubSpot : le formulaire doit contenir chaque propriété envoyée pour qu'elle soit enregistrée, y compris les UTM en champs cachés. Une propriété absente est ignorée sans erreur par un formulaire du nouvel éditeur ; un formulaire de l'ancien éditeur refuse l'envoi, et le script le renvoie alors une fois sans les UTM : le contact arrive toujours, seules les UTM sont perdues.
  • Ne rien renommer : les ids de formulaires et les noms de champs sont lus par GTM (Webmarketer, conversions). Les champs cachés UTM et ndrstnd des formulaires existants restent en place ; ndrstnd n'est jamais envoyé à HubSpot.
  • Le message affiché suit HubSpot : le script n'annule pas la soumission, Webflow garde son état de chargement, sa redirection et une copie de chaque soumission. Mais c'est la réponse de HubSpot qui décide du message du Form Block : succès, le formulaire laisse place à son message de succès ; refus, le formulaire reste affiché avec son message d'erreur, même si Webflow répond après. Un visiteur ne lit jamais « merci » pour un contact que HubSpot n'a pas reçu. L'envoi part avec la page, son titre et le cookie HubSpot du visiteur ; les champs vides ne sont jamais envoyés, pour ne rien effacer dans HubSpot.
  • Construire les champs dans le Designer : un champ créé par l'API Webflow (MCP) est publié avec un nom générique (field, field-2…) quel que soit le nom saisi. Si c'est arrivé, changer le Name dans le Designer pour une autre valeur, valider, puis remettre le bon.
  • Migration depuis l'app HubSpot de Webflow : retirer la correspondance de l'app pour ce formulaire. Tant qu'elle existe, le script ignore le formulaire, pour éviter les doublons.
  • Pas de doublon avec la capture de HubSpot : le code de suivi HubSpot capture aussi les formulaires externes (« collected forms »). Le script en retire les formulaires qu'il envoie (attribut data-hs-do-not-collect, posé automatiquement) : un seul envoi par soumission, rien à faire dans Webflow.
  • Suivi : chaque envoi déclenche sur le formulaire un événement iroko:hubspot-submit (ok, status, errors), et une erreur s'affiche dans la console du navigateur.

Script à ajouter (une fois par site)

Code à copier‑coller :

Attributs à poser dans Webflow (Custom attributes)

<!-- Form Block (ou l'élément Form) -->
data-hs-form="b3db3e7c-05c2-4fd1-adc7-64955f0571f2"

<!-- Un champ dont le nom n'est pas dans la liste ci-dessous -->
data-hs-property="0-1/lieu_departement_france"

<!-- Un nom d'entreprise : propriété d'entreprise (0-2) -->
data-hs-property="0-2/name"

<!-- Un groupe de boutons radio : sur le bloc qui les contient -->
data-hs-property="0-1/accompagnement_cgp"

<!-- Plusieurs cases pour une même propriété : la valeur de chaque case -->
data-hs-value="scpi"

Noms de champs reconnus sans attribut

Le Name du champ dans Webflow suffit. Pour tout autre champ, ajouter data-hs-property.

Name Webflow Propriété HubSpot
email 0-1/email
email-4 0-1/email
consentement_emails 0-1/consentement_initial_communication_email
firstname 0-1/firstname
lastname 0-1/lastname
phone 0-1/phone
message 0-1/message
type_document 0-1/type_document
type_document-2 0-1/type_document
utm_source 0-1/utm_source
utm_medium 0-1/utm_medium
utm_campaign 0-1/utm_campaign
utm_content 0-1/utm_content

Avant la mise en ligne

  1. Le formulaire HubSpot contient toutes les propriétés envoyées, UTM compris, et ses champs obligatoires existent dans Webflow.
  2. Les valeurs des listes et boutons radio sont celles de HubSpot.
  3. La correspondance de l'app HubSpot de Webflow est retirée pour ce formulaire.
  4. Sur le staging publié, l'envoi capturé sans le laisser partir (tout POST bloqué) : bon GUID, toutes les propriétés, UTM. L'anti-spam Turnstile de Webflow bloque les navigateurs automatisés : pour ce contrôle, réactiver le bouton par script.
  5. Un envoi réel uniquement vers le formulaire HubSpot de test (test_form_wf_opendata), jamais vers le formulaire réel (workflows, notifications) : contact à jour, UTM présents, une seule conversion, message de succès affiché.