Next.js Forms: fetch() or Server Actions
Two ways to submit a Next.js form to Formboost — a Server Action or client-side fetch — with no API route, plus the redirect, honeypot and reserved fields.
Next.js supports both client-side form handling (with fetch) and Server Actions (App Router). Both work seamlessly with Formboost — no API route, no backend code.
Prerequisites
- A Formboost account (sign up free)
- A Next.js project (App Router or Pages Router)
Step 1: Create a Formboost Endpoint
Log in to your Formboost dashboard and create a new endpoint. Copy the endpoint URL:
https://formboost.app/f/YOUR_ENDPOINT_IDStep 2: Add the Form
Option A — Client Component with fetch (App & Pages Router)
// components/ContactForm.tsx
"use client";
import { useState } from "react";
type Status = "idle" | "submitting" | "success" | "error";
export function ContactForm() {
const [status, setStatus] = useState<Status>("idle");
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
setStatus("submitting");
const form = e.currentTarget;
const data = Object.fromEntries(new FormData(form));
try {
const res = await fetch("https://formboost.app/f/YOUR_ENDPOINT_ID", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
});
if (res.ok) {
setStatus("success");
form.reset();
} else {
setStatus("error");
}
} catch {
setStatus("error");
}
}
return (
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="name">Name</label>
<input type="text" id="name" name="name" required />
</div>
<div>
<label htmlFor="email">Email</label>
<input type="email" id="email" name="email" required />
</div>
<div>
<label htmlFor="message">Message</label>
<textarea id="message" name="message" rows={5} />
</div>
<button type="submit" disabled={status === "submitting"}>
{status === "submitting" ? "Sending…" : "Send"}
</button>
{status === "success" && <p>Message sent! We'll be in touch soon.</p>}
{status === "error" && <p>Something went wrong. Please try again.</p>}
</form>
);
}Use it in any page:
// app/contact/page.tsx
import { ContactForm } from "@/components/ContactForm";
export default function ContactPage() {
return (
<main>
<h1>Contact</h1>
<ContactForm />
</main>
);
}Option B — Server Action (App Router)
Server Actions let you handle the form submission server-side without an API route. The POST goes from your Next.js server to Formboost — not directly from the browser.
// app/contact/page.tsx
export default function ContactPage() {
async function submit(formData: FormData) {
"use server";
const data = {
name: formData.get("name"),
email: formData.get("email"),
message: formData.get("message"),
};
await fetch("https://formboost.app/f/YOUR_ENDPOINT_ID", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
});
}
return (
<main>
<h1>Contact</h1>
<form action={submit}>
<div>
<label htmlFor="name">Name</label>
<input type="text" id="name" name="name" required />
</div>
<div>
<label htmlFor="email">Email</label>
<input type="email" id="email" name="email" required />
</div>
<div>
<label htmlFor="message">Message</label>
<textarea id="message" name="message" rows={5} />
</div>
<button type="submit">Send</button>
</form>
</main>
);
}Replace YOUR_ENDPOINT_ID with your actual endpoint ID in both options.
Step 3: Test It
Run npm run dev and submit the form. The submission will appear in your Formboost dashboard within seconds.
Next Steps
Set Up the n8n Integration
Connect a Formboost form to an n8n Webhook node — cloud or self-hosted — so every submission triggers a workflow. Setup, payload shape and the 404 fix.
Gatsby Forms: React State and fetch()
Submit a Gatsby form to a Formboost endpoint with React hooks and fetch — no serverless function, with loading and success states and spam screening.