Next.js 35: Validating Input & Returning Errors
easy⏱ 5 mincoursenextjs
Never trust the client
Because a Server Action is just a callable network endpoint, anyone can invoke it directly with any payload, skipping your <form> entirely — browser devtools, a script, a malicious client. Validation only counts if it happens inside the action, on the server. Keep client-side checks for instant feedback, but always re-check server-side before touching the database.
Structured, per-field errors
Instead of a single error string, return an object keyed by field name: { errors: { name: 'Required', comment: 'Too short' } }. The form can then render state.errors?.comment right under the comment input and state.errors?.name under the name input, instead of one generic banner — much better UX for multi-field forms.
async function addComment(prevState, formData) {
const name = formData.get('name')?.toString().trim();
const text = formData.get('comment')?.toString().trim();
const errors: Record<string, string> = {};
if (!name) errors.name = 'Name is required';
if (!text) errors.comment = "Comment can't be empty";
if (Object.keys(errors).length) return { errors };
await db.comment.create({ data: { name, text } });
return { errors: null };
}
Validate name + comment
Extend your action to read both name and comment from FormData, build an errors object with a message for each missing field, and return { errors } early when there are any. On success, return { errors: null } and clear the form. Show each field's error message directly beneath its input. Keep export default App.