Skip to main content
Build a basic contact form in Svelte that submits directly to PipedForm using fetch, with reactive state for handling submission status.

Basic Example

<script>
  let status = 'idle';
  let message = '';

  let name = '';
  let email = '';
  let formMessage = '';

  const onSubmit = async () => {
    status = 'loading';

    const res = await fetch('https://pipedform.com/f/{form_id}', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        name,
        email,
        message: formMessage,
      }),
    });

    const data = await res.json();

    if (res.ok) {
      status = 'success';
      message = 'Form submitted successfully';
    } else {
      status = 'error';
      message = data.message;
    }
  };
</script>

<form on:submit|preventDefault={onSubmit}>
  <input name="name" bind:value={name} placeholder="John" required />
  <input
    type="email"
    name="email"
    bind:value={email}
    placeholder="[email protected]"
    required
  />
  <textarea
    name="message"
    bind:value={formMessage}
    placeholder="Enter your message..."
    required
  ></textarea>

  {#if status === 'error'}
    <p style="color: red">{message}</p>
  {/if}
  {#if status === 'success'}
    <p style="color: green">{message}</p>
  {/if}

  <button type="submit">
    {#if status === 'loading'}
      Loading...
    {:else}
      Send
    {/if}
  </button>
</form>