Форма RSVP (підтвердження участі)
Гості підтверджують, чи прийдуть, скільки їх буде і чи є побажання щодо їжі.
Сайт на Tilda? Вставте код у блок T123 (платний тариф) або підключіть вебхук без коду.
Для чого ця форма
Форма RSVP відповідає господареві на три питання: хто прийде, скільки людей і що вони їдять. Усе інше можна з'ясувати в день події.
Питання про гостей і їжу з'являються лише після відповіді «так». Ті, хто не може прийти, відповідають у два кліки й усе одно можуть залишити примітку.
Поля, які мають значення
- Ви прийдете?
- Так або ні. Решта форми підлаштовується під відповідь.
- Скільки людей?
- Показується після «так». Допомагає спланувати місця й харчування.
- Їжа
- Без побажань, вегетаріанське чи веганське. Показується після «так».
- Ім'я та електронна пошта
- Обов'язкові, щоб ви знали, хто відповів, і могли надсилати оновлення.
Перегляд
Код форми
<!doctype html>
<html lang="uk">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Форма RSVP (підтвердження участі)</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">Форма RSVP (підтвердження участі)</h1>
<p data-i18n="lede">Гості підтверджують, чи прийдуть, скільки їх буде і чи є побажання щодо їжі.</p>
<form id="fg-form" action="https://formgong.com/submit" method="POST" enctype="multipart/form-data" data-sitekey="" data-lang="uk">
<input type="hidden" name="access_key" value="fk_your_access_key">
<input type="hidden" name="_lang" value="uk">
<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">Надіслати</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>
Код для інших фреймворків
Як отримувати більше заявок
- Вкажіть крайній термін відповіді поруч із формою.
- За тиждень до терміну нагадайте тим, хто ще не відповів.
- Додайте дату, час і адресу на сторінку подяки.
Відповідайте на кожну заявку
Кожна відповідь надходить вам на email або в Telegram одразу, як тільки її надіслано. Експортуйте CSV для списку гостей або надсилайте відповіді в таблицю Google Sheets, яка сама рахує гостей.
Питання та відповіді
Чи можуть гості змінити відповідь?
Вони можуть надіслати форму ще раз. Обидві відповіді будуть у вхідних із часом, тож ви побачите останню.
Чи можна збирати інформацію про алергії?
Додайте коротке текстове поле для алергій. Залиште його необов'язковим і питайте лише те, що потрібно кейтерингу.
Як порахувати загальну кількість гостей?
Надсилайте відповіді в Google Sheets і додайте стовпець із сумою або експортуйте CSV із вхідних.