Vue
A Vue single-file component that submits to Ikiform, plus a Nuxt server route with a secret key.
Vue posts from the browser with the SDK or fetch. No plugin or build step is needed beyond your usual setup.
Install the SDK
npm install @ikiform/sdkA single-file component
<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>For forms with the Ikiform human check, call challenge(formId) before submit and pass the token as { turnstileToken }, as in the React guide.
Nuxt server route
To post from the server instead, add a server route that forwards the body with a secret key. The page then posts JSON to your own route.
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 sent from your server all come from your server's IP address, so Ikiform's per-visitor rate limits count every visitor together. The Standard preset allows 5 posts a minute per IP and form, which a busy site can hit. Post from the browser when you can, or choose the Relaxed or Custom rate limit for forms you proxy through a server.