Skip to content

ExamplesServer Actions

Server Actions

Mutate data with Server Actions + direct mode. The page revalidates automatically after each action.

direct mode

Server Action Definition

Define actions in a "use server" file. call runs on the server, revalidatePath refreshes the page.

ts
// app/actions/actions.ts
"use server"

import { createAction } from "@noverax/courier-next"
import { revalidatePath } from "next/cache"
import { sources } from "@/api"

const action = createAction(sources, "api")

export async function createUser(_prev: ActionState, formData: FormData) {
  const name = formData.get("name") as string
  const email = formData.get("email") as string
  const role = formData.get("role") as string

  const user = await action.users.create({ name, email, role })
  revalidatePath("/docs/examples/actions")
  return { success: true, data: user }
}

Server Actions run on the server. They call the backend directly through createAction, then revalidatePath renders the page's server data again.

Server Actions docs

Create User

useActionState connects the form to the server action. Pending state and results are handled automatically.

ts
// app/actions/create-form.tsx
"use client"

import { useActionState } from "react"
import { createUser } from "./actions"

export function CreateUserForm() {
  const [state, action, isPending] = useActionState(createUser, {})

  return (
    <form action={action}>
      <input name="name" required />
      <input name="email" type="email" required />
      <button type="submit" disabled={isPending}>Create</button>
      {state.data && <pre>{JSON.stringify(state.data)}</pre>}
    </form>
  )
}
createUser — a Server ActionSANDBOX
idle
// run the request to see the response

User List + Delete

Server-fetched list with per-row delete actions. Deleted rows disappear after revalidation.

ts
// Server action for delete + revalidation
export async function deleteUser(_prev: ActionState, formData: FormData) {
  const id = Number(formData.get("id"))
  await action.users.remove({ id })
  revalidatePath("/docs/examples/actions")
  return { success: true }
}

// Client component with hidden form
function UserRow({ user }) {
  const [state, action, isPending] = useActionState(deleteUser, {})
  return (
    <form action={action}>
      <input type="hidden" name="id" value={user.id} />
      <button type="submit" disabled={isPending}>Delete</button>
    </form>
  )
}
  • Alice Johnsonadmin

    alice@example.com

  • Bob Smithuser

    bob@example.com

  • Carol Williamsmoderator

    carol@example.com