Build a contact form with Next.js 15 App Router
Use the App Router, Server Actions, and useActionState for a typed, progressive-enhancement contact form.
- 1
Create a Server Action
Add `'use server'` to a function that reads FormData and POSTs to FormLoom with `Accept: application/json`.
- 2
Bind it with useActionState
Wrap the action in `useActionState` to track the pending state and returned JSON.
- 3
Render the form
Pass the action to `<form action={...}>`. The form works with JavaScript disabled too.
example.tsx
"use server";
export async function submitContact(prev: unknown, fd: FormData) {
const res = await fetch("https://api.formloom.ai/submit/YOUR_ACCESS_KEY", {
method: "POST",
headers: { Accept: "application/json" },
body: fd,
});
return res.json();
}FAQ
Yes — App Router + React 19 form actions are the canonical way to use this pattern in Next.js 15.