The form
Replace YOUR-ACCESS-KEY with the key from your form's page. The highlighted line is the one that points the form at Formwire.
1<!-- src/lib/ContactForm.svelte -->2<script>3let status = "idle";45async function onSubmit(e) {6e.preventDefault();7status = "sending";8const body = new FormData(e.currentTarget);9body.append("access_key", "YOUR-ACCESS-KEY");10const res = await fetch("https://formwire.io/submit", {11method: "POST",12headers: { Accept: "application/json" },13body,14});15const { success } = await res.json();16status = success ? "sent" : "error";17}18</script>1920{#if status === "sent"}21<p>Thanks, your message is on its way.</p>22{:else}23<form on:submit={onSubmit}>24<input type="text" name="fax" tabindex="-1" autocomplete="off" style="display:none" />25<label for="name">Name</label>26<input id="name" name="name" type="text" required />27<label for="email">Email</label>28<input id="email" name="email" type="email" required />29<label for="message">Message</label>30<textarea id="message" name="message" rows="5" required></textarea>31<button type="submit" disabled={status === "sending"}>32{status === "sending" ? "Sending" : "Send"}33</button>34{#if status === "error"}35<p>Something went wrong. Please try again.</p>36{/if}37</form>38{/if}
Steps
- 1
Create a form and copy its access key
Sign up at app.formwire.com and create a form. Your sign-in address receives its submissions from the start. The access key is on the form's Settings tab, under General.
- 2
Add the component
Create src/lib/ContactForm.svelte with the code above and replace YOUR-ACCESS-KEY with your key. In Svelte 5 write onsubmit={onSubmit} instead of on:submit; the body is the same.
- 3
Render it from a route
Import the component into a page. With adapter-static the page prerenders and the fetch runs in the browser on submit.
svelte 1
<!-- src/routes/contact/+page.svelte -->2<script>3import ContactForm from "$lib/ContactForm.svelte";4</script>56<h1>Contact</h1>7<ContactForm /> - 4
Send a test submission
Open localhost:5173/contact, fill the form in and send it. The submission appears in the form's inbox in the dashboard within a few seconds and the notification email follows, with Reply-To set to the address the visitor typed.
Notes for Svelte
- No +page.server.js form action is needed. Add one only if you want to run your own code before the submission is stored, and post to Formwire from the action with fetch.
- SvelteKit's use:enhance is for form actions on your own server. Leave it off; this form never posts to your site.
- For a full-page redirect instead of an in-page state, remove the submit handler, set action and method on the form, and add the hidden redirect and access_key fields as in the HTML guide.
Questions
Does this work with adapter-static?
Yes. The page prerenders to HTML and the fetch runs in the visitor's browser, so the site has no server to deploy. It also works with every other SvelteKit adapter.
Is the access key safe to put in client-side code?
Yes. The access key is a public ID that can only deliver submissions to the inbox you verified. It cannot read submissions or change settings, and you can rotate it from the form's settings if it is ever abused.
How does the form stop spam without a captcha?
The hidden fax field is a honeypot: a submission that fills it in goes to the Spam folder and nobody is emailed. A spam filter and rate limits also run on every form. Settings, Spam & security has the filter level, and on Pro, allowed domains.
Where do submissions go?
Each submission is stored in the form's inbox in the dashboard and emailed to you with Reply-To set to the visitor. On Pro it can also go to more recipients and to webhooks. The inbox exports to CSV and JSON.