새 SaaS용 대기자 명단4분 분량
Webflow 사이트에 대기자 명단 폼 추가하는 방법
Webflow Form Block을 Ikiform으로 연결하고, 숨겨진 필드로 가입 경로를 태그하고, 짧은 스크립트로 모든 폼에서 Webflow의 성공 상태를 유지합니다.
Webflow에서 디자인한 Form Block은 그대로 두고, action을 Ikiform 엔드포인트로, 메서드를 POST로 바꾸세요. Code Embed에 숨겨진 ref 입력과 허니팟을 추가한 뒤, 모든 대기자 명단 폼을 fetch로 POST하고, 링크에서 ref를 채우고, 그 사람의 이메일과 함께 Webflow 자체 성공 블록을 보여 주는 사이트 전체 스크립트를 하나 붙여 넣으세요.
Webflow는 페이지에는 뛰어나고 폼에는 무난합니다. 기본 폼 처리는 제출을 저장하고 이메일을 보내지만, 사이트 플랜에 따라 보관 개수가 제한되고 가입에 유입 캠페인을 태그할 수 없습니다. 커스텀 action을 쓰면 Designer를 벗어나지 않고 둘 다 해결됩니다.
Webflow에서 다른 점
- 커스텀 action은 폼을 Webflow에서 떼어 냅니다. 브라우저가 Ikiform으로 바로 POST하므로 Webflow는 가입을 보지 못합니다. Webflow 폼 제출 목록에 없고, Webflow는 이메일을 보내지 않으며, 플랜의 폼 허용량도 쓰지 않습니다.
- Webflow의 성공 블록과 오류 블록이 작동하지 않습니다. Webflow가 POST를 처리했을 때만 나타나기 때문입니다. 스크립트가 없으면 방문자는 Ikiform 감사 페이지나 Redirect after submit URL로 이동합니다.
- 숨겨진 입력 요소가 없습니다. 숨겨진 필드와 허니팟은 폼 안의 Code Embed에 넣어야 하며, 커스텀 코드와 마찬가지로 유료 사이트 플랜이 필요합니다.
- Designer에서는 아무것도 실행되지 않습니다. 커스텀 action과 스크립트는 게시된 사이트에서만 작동하므로
webflow.io스테이징 도메인에서 테스트하세요.
- 기본적으로 Form Block은 Webflow로 POST하고, Webflow는 플랜 허용량 안에서 가입을 저장하고 성공 블록을 보여 줍니다.
- 커스텀 action을 쓰면 같은 Form Block이 Ikiform을 가리킵니다.
- 스크립트가 일반 POST를 막고, 링크에서 ref 필드를 채우고, fetch로 POST합니다.
- Ikiform이 가입을 저장하고, 이메일을 보내고, 웹훅을 보낸 뒤 201로 응답합니다.
- 스크립트가 폼을 숨기고 그 사람의 이메일과 함께 Webflow의 성공 블록을 보여 줍니다.
Form Block 설정하기
- 폼을 선택하고 Settings를 여세요. Send to에서 Webflow와 Email notifications를 제거하고 Custom action을 추가한 뒤,
https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx를 입력하고 POST를 골라 저장하세요. - 이메일 입력을 선택하고 Name을
email로 설정하세요. Webflow는 라벨로 이름을 채우므로 그대로 두면Email이나Email 2가 되고, Ikiform은 이를 다른 필드로 취급합니다. - reCAPTCHA 요소가 있다면 삭제하세요. Ikiform은 이를 검증하지 않으며, 필드 정의가 있으면
g-recaptcha-response값이 알 수 없는 필드로 거부됩니다. - 폼 안의 버튼 옆에 Code Embed를 끌어다 놓고 아래 입력 두 개를 붙여 넣으세요.
- Ikiform 폼 설정의 Redirect after submit을 Webflow에 게시한 감사 페이지로 설정하세요. 스크립트가 실행되지 않으면 사람들이 그곳으로 이동합니다.
<input type="hidden" name="ref" value="webflow">
<input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden>Ikiform의 Fields 탭에서 email은 필수로, ref는 max_length 40인 선택 text 필드로 필드 정의를 추가하세요. 그러면 남아 있는 Name 입력처럼 그 밖의 이름으로 POST된 값은 모두 422를 받으므로, 첫 테스트에서 라벨이 잘못 붙은 입력을 찾을 수 있습니다.
사이트 전체 스크립트
이것을 Site settings › Custom code › Footer code에 붙여 넣으면 히어로 폼, 푸터 폼, 나중에 추가하는 모든 페이지에 적용됩니다. action이 https://ikiform.com/f/로 시작하는 폼만 건드립니다.
<script>
const params = new URLSearchParams(location.search);
const ref = (params.get("ref") || params.get("utm_source") || "").toLowerCase().replace(/[^a-z0-9_-]/g, "").slice(0, 40);
const key = crypto.randomUUID();
document.querySelectorAll('form[action^="https://ikiform.com/f/"]').forEach((form, index) => {
const wrapper = form.closest(".w-form");
const done = wrapper?.querySelector(".w-form-done");
const fail = wrapper?.querySelector(".w-form-fail");
const button = form.querySelector('[type="submit"]');
const source = form.querySelector('[name="ref"]');
if (source && ref) source.value = ref;
form.addEventListener("submit", async (event) => {
event.preventDefault();
const label = button.value;
button.disabled = true;
button.value = button.dataset.wait || "Joining";
fail.style.display = "none";
try {
const response = await fetch(form.action, {
method: "POST",
headers: { Accept: "application/json", "Idempotency-Key": `${key}-${index}` },
body: new FormData(form),
});
const result = await response.json();
if (result.ok) {
const email = form.querySelector('[name="email"]').value;
const line = done.querySelector("div") ?? done;
line.textContent = `You're on the list. We'll write to ${email} on launch day.`;
form.style.display = "none";
done.style.display = "block";
return;
}
const wait = response.headers.get("Retry-After");
const message = wait ? `Lots of signups right now. Try again in ${wait} seconds.` : result.error.fields?.email?.[0] ?? result.error.message;
(fail.querySelector("div") ?? fail).textContent = message;
} catch {
(fail.querySelector("div") ?? fail).textContent = "Couldn't reach the server. Try again.";
}
fail.style.display = "block";
button.disabled = false;
button.value = label;
});
});
</script>- 링크의
?ref=또는?utm_source=가 페이지의 모든 숨겨진ref입력을 채웁니다. 둘 다 없으면 임베드에 설정한 값이 유지되므로, 폼마다hero,footer처럼 값을 정해 두면 어느 쪽이 전환되는지 알 수 있습니다. - 멱등성 키는 페이지를 불러올 때마다 한 번 만들어지고 폼마다 접미사가 붙습니다. 더블 클릭해도 가입은 하나만 저장되고, 같은 페이지의 다른 폼에서 한 두 번째 가입은 따로 집계됩니다.
- Webflow의 성공 블록에 그 사람의 이메일이 담긴 줄이 추가되어 오타를 잡아 줍니다.
gmial.com처럼 잘못 쓴 주소가 다시 보이면 사람들이 알아챕니다. - POST가 진행되는 동안 버튼에는 Designer에서 설정한 Loading 텍스트가 표시됩니다.
429가 나면 일반적인 실패 메시지 대신 Ikiform의Retry-After헤더를 바탕으로 얼마나 기다려야 하는지 보여 줍니다.
fetch로 POST하므로 폼의 스팸 검사는 꺼 두세요. 검사가 켜져 있으면 Ikiform이 403 challenge_required로 응답하고 오류 블록이 표시됩니다. 검사가 필요하다면 스크립트를 빼세요. 일반 POST는 코드 없이 검사를 실행합니다.허용 도메인
| 폼이 실행되는 곳 | Allowed domains에 추가할 것 |
|---|---|
| 스테이징 | your-site.webflow.io |
| 커스텀 도메인 | example.com, www.example.com도 포함 |
| Designer 화면 | 없음. 그곳에서는 POST하지 않습니다 |
webflow.io만 단독으로 추가하지 마세요. 모든 Webflow 사이트가 일치하게 됩니다. Webflow 문서 가이드는 문의 폼에 대해 같은 설정을 다루고, 메인 가이드는 가입을 이메일 도구로 전달하는 방법을 보여 줍니다.
작동 확인하기
webflow.io스테이징 도메인에 게시하세요.- 폼의 Allowed domains에 사이트 도메인을 추가하고, 개발 중에는
localhost도 추가하세요. 비워 두면 어디서 온 POST든 받습니다. ?ref=test로 페이지를 열고 가입하세요. Webflow 성공 블록에 이메일이 표시되고, Ikiform의 제출에는ref가test로 설정되어 있습니다.- 쿼리 문자열 없이 푸터 폼에서 다시 가입하세요.
ref에는 그 폼의 임베드에 있는 값이 들어갑니다. - JavaScript를 끄고 제출하세요. Webflow 감사 페이지로 이동합니다.
- 알림 수신자마다 받은편지함을 확인하세요. 각자 필드가 담긴 이메일을 받으며, 폼에
email필드가 있으면 Reply(답장)는 제출자에게 갑니다. - 허니팟을 채워서
_gotcha=bot으로 POST해 보세요. 여전히 성공 응답을 받지만, 제출은 스팸으로 저장되고 이메일이나 웹훅을 보내지 않습니다.
주의할 점
| 문제 | 해결 방법 |
|---|---|
제출 후 404 not_found | Method가 GET이라서 브라우저가 엔드포인트를 링크처럼 열었습니다. POST로 바꾸고 다시 게시하세요. |
Unknown field Email 또는 g-recaptcha-response와 함께 422 | 입력의 Name이 정의와 맞지 않거나 폼에 reCAPTCHA 요소가 남아 있습니다. 입력 이름을 email로 바꾸거나 요소를 제거하세요. |
| 스크립트가 아무것도 하지 않음 | Designer에 있거나, 사이트에 유료 플랜이 없거나, Action에 공백이 있습니다. 게시된 사이트에서 테스트하세요. |
403 challenge_required | 폼의 스팸 검사가 Ikiform으로 설정되어 있는데 fetch POST에 토큰이 없었습니다. 제출할 때마다 먼저 @ikiform/sdk의 challenge(formId)로 토큰을 받거나, 검사를 끄세요. |
403 origin_not_allowed이거나 모든 POST가 스팸으로 분류됨 | 페이지의 도메인이 폼의 Allowed domains에 없습니다. 도메인을 추가하고, 로컬 테스트용으로 localhost도 추가하세요. 등록된 도메인의 하위 도메인은 허용됩니다. |
질문
아니요. 커스텀 action을 쓰면 브라우저가 Ikiform으로 바로 POST하므로 Webflow는 제출을 받지 않습니다. Webflow 폼 제출 목록에 나타나지 않고 플랜 허용량도 쓰지 않습니다.
Webflow에는 숨겨진 입력 요소가 없습니다. 폼 안에 type이 hidden인 입력을 담은 Code Embed를 넣으세요. Code Embed에는 유료 Site 플랜 또는 Core, Growth, Agency, Freelancer Workspace가 필요합니다.
네, 스크립트로 가능합니다. Webflow는 자신이 POST를 처리했을 때만 성공 블록을 보여 주므로, 위 예제처럼 스크립트가 fetch로 POST하고 블록을 직접 보여 줍니다.
아니요. Ikiform은 제출자가 아니라 여러분과 팀에게 이메일을 보내므로 자동 응답이나 확인 이메일이 없습니다. 웹훅을 이메일 도구로 보내고 그곳에서 확인 이메일을 보내세요.
막히는 단계가 있거나 내 상황에 맞는 가이드가 필요하다면 이메일을 보내세요: hello@ikiform.com.