# Svelte und SvelteKit

> Eine Svelte-5-Komponente, die aus dem Browser sendet, und eine SvelteKit-Form-Action, die mit einem Secret Key sendet.

## Svelte-Komponente

Installiere das SDK mit `npm install @ikiform/sdk` und sende das Formular dann aus dem Browser:

`ContactForm.svelte`:

```svelte
<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-Form-Action

Eine Form Action funktioniert ohne JavaScript und wird erweitert, sobald es geladen ist. Die Action sendet mit einem Secret Key, gespeichert als `IKIFORM_SECRET_KEY`, an Ikiform. Für eine vorgerenderte Seite ohne Server siehe [SvelteKit](https://ikiform.com/de/docs/guides/sveltekit.md).

`src/routes/contact/+page.server.js`:

```js
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 };
  },
};
```

`src/routes/contact/+page.svelte`:

```svelte
<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}
```

> Posts von deinem Server kommen alle von der IP-Adresse deines Servers, sodass Ikiforms Rate-Limits pro Besucher alle Besucher zusammen zählen. Das Preset Standard erlaubt 5 Posts pro Minute pro IP und Formular, was eine viel besuchte Website erreichen kann. Sende aus dem Browser, wenn du kannst, oder wähle das [Rate-Limit](https://ikiform.com/de/docs/rate-limits.md) Relaxed oder Custom für Formulare, die du über einen Server weiterleitest.
