# Webflow 사이트에 대기자 명단 폼 추가하는 방법

> Webflow Form Block을 Ikiform으로 연결하고, 숨겨진 필드로 가입 경로를 태그하고, 짧은 스크립트로 모든 폼에서 Webflow의 성공 상태를 유지합니다.

2026-10-25 게시 · https://ikiform.com/ko/guides/waitlist/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` 스테이징 도메인에서 테스트하세요.

다이어그램: 커스텀 action 전후의 Webflow 대기자 명단 폼

1. 기본적으로 Form Block은 Webflow로 POST하고, Webflow는 플랜 허용량 안에서 가입을 저장하고 성공 블록을 보여 줍니다.
2. 커스텀 action을 쓰면 같은 Form Block이 Ikiform을 가리킵니다.
3. 스크립트가 일반 POST를 막고, 링크에서 ref 필드를 채우고, fetch로 POST합니다.
4. Ikiform이 가입을 저장하고, 이메일을 보내고, 웹훅을 보낸 뒤 201로 응답합니다.
5. 스크립트가 폼을 숨기고 그 사람의 이메일과 함께 Webflow의 성공 블록을 보여 줍니다.

디자인은 Webflow에 그대로 있습니다. 데이터가 가는 곳만 바뀝니다.

## Form Block 설정하기

1. 폼을 선택하고 **Settings**를 여세요. **Send to**에서 **Webflow**와 **Email notifications**를 제거하고 **Custom action**을 추가한 뒤, `https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx`를 입력하고 **POST**를 골라 저장하세요.
2. 이메일 입력을 선택하고 **Name**을 `email`로 설정하세요. Webflow는 라벨로 이름을 채우므로 그대로 두면 `Email`이나 `Email 2`가 되고, Ikiform은 이를 다른 필드로 취급합니다.
3. reCAPTCHA 요소가 있다면 삭제하세요. Ikiform은 이를 검증하지 않으며, 필드 정의가 있으면 `g-recaptcha-response` 값이 알 수 없는 필드로 거부됩니다.
4. 폼 안의 버튼 옆에 **Code Embed**를 끌어다 놓고 아래 입력 두 개를 붙여 넣으세요.
5. Ikiform 폼 설정의 **Redirect after submit**을 Webflow에 게시한 감사 페이지로 설정하세요. 스크립트가 실행되지 않으면 사람들이 그곳으로 이동합니다.

`폼 안의 Code Embed`:

```html
<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/`로 시작하는 폼만 건드립니다.

`푸터 코드`:

```html
<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 문서 가이드](https://ikiform.com/ko/docs/guides/webflow.md)는 문의 폼에 대해 같은 설정을 다루고, [메인 가이드](https://ikiform.com/ko/guides/waitlist.md#confirm)는 가입을 이메일 도구로 전달하는 방법을 보여 줍니다.

## 작동 확인하기

1. `webflow.io` 스테이징 도메인에 게시하세요.
2. 폼의 **Allowed domains**에 사이트 도메인을 추가하고, 개발 중에는 `localhost`도 추가하세요. 비워 두면 어디서 온 POST든 받습니다.
3. `?ref=test`로 페이지를 열고 가입하세요. Webflow 성공 블록에 이메일이 표시되고, Ikiform의 제출에는 `ref`가 `test`로 설정되어 있습니다.
4. 쿼리 문자열 없이 푸터 폼에서 다시 가입하세요. `ref`에는 그 폼의 임베드에 있는 값이 들어갑니다.
5. JavaScript를 끄고 제출하세요. Webflow 감사 페이지로 이동합니다.
6. 알림 수신자마다 받은편지함을 확인하세요. 각자 필드가 담긴 이메일을 받으며, 폼에 `email` 필드가 있으면 **Reply**(답장)는 제출자에게 갑니다.
7. 허니팟을 채워서 `_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`도 추가하세요. 등록된 도메인의 하위 도메인은 허용됩니다. |

## 질문

### Ikiform으로 보낸 대기자 명단 가입이 Webflow의 폼 제출 한도에 포함되나요?

아니요. 커스텀 action을 쓰면 브라우저가 Ikiform으로 바로 POST하므로 Webflow는 제출을 받지 않습니다. Webflow 폼 제출 목록에 나타나지 않고 플랜 허용량도 쓰지 않습니다.

### Webflow 폼에 숨겨진 필드는 어떻게 추가하나요?

Webflow에는 숨겨진 입력 요소가 없습니다. 폼 안에 type이 hidden인 입력을 담은 Code Embed를 넣으세요. Code Embed에는 유료 Site 플랜 또는 Core, Growth, Agency, Freelancer Workspace가 필요합니다.

### 커스텀 action을 쓰면서 Webflow의 성공 메시지를 유지할 수 있나요?

네, 스크립트로 가능합니다. Webflow는 자신이 POST를 처리했을 때만 성공 블록을 보여 주므로, 위 예제처럼 스크립트가 fetch로 POST하고 블록을 직접 보여 줍니다.

### Ikiform이 폼을 제출한 사람에게 이메일을 보낼 수 있나요?

아니요. Ikiform은 제출자가 아니라 여러분과 팀에게 이메일을 보내므로 자동 응답이나 확인 이메일이 없습니다. 웹훅을 이메일 도구로 보내고 그곳에서 확인 이메일을 보내세요.

## 가이드 더 보기

- [새 SaaS용 대기자 명단](https://ikiform.com/ko/guides/waitlist.md): 내 랜딩 페이지에 출시 전 대기자 명단을 만듭니다. 폼, 스팸 방지, 중복 처리, 확인 이메일, 출시일의 깔끔한 내보내기까지 다룹니다.
- [Framer 대기자 명단](https://ikiform.com/ko/guides/waitlist/framer.md): Framer에서 대기자 명단 가입을 받는 두 가지 방법: 웹훅으로 Ikiform에 보내는 Framer 폼, 또는 방문자별 한도와 스팸 검사를 유지하는 코드 컴포넌트입니다.
- [Carrd 대기자 명단](https://ikiform.com/ko/guides/waitlist/carrd.md): Carrd 페이지에서 대기자 명단 가입 받기: Pro Plus에서 UTM 추적이 되는 Send to URL 폼, 또는 Pro Standard에서 허니팟이 있는 임베드 HTML 폼.
- [일반 HTML 대기자 명단](https://ikiform.com/ko/guides/waitlist/html.md): 빌드 없이 일반 HTML로 만든 완전한 대기자 명단 페이지로, JavaScript가 꺼져도 작동하고, 스크립트가 로드되면 인라인 감사 문구를 보여 주며, 필요할 때는 기본 방식으로 돌아갑니다.
- [Product Hunt 출시 리스트](https://ikiform.com/ko/guides/waitlist/product-hunt.md): Product Hunt 몇 주 전부터 출시 리스트를 모으고, 가입마다 채널 태그를 달고, 태평양 시간 리셋에 맞춰 출시일 이메일을 두 번에 나눠 보냅니다.
- [선별 기능이 있는 베타 신청](https://ikiform.com/ko/guides/waitlist/beta-signup.md): 서버가 강제하는 선별 질문이 있는 베타 신청 폼과, 지원자에게 점수를 매겨 목록에서 기수별 참가자를 고르는 스크립트입니다.
