# Wix

> Wix는 커스텀 HTML을 페이지를 이동할 수 없는 샌드박스 프레임에서 실행하므로, fetch로 POST하는 HTML 폼을 Wix 사이트에 임베드합니다.

Wix Forms는 제출을 Wix에 보관하며 외부 action URL을 설정할 수 없습니다. Ikiform을 쓰려면 직접 만든 폼을 **Embed HTML** 요소에 넣으세요. Wix는 이 코드를 별도의 `filesusr.com` 호스트에서 제공하는 샌드박스 iframe 안에서 실행하며, 아래 내용은 모두 이 점 때문입니다.

## 폼이 fetch로 POST하는 이유

- Wix의 프레임은 폼, 스크립트, 팝업, 동일 출처 접근은 허용하지만 최상위 이동은 허용하지 않습니다. `target="_top"`으로는 방문자를 감사 페이지로 보낼 수 없습니다.
- 일반 폼 POST는 결과를 작은 프레임 안에 불러오는데, Ikiform의 감사, 오류, 확인 페이지는 프레임 안에서 렌더링되지 않습니다. 방문자에게는 빈 프레임이나 거부된 프레임이 보입니다.
- `fetch`와 `Accept: application/json`으로 POST하면 방문자가 그 자리에 머물고, 결과가 임베드 안에 표시됩니다.

## 임베드 추가하기

### 1단계: Embed HTML 요소 추가하기

Wix 에디터에서 **Add Elements** > **Embed Code** > **Embed HTML**을 여세요. Wix Studio에서는 **Embed & Social** 아래에 있습니다. **Website address**가 아니라 **Code**를 고르세요.

### 2단계: 폼 붙여 넣기

`Embed HTML`:

```html
<form id="contact" action="https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx" method="post" novalidate>
  <label>Email <input name="email" type="email" autocomplete="email" required /></label>
  <p class="error" data-error-for="email"></p>
  <label>Message <textarea name="message" rows="4"></textarea></label>
  <p class="error" data-error-for="message"></p>
  <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
  <button>Send</button>
  <p role="status" data-status></p>
</form>

<script>
  const form = document.querySelector("#contact");
  const button = form.querySelector("button");
  const status = form.querySelector("[data-status]");

  form.addEventListener("submit", async (event) => {
    event.preventDefault();
    button.disabled = true;
    status.textContent = "Sending";
    try {
      const response = await fetch(form.action, {
        method: "POST",
        headers: { Accept: "application/json" },
        body: new FormData(form),
      });
      const result = await response.json();
      const fields = result.ok ? {} : result.error.fields ?? {};
      for (const slot of form.querySelectorAll("[data-error-for]")) {
        slot.textContent = fields[slot.dataset.errorFor]?.[0] ?? "";
      }
      status.textContent = result.ok ? "Thanks, we got it." : result.error.message;
      if (result.ok) form.reset();
    } catch {
      status.textContent = "Couldn't reach the server. Try again.";
    } finally {
      button.disabled = false;
    }
  });
</script>

<style>
  body { margin: 0; font: 15px/1.5 system-ui, sans-serif; }
  form { display: grid; gap: 8px; }
  label { display: grid; gap: 4px; }
  input, textarea, button { font: inherit; padding: 8px 10px; border: 1px solid #d4d4d4; border-radius: 6px; }
  button { background: #111; color: #fff; border: 0; }
  .error { margin: 0; color: #b42318; font-size: 13px; }
</style>
```

프레임은 사이트의 글꼴이나 색상을 상속하지 않으므로 `<style>` 블록에서 설정합니다. 사이트에 맞게 바꾸세요.

### 3단계: 크기 조정과 게시

필드 오류와 상태 줄이 들어갈 만큼 요소를 길게 늘린 뒤 게시하세요. 에디터에서는 커스텀 코드 자리에 플레이스홀더만 보이므로 게시된 사이트에서 테스트하세요.

> 프리미엄 플랜과 연결된 도메인이 필요한 Wix의 사이트 전체 **Custom Code** 설정은 페이지의 head나 body에 코드를 추가합니다. 레이아웃의 특정 위치에 폼을 놓을 수는 없으므로, 폼 자체는 여전히 Embed HTML 요소에 넣어야 합니다.

## 스팸 설정

폼의 스팸 검사는 끈 상태로 두세요. Ikiform의 사람 확인에는 확인 페이지나 작은 ikiform.com 프레임이 필요한데, Wix 샌드박스 안에서는 둘 다 실행할 수 없습니다. 허니팟과 스팸 점수 산정은 모든 POST에서 계속 실행됩니다.

## 허용 도메인

POST가 iframe 안에서 전송되므로 Ikiform에는 Wix 도메인이 아니라 프레임의 호스트가 보입니다. 확인하려면 게시된 페이지를 열고 임베드를 검사해 iframe의 `src`를 읽으세요.

| 폼이 실행되는 곳 | Allowed domains에 추가할 값 |
| --- | --- |
| 임베드 프레임 | iframe의 `src`에 있는 정확한 호스트, 예: `www-example-com.filesusr.com` |
| Wix 도메인 또는 커스텀 도메인 | POST가 여기서 오지 않으므로 임베드에는 필요 없음 |

- `filesusr.com`만 단독으로 추가하지 마세요. 다른 사람의 사이트를 포함해 그 호스트의 모든 사이트가 일치하게 됩니다.
- 프레임 호스트는 사이트 주소에서 파생되므로 새 도메인을 연결하면 바뀝니다. 도메인을 바꾼 뒤에는 다시 확인하세요.

## 테스트 체크리스트

1. 게시한 뒤 시크릿 창에서 실제 페이지를 여세요.
2. [필드](https://ikiform.com/ko/docs/fields.md)를 정의한 상태에서 이메일을 비우고 제출하세요. 폼에 `novalidate`가 있으므로 Ikiform의 메시지가 필드 아래에 나타나야 합니다.
3. 실제 메시지를 제출하고 상태 줄에 "Thanks, we got it."이 표시되는지, 제출이 Ikiform에 나타나는지 확인하세요.
4. 프레임 호스트로 허용 도메인을 켜고 다시 제출하세요. 여전히 수신 목록에 들어가야 합니다.

## 문제 해결

| 증상 | 원인 | 해결 |
| --- | --- | --- |
| 제출 후 임베드가 비거나 거부된 페이지가 표시됨 | 스크립트가 실행되지 않아 브라우저가 평소처럼 POST하고 프레임 안에 Ikiform의 페이지를 불러오려 함 | 스크립트가 요소에 들어갔는지, 폼의 id가 `contact`인지 확인하세요. |
| 제출이 `origin_mismatch`와 함께 스팸으로 들어감 | 프레임 호스트가 허용 도메인에 없거나, 대신 Wix 도메인을 등록함 | iframe의 `src`에 있는 정확한 `filesusr.com` 호스트를 추가하세요. |
| 상태 줄에 `Complete the human check, then send the form again.`가 표시됨 | 스팸 검사가 샌드박스 안에서 실행할 수 없는 **Ikiform**으로 설정됨 | 이 폼의 확인을 끄세요. |
| 상태 줄에 서버에 연결할 수 없다고 표시됨 | 광고 차단기나 네트워크 필터가 요청을 막았습니다. 일부 네트워크는 `filesusr.com` 자체를 차단합니다. | 다른 네트워크에서, 또는 확장 프로그램 없이 시크릿 창에서 테스트하세요. |
| 오류 메시지가 잘림 | 요소가 폼보다 짧음 | 에디터에서 요소를 더 길게 늘리세요. |

## 관련 문서

- [순수 JavaScript](https://ikiform.com/ko/docs/guides/javascript.md): 인라인 오류를 표시하는 `fetch`.
- [사이트 빌더](https://ikiform.com/ko/docs/guides/site-builders.md): 어떤 빌더에서든 작동하는 임베드.
- [허용 도메인](https://ikiform.com/ko/docs/spam.md#allowed-domains): 출처를 비교하는 방식과 불일치 시 동작.
- [스팸 방지](https://ikiform.com/ko/docs/spam.md): 허니팟, 점수 산정, 사람 확인.
