Svelte と SvelteKit
ブラウザーから送信する Svelte 5 のコンポーネントと、シークレットキーで送信する SvelteKit のフォームアクション。
Svelte のコンポーネント
npm install @ikiform/sdk で SDK をインストールし、ブラウザーからフォームを送信します:
<script>
import { submit } from "@ikiform/sdk";
let status = $state("idle");
let errors = $state({});
let message = $state("");
async function onsubmit(event) {
event.preventDefault();
status = "sending";
const result = await submit("frm_xxxxxxxxxxxxxxxx", new FormData(event.currentTarget));
if (result.ok) {
status = "sent";
return;
}
errors = result.error.fields ?? {};
message = result.error.message;
status = "error";
}
</script>
{#if status === "sent"}
<p>Thanks, we got it.</p>
{:else}
<form {onsubmit}>
<label>
Email
<input name="email" type="email" required />
</label>
{#if errors.email}<p>{errors.email[0]}</p>{/if}
<label>
Message
<textarea name="message"></textarea>
</label>
<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"}>Send</button>
</form>
{/if}SvelteKit のフォームアクション
フォームアクションは JavaScript なしで動き、読み込まれると拡張されます。アクションは、IKIFORM_SECRET_KEY として保存したシークレットキーで Ikiform に送信します。サーバーのないプリレンダリングページについては SvelteKit を参照してください。
import { env } from "$env/dynamic/private";
import { fail } from "@sveltejs/kit";
export const actions = {
default: async ({ request }) => {
const data = await request.formData();
const body = new URLSearchParams();
for (const [name, value] of data) if (typeof value === "string") body.append(name, value);
const response = await fetch("https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx", {
method: "POST",
headers: { Accept: "application/json", Authorization: `Bearer ${env.IKIFORM_SECRET_KEY}` },
body,
});
const result = await response.json();
if (!result.ok) return fail(response.status, { message: result.error.message, fields: result.error.fields ?? {} });
return { sent: true };
},
};<script>
import { enhance } from "$app/forms";
let { form } = $props();
</script>
{#if form?.sent}
<p>Thanks, we got it.</p>
{:else}
<form method="POST" use:enhance>
<label>
Email
<input name="email" type="email" required />
</label>
{#if form?.fields?.email}<p>{form.fields.email[0]}</p>{/if}
<label>
Message
<textarea name="message"></textarea>
</label>
{#if form?.message && !form?.fields?.email}<p role="alert">{form.message}</p>{/if}
<button>Send</button>
</form>
{/if}サーバーから送られる送信はすべてサーバーの IP アドレスから届くため、Ikiform の訪問者ごとのレート制限は全訪問者をまとめてカウントします。標準のプリセットは IP とフォームごとに 1 分あたり 5 件までなので、アクセスの多いサイトでは上限に達することがあります。可能ならブラウザーから送信するか、サーバーを経由するフォームでは緩めまたはカスタムのレート制限を選んでください。