800 kilo-octets de JavaScript et de CSS supplémentaires, rien que pour afficher un formulaire de trois champs : c’est ce que chargeait l’iframe HubSpot Forms intégrée initialement sur une template part de contact partagée par plusieurs pages d’un site de conseil en recrutement, avant qu’on ne remplace cette intégration par un appel direct à l’API HubSpot.
Ce billet décrit l’appel direct à l’API HubSpot depuis une template part de formulaire, avec la gestion explicite des erreurs de validation renvoyées par l’API, en remplacement d’une iframe jugée trop lourde pour un formulaire aussi simple. Les workflows marketing HubSpot et la configuration du pipeline commercial ne sont pas traités ici.
Le problème posé par l’iframe HubSpot Forms
L’iframe fournie par défaut par HubSpot charge l’intégralité de sa bibliothèque de rendu de formulaire, pensée pour couvrir des cas d’usage bien plus riches (formulaires conditionnels, calculs de score, personnalisation avancée) que le simple formulaire de contact utilisé ici. Sur un site où la performance de chargement était un objectif affiché du projet, ce poids supplémentaire posait un problème mesurable, en particulier sur mobile.
La template part parts/formulaire-contact.html, réutilisée sur cinq pages du site (accueil, contact, trois pages de service), a été reconstruite avec des champs HTML natifs et un appel direct à l’API de création de contact HubSpot, déclenché en JavaScript à la soumission.
Construire la template part

<!-- wp:group {"className":"wpm-contact-form"} -->
<div class="wp-block-group wpm-contact-form">
<form id="wpm-contact-hubspot">
<input type="text" name="lastname" placeholder="Nom" required />
<input type="email" name="email" placeholder="Adresse courriel" required />
<textarea name="message" placeholder="Votre message" required></textarea>
<button type="submit">Envoyer</button>
</form>
<p id="wpm-contact-erreur" role="alert"></p>
</div>
<!-- /wp:group -->
Appeler l’API HubSpot et gérer les erreurs
Contrairement à un simple formulaire de capture de leads, la création de contact via l’API HubSpot Objects nécessite une authentification par jeton privé, ce qui impose de passer par un endpoint WordPress intermédiaire plutôt qu’un appel direct depuis le navigateur, pour ne jamais exposer ce jeton côté client.
add_action( 'rest_api_init', function() {
register_rest_route( 'wpm/v1', '/contact-hubspot', array(
'methods' => 'POST',
'callback' => 'wpm_creer_contact_hubspot',
'permission_callback' => '__return_true',
) );
} );
function wpm_creer_contact_hubspot( $request ) {
$email = sanitize_email( $request->get_param( 'email' ) );
if ( ! is_email( $email ) ) {
return new WP_REST_Response( array( 'erreur' => 'Adresse courriel invalide' ), 400 );
}
$reponse = wp_remote_post( 'https://api.hubapi.com/crm/v3/objects/contacts', array(
'headers' => array(
'Authorization' => 'Bearer ' . WPM_HUBSPOT_TOKEN,
'Content-Type' => 'application/json',
),
'body' => wp_json_encode( array(
'properties' => array(
'email' => $email,
'lastname' => sanitize_text_field( $request->get_param( 'lastname' ) ),
'message' => sanitize_textarea_field( $request->get_param( 'message' ) ),
),
) ),
) );
if ( is_wp_error( $reponse ) || 409 === wp_remote_retrieve_response_code( $reponse ) ) {
return new WP_REST_Response( array( 'erreur' => 'Ce contact existe déjà ou une erreur est survenue' ), 409 );
}
return new WP_REST_Response( array( 'succes' => true ), 200 );
}
Le code JavaScript côté template part
Le script associé affiche le message d’erreur retourné par l’endpoint directement dans la zone role="alert" prévue à cet effet, une gestion plus explicite que le comportement par défaut de l’iframe HubSpot, qui affichait des messages génériques peu adaptés à l’identité graphique du site.
- Le code 409, renvoyé lorsqu’un contact existe déjà avec cette adresse dans HubSpot, est traité spécifiquement pour afficher un message rassurant plutôt qu’une erreur technique brute.
- Un délai de trois secondes avant réactivation du bouton d’envoi limite les tentatives de soumissions répétées en cas d’erreur réseau temporaire.
- Le contenu du message reste transmis tel quel à HubSpot, sans traitement supplémentaire côté site : aucune donnée n’est conservée localement au-delà de la requête elle-même.
Une iframe fournie clé en main résout un problème d’intégration rapide, mais transfère souvent un coût de performance qu’un appel d’API direct permet d’éviter.
En résumé
Le remplacement de l’iframe HubSpot Forms par un appel d’API direct a demandé davantage de développement initial, mais a réduit sensiblement le poids de chargement des pages concernées, un gain particulièrement sensible sur les connexions mobiles visées par ce site. Cette approche demande en contrepartie une vigilance accrue sur la gestion des erreurs, entièrement à la charge du développeur plutôt que déléguée au widget fourni par le service tiers.