Basic Form Component
Create a contact form component:src/components/ContactForm.jsx
Copy
import React, { useState } from "react";
export default function ContactForm({ formSlug }) {
const [status, setStatus] = useState("idle");
const handleSubmit = async (e) => {
e.preventDefault();
setStatus("loading");
const data = new FormData(e.target);
const res = await fetch(`https://spike.ac/api/f/${formSlug}`, {
method: "POST",
body: data,
headers: { Accept: "application/json" },
});
setStatus(res.ok ? "success" : "error");
if (res.ok) e.target.reset();
};
return (
<form onSubmit={handleSubmit}>
<input type="text" name="_gotcha" style={{ display: "none" }} />
<input type="text" name="name" placeholder="Name" required />
<input type="email" name="email" placeholder="Email" required />
<textarea name="message" placeholder="Message" required />
<button disabled={status === "loading"}>
{status === "loading" ? "Sending..." : "Send"}
</button>
{status === "success" && <p>Thanks!</p>}
{status === "error" && <p>Error, please try again.</p>}
</form>
);
}
Usage
src/pages/contact.js
Copy
import React from "react";
import ContactForm from "../components/ContactForm";
export default function ContactPage() {
return (
<div>
<h1>Contact Us</h1>
<ContactForm formSlug="YOUR_FORM_SLUG" />
</div>
);
}
TypeScript Version
src/components/ContactForm.tsx
Copy
import React, { useState, FormEvent } from "react";
interface ContactFormProps {
formSlug: string;
}
type Status = "idle" | "loading" | "success" | "error";
export default function ContactForm({ formSlug }: ContactFormProps) {
const [status, setStatus] = useState<Status>("idle");
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
setStatus("loading");
const form = e.currentTarget;
const data = new FormData(form);
try {
const res = await fetch(`https://spike.ac/api/f/${formSlug}`, {
method: "POST",
body: data,
headers: { Accept: "application/json" },
});
setStatus(res.ok ? "success" : "error");
if (res.ok) form.reset();
} catch {
setStatus("error");
}
};
return (
<form onSubmit={handleSubmit}>
<input type="text" name="_gotcha" style={{ display: "none" }} />
<input type="text" name="name" placeholder="Name" required />
<input type="email" name="email" placeholder="Email" required />
<textarea name="message" placeholder="Message" required />
<button type="submit" disabled={status === "loading"}>
{status === "loading" ? "Sending..." : "Send"}
</button>
{status === "success" && <p>Thanks!</p>}
{status === "error" && <p>Error, please try again.</p>}
</form>
);
}
Simple HTML Form
For basic use without JavaScript:Copy
<form action="https://spike.ac/api/f/YOUR_FORM_SLUG" method="POST">
<input type="hidden" name="_next" value="/thanks/" />
<input type="text" name="_gotcha" style="display:none" />
<input type="text" name="name" required />
<input type="email" name="email" required />
<textarea name="message" required></textarea>
<button type="submit">Send</button>
</form>