Form ID

SvelteKit

폼이 Ikiform으로 바로 POST하고, JavaScript가 로드되면 fetch로 향상되는 프리렌더링 SvelteKit 페이지. adapter-static과 함께 작동합니다.

이 페이지는 서버가 필요 없습니다. 폼의 action이 Ikiform 엔드포인트이므로 adapter-static과 모든 정적 호스트에서 작동합니다. JavaScript가 없으면 일반 HTML처럼 POST하고 리디렉션하며, JavaScript가 있으면 fetch로 POST하고 결과를 그 자리에 보여 줍니다. 대신 시크릿 키를 사용하는 폼 액션으로 POST하려면 Svelte를 참고하세요.

use:enhance를 쓰지 않는 이유

SvelteKit의 use:enhance는 +page.server.js 파일에 정의된 액션을 가리키는 method="POST" 폼에서만 작동합니다. Ikiform은 외부 URL이므로 이 페이지는 대신 작은 onsubmit 핸들러를 사용합니다. 점진적 향상 방식은 같습니다. 폼이 먼저 작동하고, 스크립트가 이를 개선합니다.

설정하기

  1. 공개 환경 변수 추가하기

    .env
    PUBLIC_IKIFORM_FORM_ID=frm_xxxxxxxxxxxxxxxx
    PUBLIC_SITE_URL=https://example.com

    PUBLIC_SITE_URL은 JavaScript 없는 경우의 리디렉션에 사용합니다. 프리렌더링 중에는 page.url.origin이 여러분의 도메인이 아니라 http://sveltekit-prerender이므로, 이 값으로 리디렉션 주소를 만들 수 없습니다.

  2. 페이지 프리렌더링하기

    src/routes/contact/+page.js
    export const prerender = true;
  3. 폼 추가하기

    src/routes/contact/+page.svelte
    <script>
      import { PUBLIC_IKIFORM_FORM_ID, PUBLIC_SITE_URL } from "$env/static/public";
    
      const endpoint = `https://ikiform.com/f/${PUBLIC_IKIFORM_FORM_ID}`;
    
      let status = $state("idle");
      let errors = $state({});
      let message = $state("");
    
      async function onsubmit(event) {
        event.preventDefault();
        status = "sending";
        try {
          const response = await fetch(endpoint, {
            method: "POST",
            headers: { Accept: "application/json" },
            body: new FormData(event.currentTarget),
          });
          const result = await response.json();
          if (result.ok) {
            status = "sent";
            return;
          }
          errors = result.error.fields ?? {};
          message = result.error.message;
        } catch {
          message = "Couldn't reach the server. Try again.";
        }
        status = "error";
      }
    </script>
    
    {#if status === "sent"}
      <p>Thanks, we got it.</p>
    {:else}
      <form action={endpoint} method="POST" {onsubmit}>
        <label>
          Email
          <input name="email" type="email" autocomplete="email" required aria-invalid={errors.email ? "true" : undefined} />
        </label>
        {#if errors.email}<p>{errors.email[0]}</p>{/if}
        <label>
          Message
          <textarea name="message" rows="5"></textarea>
        </label>
        <input type="hidden" name="_redirect" value={`${PUBLIC_SITE_URL}/contact/thanks`} />
        <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
        {#if status === "error" && !errors.email}<p role="alert">{message}</p>{/if}
        <button disabled={status === "sending"}>{status === "sending" ? "Sending" : "Send"}</button>
      </form>
    {/if}

    리디렉션 대상으로 src/routes/contact/thanks/+page.svelte를 추가하세요.

SvelteKit의 CSP를 사용한다면

kit.csp를 설정했다면 fetch POST와 일반 폼 POST 모두에 Ikiform을 허용하세요. 그렇지 않으면 브라우저가 둘 중 하나를 막습니다.

svelte.config.js
const config = {
  kit: {
    csp: {
      directives: {
        "connect-src": ["self", "https://ikiform.com"],
        "form-action": ["self", "https://ikiform.com"],
      },
    },
  },
};

export default config;

Allowed domains

프로덕션과 미리보기 호스트를 등록하세요.

폼이 실행되는 곳Allowed domains에 추가할 값
vite devlocalhost. http://localhost:5173과 일치합니다. Ikiform은 포트가 아니라 호스트 이름만 비교합니다.
여러분의 도메인example.com, www.example.com도 포함
Vercelyour-project.vercel.app. your-project-git-branch-team.vercel.app 같은 미리보기 URL은 일치하지 않으므로, 테스트하는 동안 정확한 미리보기 호스트를 추가하세요.
Cloudflare Pagesyour-project.pages.dev. abc123.your-project.pages.dev 같은 미리보기 URL은 하위 도메인이므로 이미 일치합니다.
Netlifyyour-site.netlify.app. 배포 미리보기(deploy-preview-12--your-site.netlify.app)와 브랜치 배포(branch--your-site.netlify.app)는 하위 도메인이 아니므로, 테스트하는 동안 정확한 미리보기 호스트를 추가하세요.
  • vercel.app, pages.dev, netlify.app만 단독으로 추가하지 마세요. 다른 사람의 사이트를 포함해 그 호스트의 모든 사이트가 일치하게 됩니다.

테스트 체크리스트

  1. 허용 도메인에 localhost를 넣고 개발 서버를 실행해 제출하세요. 감사 메시지가 폼을 대체해야 합니다.
  2. vite build를 실행하고, 결과물에 폼이 이미 들어 있는 contact.html이 있는지 확인하세요.
  3. JavaScript를 끄고 새로 고친 뒤 제출하세요. https: 도메인에서는 /contact/thanks로 이동해야 합니다.
  4. 미리보기 배포에서 제출하고 스팸으로 표시되지 않는지 확인하세요.

문제 해결

증상원인해결
빌드가 PUBLIC_IKIFORM_FORM_ID가 $env/static/public에서 export되지 않았다며 실패함빌드가 실행되는 곳에 변수가 설정되지 않음로컬의 .env와 호스트의 빌드 설정에 추가하세요.
제출해도 아무 일이 없고, 콘솔에 x-sveltekit-action 헤더에 관한 CORS 오류가 표시됨앱 밖으로 POST하는 폼에 use:enhance를 사용함제거하고 onsubmit 핸들러를 유지하세요.
form-action이나 connect-src 때문에 브라우저가 폼 전송을 거부함kit.csp에 Ikiform이 없음두 지시어 모두에 https://ikiform.com을 추가하세요.
JavaScript 없이 제출하면 Ikiform의 감사 페이지로 이동함PUBLIC_SITE_URL이 http:이거나, 도메인이 허용 도메인에 없음https: 주소를 사용하고 도메인을 추가하세요.
제출이 origin_mismatch와 함께 스팸 필터에 들어감POST한 페이지가 폼의 허용 도메인에 없음위 표의 호스트를 추가하세요. Reject를 골랐다면 같은 POST가 대신 403 origin_not_allowed를 받습니다.