Form ID

Framer

코드 없이 웹훅 목적지로 Framer 폼을 Ikiform에 보내거나, 브라우저에서 POST하는 코드 컴포넌트로 직접 폼을 렌더링하세요.

Framer 폼은 외부 action URL로 POST할 수 없지만, 제출마다 웹훅으로 보낼 수는 있습니다. 그래서 방법이 두 가지입니다. Framer 폼을 유지하고 Ikiform을 웹훅으로 추가하거나, 방문자의 브라우저에서 POST하는 작은 코드 컴포넌트를 넣으세요.

Item웹훅을 쓰는 Framer 폼코드 컴포넌트
POST를 보내는 주체Framer의 서버방문자의 브라우저
코드없음React 파일 하나
허용 도메인비워 두세요. 서버 POST에는 Origin이 없습니다Framer 도메인과 비교
허니팟사용할 수 없음포함
레이트 리밋 집계 기준Framer 서버의 주소방문자별
Ikiform 스팸 검사끈 상태로 두기끈 상태로 두기

웹훅을 쓰는 Framer 폼

  1. 입력 이름 정하기

    Framer는 각 입력의 이름을 키로 하는 JSON을 보내므로, 입력에 붙인 이름이 Ikiform의 필드 이름이 됩니다. email, message처럼 소문자 ID를 사용하고, 필드 정의가 있다면 맞추세요.

  2. Ikiform을 웹훅으로 추가하기

    캔버스에서 폼을 선택하세요. 오른쪽 사이드바의 Send To 옆에서 Add… > Webhook을 고르고 엔드포인트를 붙여 넣으세요. Framer는 https:// URL을 요구하며, 엔드포인트는 이미 그 형식입니다.

    Webhook URL
    https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx

    Framer는 시크릿으로 요청에 서명할 수 있습니다. Ikiform은 Framer-Signature 헤더를 확인하지 않으므로 여기서 시크릿은 선택 사항입니다.

  3. Ikiform 폼 설정 조정하기

    • Allowed domains는 비워 두세요. Framer는 Origin 헤더 없이 서버에서 POST하므로, 도메인을 설정하면 모든 POST가 origin_mismatch로 스팸 처리되거나 Reject 설정 시 거부됩니다.
    • 스팸 검사는 끈 상태로 두세요. 토큰 없는 JSON POST는 403 challenge_required를 받으며, Framer에는 확인을 실행할 방법이 없습니다.
    • Relaxed 레이트 리밋을 고르세요. Ikiform은 IP 주소와 폼별로 POST를 세는데, 모든 POST가 방문자가 아니라 Framer의 서버에서 옵니다.

Framer는 2xx가 아닌 모든 응답을 실패로 보고 최대 5번 재시도합니다. Ikiform은 제출이 저장되면 201로 응답합니다. 422 validation_failed처럼 Ikiform이 거부한 POST는 재시도할 때마다 똑같이 실패하므로, 기다리지 말고 원인을 고치세요.

코드 컴포넌트

코드 컴포넌트는 페이지에 실제 폼을 렌더링하므로, 브라우저가 POST하고 Ikiform은 여러분의 사이트를 출처로 봅니다. Assets 패널에서 Code를 열고 코드 파일을 만든 뒤 다음을 붙여 넣으세요.

IkiformContact.tsx
import { addPropertyControls, ControlType } from "framer";
import { type CSSProperties, type FormEvent, useState } from "react";

const field: CSSProperties = {
  font: "inherit",
  padding: "10px 12px",
  borderRadius: 8,
  border: "1px solid rgba(0, 0, 0, 0.15)",
};

export default function IkiformContact({ formId, successText }: { formId: string; successText: string }) {
  const [status, setStatus] = useState<"idle" | "sending" | "sent" | "error">("idle");
  const [message, setMessage] = useState("");

  async function onSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setStatus("sending");
    try {
      const response = await fetch(`https://ikiform.com/f/${formId}`, {
        method: "POST",
        headers: { Accept: "application/json" },
        body: new FormData(event.currentTarget),
      });
      const result = await response.json();
      if (result.ok) return setStatus("sent");
      setMessage(result.error.message);
    } catch {
      setMessage("Couldn't reach the server. Try again.");
    }
    setStatus("error");
  }

  if (status === "sent") return <p>{successText}</p>;

  return (
    <form onSubmit={onSubmit} style={{ display: "grid", gap: 12, width: "100%" }}>
      <input name="email" type="email" placeholder="Email" autoComplete="email" required style={field} />
      <textarea name="message" placeholder="Message" rows={4} style={field} />
      <input name="_gotcha" type="text" tabIndex={-1} autoComplete="off" hidden />
      {status === "error" ? <p role="alert">{message}</p> : null}
      <button type="submit" disabled={status === "sending"} style={field}>
        {status === "sending" ? "Sending" : "Send"}
      </button>
    </form>
  );
}

addPropertyControls(IkiformContact, {
  formId: { type: ControlType.String, title: "Form ID", defaultValue: "frm_xxxxxxxxxxxxxxxx" },
  successText: { type: ControlType.String, title: "Success text", defaultValue: "Thanks, we got it." },
});
  • 컴포넌트를 페이지로 끌어다 놓고 속성 패널에서 Form ID를 설정하세요. 입력 스타일은 field를 편집해 바꾸거나, 요소를 직접 만든 것으로 교체하세요.
  • Accept: application/json을 보내면 Ikiform이 JSON으로 응답하므로, 컴포넌트가 결과를 그 자리에 보여 줄 수 있습니다.
  • 컴포넌트는 fetch로 POST하므로 폼의 스팸 검사는 끈 상태로 두세요. 허니팟과 스팸 점수 산정은 계속 실행됩니다.
사이트 빌더 임베드를 Embed 컴포넌트의 HTML 섹션에 붙여 넣을 수도 있습니다. Framer가 이를 프레임 안에 넣으면 Ikiform의 감사 및 오류 페이지가 그 안에서 열리지 않으므로, 임베드는 target="_top"을 사용합니다. 코드 컴포넌트는 프레임을 아예 쓰지 않습니다.

허용 도메인

코드 컴포넌트와 임베드에만 해당합니다. 웹훅을 쓸 때는 허용 도메인을 비워 두세요.

폼이 실행되는 곳Allowed domains에 추가할 값
Framer 하위 도메인your-project.framer.app, 오래된 프로젝트는 your-project.framer.website
커스텀 도메인example.com, www.example.com도 포함
Framer 편집기 미리보기없음. 대신 게시된 사이트에서 테스트하세요.
  • framer.app이나 framer.website만 단독으로 추가하지 마세요. 다른 사람의 사이트를 포함해 그 호스트의 모든 사이트가 일치하게 됩니다.

테스트 체크리스트

  1. 사이트를 게시하세요. Framer는 게시된 사이트의 폼에 대해서만 웹훅을 보냅니다.
  2. 폼을 제출하고 Ikiform에서 제출을 확인하세요. 웹훅을 쓰면 필드가 입력 이름과 정확히 일치해야 합니다.
  3. 코드 컴포넌트라면 허용 도메인을 켜고, 게시된 도메인에서 제출한 뒤 스팸으로 표시되지 않았는지 확인하세요.

문제 해결

증상원인해결
모든 웹훅 제출이 origin_mismatch로 스팸에 들어감Allowed domains가 설정되어 있고, Framer 서버의 POST에는 출처가 없음이 폼의 허용 도메인을 비우거나 코드 컴포넌트로 바꾸세요.
Framer가 웹훅 전송 실패를 보고함Ikiform이 POST를 거부함: 403 challenge_required, 403 origin_not_allowed 또는 422 validation_failed스팸 검사를 끄고, 허용 도메인을 비우고, 입력 이름을 필드에 맞추세요.
제출이 많은 폼에서 429 rate_limitedFramer 서버의 POST가 적은 수의 IP 주소를 공유함Relaxed나 Custom 한도를 고르세요.
컴포넌트가 서버에 연결할 수 없다고 표시함광고 차단기나 개인정보 보호 확장 프로그램이 요청을 막았거나, Form ID가 비어 있음시크릿 창에서 시도하고 속성이 설정되었는지 확인하세요.
제출이 origin_mismatch와 함께 스팸 필터에 들어감POST한 페이지가 폼의 허용 도메인에 없음위 표의 호스트를 추가하세요. Reject를 골랐다면 같은 POST가 대신 403 origin_not_allowed를 받습니다.