Formulaire RSVP (confirmation de présence)

Les invités confirment s’ils viennent, combien ils seront et leurs besoins alimentaires.

Vous utilisez Tilda ? Collez le code dans un bloc T123 (offre payante) ou utilisez le webhook sans code.

À quoi sert ce formulaire

Un formulaire RSVP répond à trois questions pour l’hôte : qui vient, combien de personnes, et ce qu’elles mangent. Tout le reste peut attendre le jour J.

Les questions sur les invités et le repas n’apparaissent qu’après un oui. Ceux qui ne peuvent pas venir répondent en deux clics et peuvent quand même laisser un mot.

Les champs qui comptent

Serez-vous présent ?
Oui ou non. Le reste du formulaire s’adapte à la réponse.
Combien de personnes ?
Affiché après un oui. Permet de prévoir les places et le traiteur.
Repas
Pas de préférence, végétarien ou végan. Affiché après un oui.
Nom et e-mail
Obligatoires, pour savoir qui a répondu et pouvoir envoyer des informations.

Aperçu

Votre réponse

Code du formulaire

HTML
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Formulaire RSVP (confirmation de présence)</title>
<style>
  body { font-family: "Segoe UI", sans-serif; color: #12263a; margin: 0; background: #fff; }
  main { max-width: 640px; margin: 0 auto; padding: 32px 20px 64px; }
  h1 { font-size: 28px; font-weight: 650; letter-spacing: -0.02em; line-height: 1.2; }
  h2 { font-size: 18px; margin: 18px 0 0; }
  p { line-height: 1.5; }
  form { display: grid; gap: 14px; position: relative; }
  .field { display: grid; gap: 6px; }
  label span, .check span { font-size: 14px; }
  input, select, textarea { font: inherit; color: inherit; padding: 10px 12px; border: 1px solid #b4bdce; border-radius: 8px; width: 100%; box-sizing: border-box; background: #fff; }
  textarea { min-height: 96px; }
  .check { display: flex; gap: 8px; align-items: flex-start; }
  .check input { width: auto; margin-top: 4px; }
  button { background: #3c4ad8; color: #fff; border: 0; border-radius: 8px; padding: 12px 18px; font: inherit; cursor: pointer; }
  .note { background: #fff6eb; padding: 12px 14px; border-radius: 8px; }
  form [data-show-if] { display: none; }
form:has(select[name="attending"] option[value="yes"]:checked) [data-show-if="attending"][data-show-equals="yes"] { display: grid; }
</style>
</head>
<body>
<main>
<h1 data-i18n="title">Formulaire RSVP (confirmation de présence)</h1>
<p data-i18n="lede">Les invités confirment s’ils viennent, combien ils seront et leurs besoins alimentaires.</p>


<form id="fg-form" action="https://formgong.com/submit" method="POST" enctype="multipart/form-data" data-sitekey="" data-lang="fr">
<input type="hidden" name="access_key" value="fk_your_access_key">
<input type="hidden" name="_lang" value="fr">
<div aria-hidden="true" style="position:absolute;inset-inline-start:0;top:0;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)"><label>Leave this field empty<input name="botcheck" tabindex="-1" autocomplete="off"></label></div>
<section><h2 data-i18n="section.reply">Your reply</h2>
<div class="field"><label for="fg-attending"><span data-i18n="attending">Will you attend?</span></label><select id="fg-attending" name="attending" required><option value="">—</option><option value="yes" data-i18n="attending.yes">Yes, I will be there</option><option value="no" data-i18n="attending.no">Sorry, I can't make it</option></select></div>
<div class="field" data-show-if="attending" data-show-equals="yes"><label for="fg-guests"><span data-i18n="guests">How many people?</span></label><input id="fg-guests" name="guests" type="number" min="1" max="10"></div>
<div class="field" data-show-if="attending" data-show-equals="yes"><label for="fg-food"><span data-i18n="food">Food</span></label><select id="fg-food" name="food"><option value="">—</option><option value="none" data-i18n="food.none">No preference</option><option value="vegetarian" data-i18n="food.vegetarian">Vegetarian</option><option value="vegan" data-i18n="food.vegan">Vegan</option></select></div>
<div class="field"><label for="fg-note"><span data-i18n="note">Anything else?</span></label><textarea id="fg-note" name="note" maxlength="500"></textarea></div>
<div class="field"><label for="fg-name"><span data-i18n="name">Name</span></label><input id="fg-name" name="name" type="text" required maxlength="80" autocomplete="name"></div>
<div class="field"><label for="fg-email"><span data-i18n="email">Email</span></label><input id="fg-email" name="email" type="email" required maxlength="120" autocomplete="email"></div></section>
<!-- Set data-sitekey on this form to YOUR_TURNSTILE_SITE_KEY. Required for attachments. -->
<div data-turnstile></div>
<button type="submit" data-i18n="submit">Envoyer</button>
<p data-status role="status"></p>
</form>
</main>
<script type="application/json" id="fg-labels">{"uk":{"title":"Форма RSVP (підтвердження участі)","lede":"Гості підтверджують, чи прийдуть, скільки їх буде і чи є побажання щодо їжі.","submit":"Надіслати","thanks":"Надіслано. Дякуємо.","file_too_big":"До 3 файлів, по 5 MiB, разом до 10 MiB.","error":"Не вдалося надіслати. Спробуйте ще раз.","section.reply":"Ваша відповідь","attending":"Ви прийдете?","attending.yes":"Так, я прийду","attending.no":"На жаль, не зможу","guests":"Скільки людей?","food":"Їжа","food.none":"Без побажань","food.vegetarian":"Вегетаріанське","food.vegan":"Веганське","note":"Щось ще?","name":"Ім'я","email":"Електронна пошта"},"en":{"title":"RSVP form","lede":"Guests confirm whether they are coming, how many, and any food needs.","submit":"Send","thanks":"Sent. Thank you.","file_too_big":"Up to 3 files, 5 MiB each and 10 MiB combined.","error":"Could not send. Please try again.","section.reply":"Your reply","attending":"Will you attend?","attending.yes":"Yes, I will be there","attending.no":"Sorry, I can't make it","guests":"How many people?","food":"Food","food.none":"No preference","food.vegetarian":"Vegetarian","food.vegan":"Vegan","note":"Anything else?","name":"Name","email":"Email"},"pl":{"title":"Formularz RSVP (potwierdzenie obecności)","lede":"Goście potwierdzają, czy przyjdą, ile osób i czy mają wymagania co do jedzenia.","submit":"Wyślij","thanks":"Wysłano. Dziękujemy.","file_too_big":"Do 3 plików, po 5 MiB, łącznie 10 MiB.","error":"Nie udało się wysłać. Spróbuj ponownie.","section.reply":"Twoja odpowiedź","attending":"Czy przyjdziesz?","attending.yes":"Tak, będę","attending.no":"Niestety nie dam rady","guests":"Ile osób?","food":"Jedzenie","food.none":"Bez preferencji","food.vegetarian":"Wegetariańskie","food.vegan":"Wegańskie","note":"Coś jeszcze?","name":"Imię","email":"E-mail"},"tr":{"title":"LCV formu (katılım onayı)","lede":"Konuklar gelip gelmeyeceklerini, kaç kişi olacaklarını ve yemek tercihlerini bildirir.","submit":"Gönder","thanks":"Gönderildi. Teşekkürler.","file_too_big":"En fazla 3 dosya, dosya başına 5 MiB, toplam 10 MiB.","error":"Gönderilemedi. Lütfen tekrar deneyin.","section.reply":"Yanıtınız","attending":"Katılacak mısınız?","attending.yes":"Evet, orada olacağım","attending.no":"Maalesef gelemeyeceğim","guests":"Kaç kişi?","food":"Yemek","food.none":"Tercih yok","food.vegetarian":"Vejetaryen","food.vegan":"Vegan","note":"Başka bir şey?","name":"Ad","email":"E-posta"},"ar":{"title":"نموذج تأكيد الحضور (RSVP)","lede":"يؤكد الضيوف حضورهم وعددهم وأي احتياجات غذائية.","submit":"إرسال","thanks":"تم الإرسال. شكرًا لك.","file_too_big":"حتى 3 ملفات، 5 MiB لكل ملف و10 MiB إجمالًا.","error":"تعذّر الإرسال. يُرجى المحاولة مرة أخرى.","section.reply":"ردّك","attending":"هل ستحضر؟","attending.yes":"نعم، سأحضر","attending.no":"عذرًا، لن أتمكن من الحضور","guests":"كم عدد الأشخاص؟","food":"الطعام","food.none":"بلا تفضيل","food.vegetarian":"نباتي","food.vegan":"نباتي صرف","note":"أي شيء آخر؟","name":"الاسم","email":"البريد الإلكتروني"},"he":{"title":"טופס אישור הגעה (RSVP)","lede":"האורחים מאשרים אם יגיעו, כמה יהיו ואם יש להם צרכים בנושא אוכל.","submit":"שליחה","thanks":"נשלח. תודה.","file_too_big":"עד 3 קבצים, 5 MiB לכל קובץ ו-10 MiB בסך הכול.","error":"השליחה נכשלה. נסו שוב.","section.reply":"התשובה שלכם","attending":"האם תגיעו?","attending.yes":"כן, אגיע","attending.no":"מצטער/ת, לא אוכל להגיע","guests":"כמה אנשים?","food":"אוכל","food.none":"ללא העדפה","food.vegetarian":"צמחוני","food.vegan":"טבעוני","note":"משהו נוסף?","name":"שם","email":"אימייל"},"es":{"title":"Formulario de confirmación de asistencia (RSVP)","lede":"Los invitados confirman si vienen, cuántos son y si tienen necesidades de comida.","submit":"Enviar","thanks":"Enviado. Gracias.","file_too_big":"Hasta 3 archivos, 5 MiB cada uno y 10 MiB en total.","error":"No se pudo enviar. Inténtalo de nuevo.","section.reply":"Tu respuesta","attending":"¿Vas a asistir?","attending.yes":"Sí, allí estaré","attending.no":"Lo siento, no podré ir","guests":"¿Cuántas personas?","food":"Comida","food.none":"Sin preferencia","food.vegetarian":"Vegetariana","food.vegan":"Vegana","note":"¿Algo más?","name":"Nombre","email":"Correo electrónico"},"fr":{"title":"Formulaire RSVP (confirmation de présence)","lede":"Les invités confirment s’ils viennent, combien ils seront et leurs besoins alimentaires.","submit":"Envoyer","thanks":"Envoyé. Merci.","file_too_big":"Jusqu’à 3 fichiers, 5 Mio chacun et 10 Mio au total.","error":"Envoi impossible. Veuillez réessayer.","section.reply":"Votre réponse","attending":"Serez-vous présent ?","attending.yes":"Oui, je serai là","attending.no":"Désolé, je ne pourrai pas venir","guests":"Combien de personnes ?","food":"Repas","food.none":"Pas de préférence","food.vegetarian":"Végétarien","food.vegan":"Végan","note":"Autre chose ?","name":"Nom","email":"E-mail"},"pt":{"title":"Formulário de confirmação de presença (RSVP)","lede":"Os convidados confirmam se vêm, quantos são e se têm necessidades alimentares.","submit":"Enviar","thanks":"Enviado. Obrigado.","file_too_big":"Até 3 ficheiros, 5 MiB cada e 10 MiB no total.","error":"Não foi possível enviar. Tente novamente.","section.reply":"A sua resposta","attending":"Vai estar presente?","attending.yes":"Sim, vou estar presente","attending.no":"Lamento, não vou poder","guests":"Quantas pessoas?","food":"Refeição","food.none":"Sem preferência","food.vegetarian":"Vegetariana","food.vegan":"Vegana","note":"Mais alguma coisa?","name":"Nome","email":"Email"},"hi":{"title":"RSVP फ़ॉर्म (आने की पुष्टि)","lede":"मेहमान बताते हैं कि वे आएँगे या नहीं, कितने लोग होंगे और खाने से जुड़ी ज़रूरतें।","submit":"भेजें","thanks":"भेज दिया गया। धन्यवाद।","file_too_big":"अधिकतम 3 फ़ाइलें, हर फ़ाइल 5 MiB तक और कुल 10 MiB।","error":"भेजा नहीं जा सका। कृपया फिर से कोशिश करें।","section.reply":"आपका जवाब","attending":"क्या आप आएँगे?","attending.yes":"हाँ, मैं आऊँगा/आऊँगी","attending.no":"माफ़ कीजिए, मैं नहीं आ पाऊँगा/पाऊँगी","guests":"कितने लोग?","food":"भोजन","food.none":"कोई पसंद नहीं","food.vegetarian":"शाकाहारी","food.vegan":"वीगन","note":"और कुछ?","name":"नाम","email":"ईमेल"},"ja":{"title":"出欠確認(RSVP)フォーム","lede":"ゲストが出欠、人数、食事の希望を知らせます。","submit":"送信","thanks":"送信しました。ありがとうございます。","file_too_big":"ファイルは3つまで、1つ5 MiB、合計10 MiBまでです。","error":"送信できませんでした。もう一度お試しください。","section.reply":"ご回答","attending":"ご出席されますか?","attending.yes":"はい、出席します","attending.no":"申し訳ありませんが欠席します","guests":"人数","food":"食事","food.none":"指定なし","food.vegetarian":"ベジタリアン","food.vegan":"ヴィーガン","note":"その他","name":"お名前","email":"メールアドレス"},"de":{"title":"RSVP-Formular (Zusage)","lede":"Gäste bestätigen, ob sie kommen, wie viele es sind und was sie beim Essen brauchen.","submit":"Senden","thanks":"Gesendet. Vielen Dank.","file_too_big":"Bis zu 3 Dateien, je 5 MiB und insgesamt 10 MiB.","error":"Senden fehlgeschlagen. Bitte versuchen Sie es erneut.","section.reply":"Ihre Antwort","attending":"Kommen Sie?","attending.yes":"Ja, ich komme","attending.no":"Leider kann ich nicht","guests":"Wie viele Personen?","food":"Essen","food.none":"Keine Präferenz","food.vegetarian":"Vegetarisch","food.vegan":"Vegan","note":"Sonst noch etwas?","name":"Name","email":"E-Mail"}}</script>
<script>
function mountCaptcha(node, siteKey) {
  if (!node || !siteKey) return () => {};
  let disposed = false;
  let widget;
  function render() {
    if (disposed || !window.turnstile) return;
    window.turnstile.ready(() => {
      if (disposed) return;
      widget = window.turnstile.render(node, { sitekey: siteKey, language: node.dataset.language || document.documentElement.lang || "auto" });
      node.dataset.widgetId = widget;
    });
  }
  if (window.turnstile) render();
  else {
    let script = document.querySelector('script[src^="https://challenges.cloudflare.com/turnstile/v0/api.js"]');
    if (!script) {
      script = document.createElement("script");
      script.src = "https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit";
      script.async = true;
      document.head.appendChild(script);
    }
    script.addEventListener("load", render, { once: true });
  }
  return () => { disposed = true; if (widget !== undefined) window.turnstile?.remove(widget); };
}
function resetCaptcha(form) {
  const widget = form.querySelector("[data-turnstile]")?.dataset.widgetId;
  if (widget !== undefined) window.turnstile?.reset(widget);
}
(function () {
  var MAX = 5242880;
  var form = document.getElementById("fg-form");
  var packNode = document.getElementById("fg-labels");
  if (!form || !packNode) return;
  var pack = JSON.parse(packNode.textContent);
  function code() {
    var q = new URLSearchParams(location.search).get("lang") || "";
    // ?lang= preview override, then the form language chosen when copying, then the page and browser.
    var raw = (q || form.getAttribute("data-lang") || document.documentElement.lang || (navigator.language || "en")).slice(0, 2).toLowerCase();
    return pack[raw] ? raw : "en";
  }
  function apply() {
    var dict = pack[code()];
    document.querySelectorAll("[data-i18n]").forEach(function (node) {
      var key = node.getAttribute("data-i18n");
      if (key && typeof dict[key] === "string") node.textContent = dict[key];
    });
  }
  apply();
  var status = form.querySelector("[data-status]");
  form.addEventListener("submit", function (event) {
    event.preventDefault();
    var dict = pack[code()];
    var body = new FormData(form);
    var files = Array.from(body.values()).filter(function (value) { return value instanceof File && value.size; });
    if (files.length > 3 || files.some(function (file) { return file.size > MAX; }) || files.reduce(function (sum,file) { return sum + file.size; },0) > 10 * 1024 * 1024) {
      if (status) status.textContent = dict.file_too_big;
      return;
    }
    var button = form.querySelector("button[type=submit]");
    if (button) button.disabled = true;
    fetch(form.action, { method: "POST", headers: { Accept: "application/json" }, body: body })
      .then(function (response) { return response.json(); }).then(function (result) {
        if (status) status.textContent = result && result.success ? dict.thanks : ((result && result.message) || dict.error);
      }).catch(function () { if (status) status.textContent = dict.error; })
      .finally(function () { if (button) button.disabled = false; resetCaptcha(form); });
  });
  mountCaptcha(form.querySelector("[data-turnstile]"), form.dataset.sitekey);

})();
</script>
</body>
</html>

Code pour d’autres frameworks

React
Vue
Svelte

Comment recevoir plus de demandes

  • Indiquez la date limite de réponse à côté du formulaire.
  • Relancez les personnes qui n’ont pas répondu une semaine avant la date limite.
  • Ajoutez la date, l’heure et l’adresse à la page de remerciement.

Répondre à chaque demande

Chaque réponse arrive dans votre e-mail ou sur Telegram au fur et à mesure. Exportez un CSV pour la liste des invités, ou envoyez les réponses vers un Google Sheet qui compte les invités pour vous.

Questions et réponses

Les invités peuvent-ils modifier leur réponse ?

Ils peuvent renvoyer le formulaire. Les deux réponses figurent dans votre boîte de réception avec l’heure, vous voyez donc la plus récente.

Puis-je recueillir les allergies ?

Ajoutez un court champ texte pour les allergies. Laissez-le facultatif et ne demandez que ce dont le traiteur a besoin.

Comment compter le nombre total d’invités ?

Envoyez les réponses vers Google Sheets et ajoutez une colonne de somme, ou exportez un CSV depuis la boîte de réception.