Loading page
Server actions keep the endpoint server-side; client fetch keeps the visitor on the page.
// app/contact/actions.ts
"use server";
export async function sendContact(formData: FormData) {
const response = await fetch("https://formivo.faizyab.me/api/f/YOUR_FORM_ID", {
method: "POST",
headers: { "Content-Type": "application/json", Accept: "application/json" },
body: JSON.stringify(Object.fromEntries(formData)),
});
return { ok: response.ok };
}
// app/contact/page.tsx
import { sendContact } from "./actions";
export default function ContactPage() {
async function action(formData: FormData) {
"use server";
await sendContact(formData);
}
return (
<form action={action}>
<input name="email" type="email" required aria-label="Email" />
<button type="submit">Send</button>
</form>
);
}Server actions return whatever you return; the endpoint itself answers 201 or an error code.
| Symptom | Fix |
|---|---|
| Hydration error after submitting | Do not return JSX from an action; return data and render it. |
| Endpoint exposed in the bundle | Use a server action; NEXT_PUBLIC_ variables are public. |