Add a contact form to a Next.js site

Add a contact form to Next.js with SiteBackend - a plain HTML form or a client component with fetch. Works with static export.

1 minUpdated

SiteBackend works with any Next.js setup, including output: "export", because the form posts straight to SiteBackend.

Option 1: a plain form (no JavaScript)

A Server Component is enough. The browser posts the form and SiteBackend redirects back.

app/contact/page.tsx
export default function ContactPage() {
  return (
    <form action="https://api.sitebackend.com/forms/YOUR_FORM_ID" method="POST">
      <input type="email" name="email" required />
      <textarea name="message" required />
      <input type="text" name="_gotcha" tabIndex={-1} autoComplete="off" hidden />
      <button type="submit">Send</button>
    </form>
  );
}

Option 2: a client component with fetch

Stay on the page and show your own messages.

app/contact/contact-form.tsx
"use client";
 
import { useState } from "react";
 
const ENDPOINT = process.env.NEXT_PUBLIC_SITEBACKEND_FORM!;
 
export function ContactForm() {
  const [status, setStatus] = useState<"idle" | "sending" | "sent" | "error">("idle");
  const [error, setError] = useState("");
 
  async function onSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setStatus("sending");
    const res = await fetch(ENDPOINT, {
      method: "POST",
      body: new FormData(event.currentTarget),
      headers: { Accept: "application/json" },
    });
    const result = await res.json();
    if (result.ok) {
      setStatus("sent");
    } else {
      setError(result.error);
      setStatus("error");
    }
  }
 
  if (status === "sent") return <p>Thanks! We'll be in touch.</p>;
  return (
    <form onSubmit={onSubmit}>
      <input type="email" name="email" required />
      <textarea name="message" required />
      <button type="submit" disabled={status === "sending"}>
        {status === "sending" ? "Sending…" : "Send"}
      </button>
      {status === "error" && <p role="alert">{error}</p>}
    </form>
  );
}
.env.local
NEXT_PUBLIC_SITEBACKEND_FORM=https://api.sitebackend.com/forms/YOUR_FORM_ID

Local development

If you use allowed origins, add http://localhost:3000.

Show testimonials too

SiteBackend can also collect testimonials from your customers and show them on your site. See add testimonials to a Next.js site.