# Vue

> Eine Vue-Single-File-Komponente, die an Ikiform sendet, plus eine Nuxt-Server-Route mit einem Secret Key.

Vue sendet aus dem Browser mit dem SDK oder `fetch`. Über dein übliches Setup hinaus brauchst du kein Plugin und keinen Build-Schritt.

## SDK installieren

`Terminal`:

```bash
npm install @ikiform/sdk
```

## Eine Single-File-Komponente

`ContactForm.vue`:

```vue
<script setup>
import { submit } from "@ikiform/sdk";
import { ref } from "vue";

const status = ref("idle");
const errors = ref({});
const message = ref("");

async function onSubmit(event) {
  status.value = "sending";
  const result = await submit("frm_xxxxxxxxxxxxxxxx", new FormData(event.target));
  if (result.ok) {
    status.value = "sent";
    return;
  }
  errors.value = result.error.fields ?? {};
  message.value = result.error.message;
  status.value = "error";
}
</script>

<template>
  <p v-if="status === 'sent'">Thanks, we got it.</p>
  <form v-else @submit.prevent="onSubmit">
    <label>
      Email
      <input name="email" type="email" required />
    </label>
    <p v-if="errors.email">{{ errors.email[0] }}</p>
    <label>
      Message
      <textarea name="message"></textarea>
    </label>
    <input name="_gotcha" type="text" tabindex="-1" autocomplete="off" hidden />
    <p v-if="status === 'error' && !errors.email" role="alert">{{ message }}</p>
    <button :disabled="status === 'sending'">Send</button>
  </form>
</template>
```

Für Formulare mit der **Ikiform**-Menschlichkeitsprüfung rufst du `challenge(formId)` vor `submit` auf und übergibst das Token als `{ turnstileToken }`, wie in der [React-Anleitung](https://ikiform.com/de/docs/guides/react.md#component).

## Nuxt-Server-Route

Um stattdessen vom Server zu senden, füge eine Server-Route hinzu, die den Body mit einem Secret Key weiterleitet. Die Seite sendet dann JSON an deine eigene Route. Für eine Komponente, die direkt aus dem Browser sendet, mit einem Fallback vor der Hydration, siehe [Nuxt](https://ikiform.com/de/docs/guides/nuxt.md).

`server/api/contact.post.ts`:

```ts
export default defineEventHandler(async (event) => {
  const body = await readBody(event);
  return $fetch("https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx", {
    method: "POST",
    headers: { Authorization: `Bearer ${process.env.IKIFORM_SECRET_KEY}` },
    body,
    ignoreResponseError: true,
  });
});
```

> 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.
