Skip to main content
Build a basic contact form in Astro that submits directly to PipedForm using fetch, with a client-side script for handling submission status.

Basic Example

<form id="contact-form">
  <input id="name" name="name" required />
  <input id="email" name="email" type="email" required />
  <textarea id="message" name="message" required></textarea>
  <p id="form-status"></p>

  <button type="submit" id="submit-btn">Submit</button>
</form>

<script>
  const form = document.getElementById('contact-form') as HTMLFormElement;
  const submitBtn = document.getElementById('submit-btn') as HTMLButtonElement;
  const status = document.getElementById('form-status') as HTMLParagraphElement;

  form.addEventListener('submit', async (e) => {
    e.preventDefault();

    submitBtn.disabled = true;
    submitBtn.textContent = 'Sending...';
    status.textContent = '';

    try {
      const formData = new FormData(form);

      const response = await fetch('https://pipedform.com/f/{form_id}', {
        method: 'POST',
        body: formData,
        headers: {
          Accept: 'application/json',
        },
      });

      if (response.ok) {
        status.textContent = 'Thanks! Your message has been sent.';
        form.reset();
      } else {
        status.textContent = 'Something went wrong. Please try again.';
      }
    } catch (error) {
      status.textContent = 'Network error. Please check your connection.';
    } finally {
      submitBtn.disabled = false;
      submitBtn.textContent = 'Submit';
    }
  });
</script>