svelte-onsubmit

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

bash
npm install svelte-onsubmit

Quick start

Option A — OnSubmitForm component (recommended)

Drop-in replacement for a plain <form>. Handles loading state, errors, and success message automatically:

svelte
<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>
Your form ID is available in the onsubmit.dev dashboard after creating a form.

Option B — useOnSubmit function (full control)

Use the function when you need to drive your own UI state:

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

PropTypeDescription
formIdstringRequired. Your onsubmit.dev form ID.
successMessagestringText rendered in place of the form on success.
endpointstringOverride the default API base URL.
onSuccess(data: unknown) => voidCalled after a successful submission.
onError(error: unknown) => voidCalled when submission fails.

Function API

Reactive state powered by Svelte 5 runes — values update automatically in your template without .value or explicit subscriptions.

Options

OptionTypeDescription
formIdstringRequired. Your onsubmit.dev form ID.
endpointstringOverride the default API base URL.
onSuccess(data: unknown) => voidCalled after a successful submission.
onError(error: unknown) => voidCalled when submission fails.

Returns

PropertyTypeDescription
handleSubmit(e: Event) => Promise<void>Pass directly to <form onsubmit={...}>.
isLoadingbooleantrue while the request is in flight.
isSuccessbooleantrue after a successful submission.
errorstring | nullError message, or null if none.
dataunknownRaw response from the API.
reset() => voidResets 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:

svelte
<OnSubmitForm formId="YOUR_FORM_ID" endpoint="https://your-instance.example.com/f">
  ...
</OnSubmitForm>

Or with the function:

ts
const { handleSubmit } = useOnSubmit({
  formId: 'YOUR_FORM_ID',
  endpoint: 'https://your-instance.example.com/f',
});