Guides

Guides18 min de lecture

Ajouter un formulaire de feedback à votre site ou à votre application

Placez un formulaire de feedback sur n'importe quelle page ou dans votre application : une note, un commentaire, la page d'origine, le filtrage du spam et des alertes quand une note est basse.

Preet SutharFondateur, Ikiform

Ajoutez un court formulaire avec une note de 1 à 5, un commentaire facultatif et un e-mail facultatif, et envoyez-le à un backend de formulaires pour ne pas gérer de serveur. Envoyez l'adresse de la page avec chaque réponse, car le navigateur ne vous donnera pas l'URL complète de lui-même. Faites remonter les notes basses dans le chat de votre équipe le jour même et gardez toutes les réponses au même endroit pour suivre les tendances.

La plupart des gens ne vous disent jamais ce qui ne va pas sur votre site. Ils partent. Un petit formulaire de feedback capte les quelques personnes qui le diront, au moment où elles le remarquent, sur la page en cause. Ce guide en construit un qui s'adapte à n'importe quel site ou application, envoie la page d'origine, bloque les bots et met les réponses mécontentes sous les yeux de votre équipe le jour même.

Comment fonctionne un formulaire de feedback

Le formulaire envoie à Ikiform. Ikiform valide la note, vérifie que l'envoi n'est pas du spam, le stocke, envoie un e-mail à votre équipe et un webhook signé. À partir du webhook, les notes basses vont dans un canal de chat et chaque réponse peut aller dans un tableur ou une base de données.

Le trajet d'un feedback, de votre page à votre équipen'importequelle pageou écrannote,commentaire,adresse de lapageIkiformvalide, filtrele spam, stocketableau debordfiltre parformulaire etdate, exportCSVe-mail denotificationà l'équipe, laréponse va auvisiteurwebhooksignésubmission.createdavec champs etmetachatd'équipeseulement lesnotes 1 ou 2envoirelaisLe trajet d'un feedback, de votre page à votre équipen'importequelle pageou écrannote,commentaire,adresse de lapageIkiformvalide, filtrele spam, stocketableau de bordfiltre parformulaire et date,export CSVe-mail denotificationà l'équipe, laréponse va auvisiteurwebhook signésubmission.createdavec champs et metachat d'équipeseulement les notes1 ou 2envoirelais
  1. Un visiteur choisit une note, écrit éventuellement un commentaire, et le formulaire l'envoie avec l'adresse de la page.
  2. Ikiform vérifie que la note est un nombre entier de 1 à 5, lance les vérifications anti-spam et stocke la réponse.
  3. La réponse apparaît dans le tableau de bord, où vous pouvez la filtrer et l'exporter en CSV.
  4. Ikiform envoie un e-mail à votre équipe. Quand le visiteur a laissé son e-mail, Répondre lui écrit directement.
  5. Ikiform envoie un webhook submission.created signé avec les champs et les métadonnées du navigateur.
  6. Un petit relais ne publie que les notes basses dans le chat de votre équipe, pour qu'elles soient lues aujourd'hui.
Le relais est facultatif. Commencez par l'e-mail et le tableau de bord, et ajoutez l'alerte dans le chat quand les réponses commencent à s'accumuler.

Les façons de recueillir du feedback

Chaque type d'outil sert un usage différent. Choisissez selon ce que vous devez voir quand une réponse arrive, pas selon l'apparence du widget.

ApprochePoints fortsCompromis
Outils de feedback pour sites web, comme Hotjar ou UsersnapCaptures d'écran, annotations et contexte de la page, sans autre code qu'une balise script.Un script tiers sur chaque page, des réponses stockées dans leur produit et des prix fixés par leurs offres.
Le widget d'un outil de suivi d'erreurs, comme Sentry User FeedbackRelie un signalement à l'erreur et, avec le session replay activé, à un enregistrement de ce qui s'est passé.Conçu pour les bugs, pas pour les avis. Il faut d'abord le SDK de l'outil dans votre application.
Les créateurs de formulaires, comme Typeform, Tally ou Google FormsDes formulaires soignés sans code. Bien pour une enquête envoyée par lien.Une iframe ou une page à part : la réponse perd donc la page dont elle parle, sauf si vous la passez dans l'URL.
Les tableaux de feedback, comme CannyVote public et suivi de l'avancement des demandes de fonctionnalités.Conçu pour les idées, pas pour les réactions rapides. Les réponses sont publiques par principe.
Votre propre route API et votre base de donnéesContrôle total sur les données et toute la logique.Vous construisez vous-même le filtrage du spam, les limites de débit, l'e-mail de notification et l'export, et il vous faut un serveur.
Un backend de formulaires, comme IkiformVotre propre markup sur n'importe quel site ou application. Validation, filtrage du spam, stockage, e-mail et webhooks signés, sans serveur.Pas de captures d'écran, car l'envoi de fichiers n'est pas pris en charge, ni de vote ou de session replay.

Si vous avez besoin de captures d'écran sur chaque signalement, un outil de feedback ou de suivi d'erreurs justifie son script. Si vous voulez un formulaire à l'image de votre site, des réponses portables et décider vous-même où elles vont, utilisez un backend de formulaires. C'est ce que fait la suite de ce guide.

Le formulaire

Trois questions suffisent : une note, un commentaire et un e-mail facultatif. La note, c'est ce à quoi les gens répondent ; le commentaire, c'est là qu'est la valeur ; l'e-mail, c'est ce qui vous permet de leur répondre. Choisissez votre stack ci-dessous ; ce choix s'applique à tous les exemples de code de ces guides.

Un seul bloc de markup et un court script. Sans JavaScript, le formulaire envoie quand même et redirige ; avec, le visiteur reste sur la page et voit l'erreur du serveur à côté du bouton. Le script remplit page avec l'adresse sans les paramètres d'URL, pour que les tokens présents dans les URL n'arrivent jamais dans votre boîte de réception.

feedback.html
<form id="feedback" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post">
  <fieldset>
    <legend>How useful was this page?</legend>
    <label><input type="radio" name="rating" value="1" required /> 1</label>
    <label><input type="radio" name="rating" value="2" /> 2</label>
    <label><input type="radio" name="rating" value="3" /> 3</label>
    <label><input type="radio" name="rating" value="4" /> 4</label>
    <label><input type="radio" name="rating" value="5" /> 5</label>
  </fieldset>
  <label for="comment">What would make it better?</label>
  <textarea id="comment" name="comment" rows="4" maxlength="4000"></textarea>
  <label for="feedback-email">Email, if you'd like a reply</label>
  <input id="feedback-email" name="email" type="email" />
  <input type="hidden" name="page" />
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
  <button>Send feedback</button>
  <p id="feedback-status" role="status"></p>
</form>

<script>
  const form = document.getElementById("feedback");
  const status = document.getElementById("feedback-status");
  form.elements.page.value = location.origin + location.pathname;

  form.addEventListener("submit", async (event) => {
    event.preventDefault();
    const button = form.querySelector("button");
    button.disabled = true;
    status.textContent = "Sending";
    try {
      const response = await fetch(form.action, {
        method: "POST",
        headers: { Accept: "application/json" },
        body: new FormData(form),
      });
      const result = await response.json();
      if (result.ok) {
        form.replaceChildren(Object.assign(document.createElement("p"), { textContent: "Thanks. The team reads every note." }));
        return;
      }
      const fields = result.error.fields ?? {};
      status.textContent = fields.rating?.[0] ?? fields.comment?.[0] ?? fields.email?.[0] ?? result.error.message;
    } catch {
      status.textContent = "Couldn't send it. Try again in a moment.";
    }
    button.disabled = false;
  });
</script>
  • Remplacez frm_xxxxxxxxxxxxxxxx par l'id de votre formulaire, visible dans le tableau de bord.
  • rating est un groupe de cinq boutons radio. Ikiform le stocke comme un nombre, donc les moyennes ne demandent aucun parsing.
  • email est facultatif. Les gens écrivent plus franchement quand ils n'ont pas à s'identifier, et ceux qui veulent une réponse le laisseront.
  • L'input masqué _gotcha est le honeypot. Les humains ne le voient jamais ; les bots qui remplissent tous les inputs se signalent eux-mêmes comme spam.
  • page enregistre la page dont parle la réponse. La section suivante explique pourquoi vous l'envoyez vous-même.
Les versions côté serveur envoient avec une clé secrète, donc Ikiform ignore Allowed domains et sa vérification humaine. Chaque envoi vient alors de l'IP de votre serveur, et la limite Standard de 5 par minute et par visiteur compte tous vos visiteurs ensemble. Choisissez la limite de débit Relaxed ou Custom pour un formulaire que vous envoyez via un serveur, et gardez IKIFORM_SECRET_KEY dans des variables d'environnement réservées au serveur.

Les guides par framework de la documentation détaillent la mise en place : Next.js, Astro, SvelteKit, Nuxt, React, Vue et HTML simple. Le modèle de formulaire de feedback génère les mêmes champs en HTML, en React et en server action ; les modèles de signalement de bug et d'enquête couvrent les formulaires plus longs.

Définir les champs

Collez une définition dans l'onglet Fields du formulaire et Ikiform l'applique à chaque envoi, depuis n'importe quelle page. Essayez ci-dessous : l'aperçu exécute le validateur d'Ikiform dans votre navigateur, donc une note de 0 ou un e-mail mal formé affiche le 422 que vous recevriez.

Aperçu

Exécute le validateur d'Ikiform dans votre navigateur. Rien n'est envoyé.

Cette page vous a-t-elle été utile ?

Rempli par le script avec l'adresse de la page, sans les paramètres d'URL.

Un rating accepte un nombre entier de 1 à son max, ici 5. Il peut aller jusqu'à 10, mais cinq choix sont plus rapides.
ChampTypePourquoi
ratingrating, max 5Un clic. Stocké comme un nombre, pour faire la moyenne par page
commenttextarea, jusqu'à 4 000 caractèresLa raison derrière la note
emailemail, facultatifRépondre aux personnes qui posent une question. Devient l'adresse de réponse de la notification
pageurl, facultatifLa page dont parle la réponse

Une fois les champs définis, tout autre nom dans l'envoi est refusé avec Unknown field. Si plus tard vous envoyez plus de contexte, comme une version d'application ou un nom d'offre, ajoutez d'abord un champ pour lui. Les id de champ sont en snake_case minuscule.

Savoir de quelle page il s'agit

Une note sans page est difficile à exploiter. Ikiform enregistre les métadonnées du navigateur avec chaque soumission, mais l'une de ces valeurs est moins utile qu'elle n'en a l'air :

ValeurD'où elle vientCe que vous obtenez
meta.user_agentEnregistré par IkiformLe navigateur et le système d'exploitation, depuis un envoi du navigateur
meta.originEnregistré par IkiformL'origine de votre site, comme https://example.com
meta.referrerEnregistré par IkiformGénéralement l'origine seule. Les navigateurs appliquent par défaut la politique strict-origin-when-cross-origin, qui supprime le chemin lors d'un envoi vers un autre site
meta.countryEnregistré par IkiformUn code pays à deux lettres
pageEnvoyé par votre formulaireLe chemin complet, pour savoir de quelle page parle la réponse

C'est pourquoi chaque exemple ci-dessus envoie page lui-même. Les versions HTML et SPA lisent location ; les versions serveur lisent l'adresse que leur framework connaît déjà. Toutes suppriment les paramètres d'URL, qui peuvent contenir des termes de recherche, des id de suivi ou des tokens à usage unique que vous ne voulez pas stocker.

Les versions serveur envoient depuis votre serveur, donc meta.user_agent est le runtime de votre serveur, pas le navigateur du visiteur. Pour le feedback sur une page, c'est rarement important. Pour les signalements de bug, ça l'est, et le guide du signalement de bug transmet le user agent du navigateur dans un champ.

Où poser la question

L'emplacement du formulaire détermine ce que vous entendez. Un formulaire dans le pied de page de chaque page reçoit un filet d'avis tranchés. Une question à la fin d'une tâche reçoit des réponses régulières et précises.

EmplacementIdéal pourPoints de vigilance
Fin d'une page de documentation ou d'un articleRepérer les pages qui ne répondent pas à la questionPeu de réponses par page. Lisez-les par section, pas par page
Après une tâche dans votre application, comme un export ou un premier projetLe ressenti d'un parcours précis, tant qu'il est fraisDemandez une fois par personne, pas à chaque fois qu'elle termine la tâche
Un bouton flottant sur chaque écranN'importe quoi, n'importe quand. Voir le widget ReactIl ne doit pas masquer vos propres boutons, bannières de cookies ou bulles de chat
Un lien dans un e-mailLes scores à suivre dans le temps, comme le NPSLe client e-mail n'est pas votre page : le formulaire a donc besoin d'une page d'atterrissage sur votre site

Gardez le formulaire court, où qu'il soit. Demandez d'abord la note et affichez le champ de commentaire avec, pas dans une deuxième étape. Une deuxième étape fait fuir la plupart des gens, et une note sans raison reste utile.

Mettre les notes basses sous les yeux de quelqu'un

Ce qui arrive à une réponse selon sa noteréponsestockéetoutes notes,toutes pageswebhooksubmission.createdlerelaislit lanote3, 4 ou 5 :rien deplusrevuehebdomadairemoyennes parpage depuis leCSVchatd'équipenote, page,commentairequelqu'unrépondsi un e-mail aété laissésignéexport1 ou 2Ce qui arrive à une réponse selon sa noteréponse stockéetoutes notes, toutespageswebhooksubmission.createdle relaislit la note3, 4 ou 5 : riende plusrevuehebdomadairemoyennes par pagedepuis le CSVchatd'équipenote, page,commentairequelqu'unrépondsi un e-maila été laissésignéexport1 ou 2
  1. Chaque réponse est stockée, quelle que soit sa note et la page d'où elle vient.
  2. Ikiform envoie un webhook submission.created signé à votre relais.
  3. Le relais lit la note. Les notes de 3 à 5 ne demandent rien de plus dans l'immédiat.
  4. Une note de 1 ou 2 part dans le chat de votre équipe avec la page et le commentaire.
  5. Si le visiteur a laissé son e-mail, quelqu'un lui répond le jour même.
  6. Une fois par semaine, l'export donne les moyennes par page, et c'est là que les tendances apparaissent.
N'alertez que sur les mauvaises notes. Un canal qui sonne pour chaque 5 sur 5 est mis en sourdine en une semaine.

Les e-mails de notification vont à 10 destinataires confirmés au plus par formulaire et arrivent pour chaque réponse. Ça convient pour quelques réponses par jour. Au-delà, envoyez les notes basses dans le chat avec un relais comme cette route Next.js ; le même code tourne dans un Cloudflare Worker :

app/api/feedback-alerts/route.ts
import { verifyWebhook, WebhookVerificationError } from "@ikiform/sdk/webhooks";

export async function POST(request: Request) {
  const payload = await request.text();
  try {
    const event = await verifyWebhook({
      payload,
      headers: request.headers,
      secret: process.env.IKIFORM_WEBHOOK_SECRET!,
    });
    if (event.type !== "submission.created") return new Response(null, { status: 204 });
    const { rating, comment, page, email } = event.data.fields;
    if (Number(rating) > 2) return new Response(null, { status: 204 });

    const lines = [
      `*${rating}/5* on ${page ?? event.data.meta.origin ?? "an unknown page"}`,
      comment ? `> ${String(comment).slice(0, 500)}` : "_No comment._",
      email ? `Reply to ${email}` : "Anonymous",
    ];
    const response = await fetch(process.env.SLACK_WEBHOOK_URL!, {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ text: lines.join("\n") }),
    });
    if (!response.ok) return new Response(`Slack answered ${response.status}`, { status: 502 });
    return new Response(null, { status: 204 });
  } catch (error) {
    if (error instanceof WebhookVerificationError) return new Response(error.reason, { status: 400 });
    throw error;
  }
}
  • verifyWebhook vérifie la signature et l'horodatage, pour que personne d'autre ne puisse publier dans votre canal via cette URL.
  • Les notes supérieures à 2 répondent 204 et s'arrêtent là. Ikiform considère tout 2xx comme livré.
  • Un appel Slack en échec répond 502, et Ikiform réessaie avec le même webhook-id : une courte panne ne fait donc pas perdre d'alerte.
  • Les valeurs des champs sont ce que le visiteur a tapé. Le relais coupe le commentaire à 500 caractères avant qu'il n'arrive dans le chat.

Ajoutez l'endpoint sous Webhooks et copiez son secret whsec_ dans IKIFORM_WEBHOOK_SECRET. Un espace de travail peut avoir 3 endpoints. Pour des routes sans code, voyez Slack, Discord et Google Sheets. Pour un feedback qui doit devenir un ticket, Linear et GitHub Issues propose un relais qui en crée un par soumission.

Il n'y a pas d'intégrations en un clic. Chaque outil est atteint par un webhook signé, directement ou via un outil d'automatisation comme Zapier ou n8n.

Tenir les bots à l'écart

Un formulaire de feedback sur chaque page, c'est un formulaire public sur chaque page. Les bots le trouvent, et ils envoient surtout des liens. Les réglages par défaut d'Ikiform en gèrent l'essentiel :

DéfenseCe qu'elle arrêteConfiguration
HoneypotLes bots qui remplissent tous les inputsL'input masqué _gotcha des exemples
Score de spamTrois liens ou plus (+2), phrases de spam connues (+2), e-mails jetables (+2), répétitions identiques (+3). À 5, c'est stocké comme spamAucun
Limites de débitLes scripts qui envoient en boucleActivée par défaut : Standard, 5 par minute et par visiteur, et 300 par minute pour l'ensemble du formulaire
Domaines autorisésLes envois depuis d'autres sitesAjoutez votre domaine dans les réglages du formulaire
Vérification humaineLes bots qui pilotent un vrai navigateurRéglez Spam check sur Ikiform. Les envois fetch du navigateur ont alors besoin d'un token de challenge()

Le spam reçoit la même réponse de succès qu'un vrai envoi, ne déclenche ni e-mail ni webhook et ne compte pas dans l'utilisation. Un vrai visiteur qui colle trois liens dans un commentaire peut déclencher la règle des liens en même temps qu'une répétition : jetez donc un œil au filtre Spam de temps en temps. Marquer une réponse comme non-spam envoie alors son webhook. La documentation anti-spam explique chaque vérification.

Lire les réponses

Lisez chaque commentaire les premières semaines. Ensuite, la vue utile est la note moyenne par page, la plus basse en premier, avec les commentaires à côté.

Export

Ouvrez Submissions, choisissez le formulaire de feedback, une période, puis Export CSV. Les colonnes sont id, created_at, form et status, puis une par champ : avec les champs ci-dessus, rating est la colonne E et page la colonne H. Un export contient jusqu'à 100 000 lignes ; le guide d'export présente l'API pour aller au-delà.

Importez le fichier dans Google Sheets et mettez ceci dans une feuille vide. Il liste chaque page avec sa note moyenne et son nombre de réponses, de la pire à la meilleure :

Google Sheets
=QUERY(A2:H, "select H, avg(E), count(E) where D = 'received' and E is not null group by H order by avg(E) asc label avg(E) 'average', count(E) 'answers'", 0)
  1. Ignorez les pages qui n'ont qu'une ou deux réponses. Un visiteur en colère ne fait pas une tendance.
  2. Lisez les commentaires des trois pages les moins bien notées. La correction se trouve généralement dans les premiers.
  3. Après avoir modifié une page, comparez sa moyenne sur les semaines d'avant et d'après, pas la moyenne globale.
Le feedback n'est pas anonyme pour Ikiform, même sans e-mail : chaque réponse enregistre le user agent, l'origine, le referrer et le pays, ainsi qu'un hash de l'IP qui n'est jamais renvoyé. Indiquez ce que vous collectez dans votre politique de confidentialité.

Choisissez votre cas

Le formulaire ci-dessus couvre les réactions rapides sur n'importe quelle page. Ces pages-ci couvrent le feedback qui a un autre rôle : un bug à reproduire, une demande à évaluer, un score à suivre ou un client sur le départ.

Vérifiez que tout fonctionne

Faites ces vérifications avant de mettre le formulaire sur chaque page. Ikiform n'a pas d'offre gratuite. Les tests sont gratuits : un espace de travail sans offre accepte 50 soumissions de test par mois depuis localhost. Pour passer en production, choisissez Pro à partir de 6 $/mois pour 500 soumissions, ou payez une seule fois : 10 000 soumissions pour 49 $ ou 50 000 soumissions pour 149 $, avec des crédits qui n'expirent jamais. Voir les tarifs.

  1. Dans Allowed domains du formulaire, ajoutez le domaine de votre site, plus localhost pendant le développement. Laissez vide pour accepter les envois de partout.
  2. Choisissez une note, écrivez un commentaire et envoyez. La ligne de remerciement remplace le formulaire, ou le navigateur arrive sur votre page de redirection pour la version HTML simple.
  3. Ouvrez Submissions dans le tableau de bord. La réponse affiche rating comme un nombre et page avec le chemin complet.
  4. Envoyez une note de 6 avec curl ou la console du navigateur. Ikiform répond 422 en nommant rating.
  5. Vérifiez la boîte de réception de chaque destinataire des notifications. Chacun reçoit un e-mail avec les champs, et Reply répond à l'expéditeur quand le formulaire a un champ email.
  6. Envoyez une note de 1. Votre relais la publie dans le chat de l'équipe, et la livraison sous Webhooks affiche succeeded.
  7. Envoyez avec le honeypot rempli, _gotcha=bot. L'envoi reçoit quand même une réponse de succès, mais la soumission est stockée comme spam et n'envoie ni e-mail ni webhook.
  8. Rien n'est arrivé ? Passez le filtre de statut du tableau de bord sur Spam. Le spam reçoit la même réponse de succès qu'une vraie soumission.

Dépannage

ProblèmeQue faire
403 origin_not_allowed, ou tous les envois finissent en spamLe domaine de la page n'est pas dans les Allowed domains du formulaire. Ajoutez-le, plus localhost pour les tests en local. Les sous-domaines d'un domaine listé sont autorisés.
422 avec Rating must be at most 5Le formulaire envoie une note supérieure au max du champ. Changez les valeurs des boutons radio ou augmentez max dans la définition, jusqu'à 10.
422 avec un Unknown fieldLe formulaire envoie un nom absent de la définition, souvent un nouvel input masqué. Ajoutez un champ avec cet id, ou supprimez l'input.
page est videLe script qui le remplit ne s'est pas exécuté, ou s'est exécuté avant que le formulaire n'existe. Placez-le après le formulaire, ou renseignez page au moment de l'envoi comme le font les exemples SPA.
meta.referrer n'affiche que votre domaineC'est normal. Par défaut, les navigateurs n'envoient que l'origine sur les envois cross-site. Utilisez plutôt le champ page.
La soumission est dans le tableau de bord mais aucun e-mail ni webhook n'est arrivéElle a été stockée comme spam. Le spam n'envoie rien. Ouvrez-la sous le filtre Spam pour voir les raisons, et marquez-la comme non-spam pour envoyer son e-mail et ses webhooks.
429 rate_limitedUn visiteur a envoyé plus que ce que permet la limite de débit du formulaire. Standard autorise 5 envois par minute et par visiteur. Attendez la durée de Retry-After, ou choisissez Relaxed ou Custom pour les formulaires qui envoient depuis une seule IP partagée.
402 test_limit_reachedL'espace de travail n'a pas d'offre et a utilisé ses 50 tests gratuits depuis localhost ce mois-ci. Choisissez une offre, ou utilisez Send test dans le tableau de bord.

Questions

Une étape vous bloque, ou vous voulez un guide pour votre cas ? Écrivez à hello@ikiform.com.