Command Palette

Search for a command to run...

Hectal
Back to the lesson: Topic 20.3 — Server Functions and Server Actions
React · Example 2 of 2

Server Functions are public: authorise every call

A model of the defensive pattern from the Next.js security guide: take only an id from the client, get the user from the session, and look the record up by id and owner together. The unsafe version lets a signed-in user delete someone else's note just by changing the arguments.

A Server Function is an async function marked "use server" that runs on the server but can be called from the client like a normal function; used as a form action it is called a Server Action, works before JavaScript loads, and is a public HTTP endpoint that must validate its input and authorise every call.

Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.

Ready for more? This phase has 5 hands-on exercises with automatic checks.

Practice questions

Write the code in the editor, run it, then open the model answer to compare.

01

Write a "use server" function renameList(listId: string, formData: FormData) that renames a to-do list only if the signed-in user owns it and the new name is 1 to 40 characters.

02

Write the client form for it using useActionState with a pending label and an error message.

Explain it without notes

01

What is a Server Function, how do you declare one, and how does the client call it?

02

What is the difference between a Server Function and a Server Action?

03

What is progressive enhancement and how do Server Actions support it?

04

Why must every Server Function authorise and validate on its own? What checks belong in it?

Server Functions are public: authorise every call

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

unsafe: notes left 1 of 2
safe, someone else's note: { ok: false, error: 'Not found' }
safe, no cookie: { ok: false, error: 'Unauthorized' }
safe, bad input: { ok: false, error: 'Invalid id' }
safe, own note: { ok: true }
left: [ 'Note by Ravi' ]