FormLoom

Framer feedback form

Collect product or page feedback with an optional rating.

Recommended fields

FieldTypeRequired
emailemailNo
ratingselectNo
feedbacktextareaYes

The code

Add an Embed element to your Framer page, choose HTML, and paste a `<form method="POST">` block pointing at FormLoom. Include a small `<style>` block in the same embed so the form matches your site's design.

Plain HTML (no JavaScript)
contact.html
<form action="https://formloom.vercel.app/api/submit/YOUR_ACCESS_KEY" method="POST">
  <label>
    Email (optional)
    <input type="email" name="email" />
  </label>
  <label>
    Rating
    <select name="rating">
      <option value="5 — Excellent">5 — Excellent</option>
      <option value="4 — Good">4 — Good</option>
      <option value="3 — OK">3 — OK</option>
      <option value="2 — Poor">2 — Poor</option>
      <option value="1 — Bad">1 — Bad</option>
    </select>
  </label>
  <label>
    Your feedback
    <textarea name="feedback" required></textarea>
  </label>
  <!-- honeypot: bots fill this, humans don't see it -->
  <input type="checkbox" name="botcheck" style="display:none" tabindex="-1" autocomplete="off" />
  <button type="submit">Send</button>
</form>
AJAX fetch (vanilla JS)
contact.html
<form id="contact-form">
  <label>
    Email (optional)
    <input type="email" name="email" />
  </label>
  <label>
    Rating
    <select name="rating">
      <option value="5 — Excellent">5 — Excellent</option>
      <option value="4 — Good">4 — Good</option>
      <option value="3 — OK">3 — OK</option>
      <option value="2 — Poor">2 — Poor</option>
      <option value="1 — Bad">1 — Bad</option>
    </select>
  </label>
  <label>
    Your feedback
    <textarea name="feedback" required></textarea>
  </label>
  <!-- honeypot: bots fill this, humans don't see it -->
  <input type="checkbox" name="botcheck" style="display:none" tabindex="-1" autocomplete="off" />
  <button type="submit">Send</button>
</form>

<script>
const form = document.getElementById("contact-form");
form.addEventListener("submit", async (e) => {
  e.preventDefault();
  const res = await fetch("https://formloom.vercel.app/api/submit/YOUR_ACCESS_KEY", {
    method: "POST",
    headers: { "Content-Type": "application/json", Accept: "application/json" },
    body: JSON.stringify(Object.fromEntries(new FormData(form))),
  });
  const data = await res.json();
  if (data.success) {
    form.reset();
    alert("Thanks — we got your message.");
  } else {
    alert(data.message || "Something went wrong.");
  }
});
</script>
@formloom/client (typed SDK)
submit.ts
// npm i @formloom/client
import { createForm } from "@formloom/client";

type Contact = {
  email?: string;
  rating?: string;
  feedback: string;
};

const form = createForm<Contact>("YOUR_ACCESS_KEY");

// End-to-end typed: TS errors if you send the wrong shape.
const { success, message } = await form.submit({
  email: form.email.value,
  rating: form.rating.value,
  feedback: form.feedback.value,
});

Tips

  • Make email optional to lower friction for quick feedback.
  • Pipe feedback to Slack via a webhook for real-time triage.

FAQ

No — keep email optional so people leave quick feedback without committing.
Framer feedback form — copy-paste code + live demo · FormLoom