Svelte
Svelte function and component for onsubmit.dev. Connect any Svelte form to your onsubmit.dev endpoint with zero dependencies. No backend required. Built for Svelte 5 runes.
Installation
npm install svelte-onsubmitQuick start
Option A — OnSubmitForm component (recommended)
Drop-in replacement for a plain <form>. Handles loading state, errors, and success message automatically:
<script lang="ts">
import { OnSubmitForm } from 'svelte-onsubmit';
</script>
<OnSubmitForm formId="YOUR_FORM_ID" successMessage="Thanks! We'll be in touch.">
<input name="name" placeholder="Your name" required />
<input name="email" type="email" placeholder="Email" required />
<textarea name="message" placeholder="Message"></textarea>
<button type="submit">Send</button>
</OnSubmitForm>Option B — useOnSubmit function (full control)
Use the function when you need to drive your own UI state:
<script lang="ts">
import { useOnSubmit } from 'svelte-onsubmit';
const { handleSubmit, isLoading, isSuccess, error, reset } = useOnSubmit({
formId: 'YOUR_FORM_ID',
onSuccess: (data) => console.log('Submitted!', data),
onError: (err) => console.error('Failed:', err),
});
</script>
{#if isSuccess}
<p>Thanks! We'll be in touch.</p>
<button onclick={reset}>Send another</button>
{:else}
<form onsubmit={handleSubmit}>
<input name="name" placeholder="Your name" required />
<input name="email" type="email" placeholder="Email" required />
{#if error}
<p style="color: red">{error}</p>
{/if}
<button type="submit" disabled={isLoading}>
{isLoading ? 'Sending…' : 'Send'}
</button>
</form>
{/if}Component props
OnSubmitForm accepts the following props. All other attributes are forwarded to the underlying <form> element.
| Prop | Type | Description |
|---|---|---|
| formId | string | Required. Your onsubmit.dev form ID. |
| successMessage | string | Text rendered in place of the form on success. |
| endpoint | string | Override the default API base URL. |
| onSuccess | (data: unknown) => void | Called after a successful submission. |
| onError | (error: unknown) => void | Called when submission fails. |
Function API
Reactive state powered by Svelte 5 runes — values update automatically in your template without .value or explicit subscriptions.
Options
| Option | Type | Description |
|---|---|---|
| formId | string | Required. Your onsubmit.dev form ID. |
| endpoint | string | Override the default API base URL. |
| onSuccess | (data: unknown) => void | Called after a successful submission. |
| onError | (error: unknown) => void | Called when submission fails. |
Returns
| Property | Type | Description |
|---|---|---|
| handleSubmit | (e: Event) => Promise<void> | Pass directly to <form onsubmit={...}>. |
| isLoading | boolean | true while the request is in flight. |
| isSuccess | boolean | true after a successful submission. |
| error | string | null | Error message, or null if none. |
| data | unknown | Raw response from the API. |
| reset | () => void | Resets all state back to initial values. |
File uploads
File inputs are handled automatically. When the form contains a file field the data is sent as multipart/form-data. Otherwise JSON is used.
Custom endpoint
Useful for self-hosted deployments:
<OnSubmitForm formId="YOUR_FORM_ID" endpoint="https://your-instance.example.com/f">
...
</OnSubmitForm>Or with the function:
const { handleSubmit } = useOnSubmit({
formId: 'YOUR_FORM_ID',
endpoint: 'https://your-instance.example.com/f',
});