Formularz RSVP (potwierdzenie obecności)

Goście potwierdzają, czy przyjdą, ile osób i czy mają wymagania co do jedzenia.

Używasz Tildy? Wklej do bloku T123 (płatny plan) albo użyj webhooka bez kodu.

Do czego służy ten formularz

Formularz RSVP odpowiada gospodarzowi na trzy pytania: kto przyjdzie, ile osób i co jedzą. Reszta może poczekać do dnia wydarzenia.

Pytania o gości i jedzenie pojawiają się dopiero po odpowiedzi „tak”. Osoby, które nie mogą przyjść, odpowiadają w dwóch kliknięciach i nadal mogą zostawić uwagę.

Pola, które mają znaczenie

Czy przyjdziesz?
Tak lub nie. Reszta formularza dostosowuje się do odpowiedzi.
Ile osób?
Pokazuje się po „tak”. Pozwala zaplanować miejsca i catering.
Jedzenie
Bez preferencji, wegetariańskie lub wegańskie. Pokazuje się po „tak”.
Imię i e-mail
Wymagane, żeby było wiadomo, kto odpowiedział, i można było wysyłać informacje.

Podgląd

Twoja odpowiedź

Kod formularza

HTML
<!doctype html>
<html lang="pl">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Formularz RSVP (potwierdzenie obecności)</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">Formularz RSVP (potwierdzenie obecności)</h1>
<p data-i18n="lede">Goście potwierdzają, czy przyjdą, ile osób i czy mają wymagania co do jedzenia.</p>


<form id="fg-form" action="https://formgong.com/submit" method="POST" enctype="multipart/form-data" data-sitekey="" data-lang="pl">
<input type="hidden" name="access_key" value="fk_your_access_key">
<input type="hidden" name="_lang" value="pl">
<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">Wyślij</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>

Kod dla innych frameworków

React
Vue
Svelte

Jak dostawać więcej zgłoszeń

  • Umieść termin odpowiedzi obok formularza.
  • Tydzień przed terminem wyślij przypomnienie osobom, które jeszcze nie odpowiedziały.
  • Dodaj datę, godzinę i adres na stronie podziękowania.

Odpowiadaj na każde zgłoszenie

Każda odpowiedź trafia na Twój e-mail lub Telegram od razu po wysłaniu. Wyeksportuj CSV jako listę gości albo wysyłaj odpowiedzi do arkusza Google Sheets, który sam policzy gości.

Pytania i odpowiedzi

Czy goście mogą zmienić odpowiedź?

Mogą wysłać formularz ponownie. Obie odpowiedzi są w skrzynce wraz z godziną, więc widzisz najnowszą.

Czy mogę zbierać informacje o alergiach?

Dodaj krótkie pole tekstowe na alergie. Zostaw je opcjonalne i pytaj tylko o to, czego potrzebuje catering.

Jak policzyć łączną liczbę gości?

Wysyłaj odpowiedzi do Google Sheets i dodaj kolumnę z sumą albo wyeksportuj CSV ze skrzynki.