FormsFort

JS Frameworks

FormsFort JavaScript framework guide for Vue, Svelte, Angular, and Alpine form submissions.

JS Frameworks

Use FormsFort from Vue, Svelte, Angular, or Alpine. These patterns mirror the Web3Forms framework examples: submit from the browser, include the public access key, and show the success or error message returned by the API.

Vue

Vue forms can post JSON from a composition API submit handler. Use FormData instead when the form includes file inputs.

<script setup lang="ts">
import { ref } from "vue";

const name = ref("");
const email = ref("");
const message = ref("");
const result = ref("");

async function submitForm() {
  result.value = "Sending...";

  const response = await fetch("https://api.formsfort.dev/submit", {
    method: "POST",
    headers: {
      accept: "application/json",
      "content-type": "application/json",
    },
    body: JSON.stringify({
      access_key: "YOUR_ACCESS_KEY",
      name: name.value,
      email: email.value,
      message: message.value,
    }),
  });

  const body = await response.json();
  result.value = body.message || (response.ok ? "Submitted." : "Submission failed.");
}
</script>

<template>
  <form @submit.prevent="submitForm">
    <input v-model="name" name="name" required />
    <input v-model="email" name="email" type="email" required />
    <textarea v-model="message" name="message" required></textarea>
    <button type="submit">Send Message</button>
    <p role="status">{{ result }}</p>
  </form>
</template>

Svelte

Svelte can use a native submit event and convert regular form fields to a JSON payload.

<script>
  let status = "";

  async function handleSubmit(event) {
    status = "Sending...";
    const formData = new FormData(event.currentTarget);

    const response = await fetch("https://api.formsfort.dev/submit", {
      method: "POST",
      headers: {
        "accept": "application/json",
        "content-type": "application/json"
      },
      body: JSON.stringify(Object.fromEntries(formData))
    });

    const body = await response.json();
    status = body.message || (response.ok ? "Submitted." : "Submission failed.");
  }
</script>

<form on:submit|preventDefault={handleSubmit}>
  <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />
  <input name="name" required />
  <input name="email" type="email" required />
  <textarea name="message" required></textarea>
  <button type="submit">Send</button>
</form>

<p role="status">{status}</p>

Angular service

Angular examples commonly isolate the API call in a service and let the component build FormData from a template-driven form.

import { Injectable } from "@angular/core";

@Injectable({ providedIn: "root" })
export class MailService {
  sendEmail(formData: FormData): Promise<Response> {
    return fetch("https://api.formsfort.dev/submit", {
      method: "POST",
      headers: { accept: "application/json" },
      body: formData,
    });
  }
}

Angular component submit

Append reserved fields in the component before calling the service. A browser-origin request is the default FormsFort protection model.

async submitEmail(contactForm: NgForm) {
  this.onSubmit = true;

  const formData = new FormData();
  formData.append("access_key", environment.formsfortAccessKey);
  formData.append("subject", "New website lead");
  formData.append("from_name", "Example Site");
  formData.append("name", this.contactFormValues.name);
  formData.append("email", this.contactFormValues.email);
  formData.append("message", this.contactFormValues.message);

  const response = await this.mailService.sendEmail(formData);
  const body = await response.json();
  this.alertMessage = body.message || (response.ok ? "Submitted." : "Submission failed.");

  if (response.ok) {
    contactForm.reset();
  }

  this.onSubmit = false;
}

Alpine.js

Alpine works well for small static forms that need inline loading and result state without a larger framework.

<form x-data="contactForm()" @submit.prevent="submit">
  <input type="hidden" name="access_key" value="YOUR_ACCESS_KEY" />
  <input name="name" required />
  <input name="email" type="email" required />
  <textarea name="message" required></textarea>
  <button type="submit" :disabled="loading">Send</button>
  <p x-text="status" role="status"></p>
</form>

<script>
  function contactForm() {
    return {
      loading: false,
      status: "",
      async submit(event) {
        this.loading = true;
        this.status = "Sending...";

        const formData = new FormData(event.currentTarget);
        const response = await fetch("https://api.formsfort.dev/submit", {
          method: "POST",
          headers: {
            accept: "application/json",
            "content-type": "application/json",
          },
          body: JSON.stringify(Object.fromEntries(formData)),
        });

        const body = await response.json();
        this.status = body.message || (response.ok ? "Submitted." : "Submission failed.");
        this.loading = false;
      },
    };
  }
</script>

On this page