Why this lesson matters

Understand validation and errors and use it correctly in an App Router project. Forms and Server Actions provide a direct server mutation path, but validation, authorization, error mapping and revalidation still belong to the mutation contract.

How to reason about it

  • For Validation and Errors, the outcome to verify is: A Server Action does not replace validation or authorization; enforce both at the server boundary.
  • In Validation and Errors, keep this failure controlled: Calling a Server Action from a form does not make it trusted; client input remains untrusted and permissions must be checked again on the server.
  • Validation and Errors practice target: Build a form whose Server Action validates input, checks access, writes data and returns a field-level error on failure.

Practical walkthrough

In the Validation and Errors walkthrough: A Server Action does not replace validation or authorization; enforce both at the server boundary.

actions.tstsx
'use server';

export async function createProject(formData: FormData) {
  const name = String(formData.get('name') ?? '').trim();
  if (!name) return { error: 'Name is required' };
  await saveProject({ name });
  return { ok: true };
}

Practice it yourself

Practice

Validation and Errors exercise

Build a form whose Server Action validates input, checks access, writes data and returns a field-level error on failure.

  • Record the expected result before execution
  • Test one valid path and one lesson-specific failure path
  • Explain in two lines which boundary owns the decision

Summary