Ask
45
@newborn_noob ·

is it normal that server actions post to the page url instead of an api route Mutations

Coming from express, so I expected to see POST /api/something. Devtools shows POST /dashboard with a Next-Action: 60a1c8... header, and the response body is a stream of numbered lines rather than JSON. Nothing in my code mentions /dashboard as an endpoint. Is that expected or did I wire something up wrong?

6 answers Share
Report

Answering anonymously — a moderator will review it first.

  • @iron_camber · 3w ago · 2 replies

    Expected. Actions are addressed by an id, not by a URL — the header is the id, and the POST goes to whatever route you are currently on so the server can re-render that route and stream the updated UI back in the same response as your return value. That is why you get one round trip for "mutate and refresh" instead of two.

    The numbered lines are the RSC payload format. It is not meant to be read by humans and it is not a stable API.

    77
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @newborn_noob · 3w ago

      So the revalidated UI and the return value come back together. That explains why my router.refresh() after every action was doing nothing useful except a second fetch.

      12
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
  • @slowmiles_kat · 3w ago · 2 replies

    The consequences are what matter:

    • You cannot curl it as an API and you should not try. If a mobile client or a third party needs to call it, write a route handler.
    • It is still a public endpoint. Anyone can craft that POST with any arguments. Do auth and ownership checks inside the action, not in the component that renders the button.
    • Middleware runs on it, same as any request.
    39
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @crypt_cass · 3w ago

      That middleware line catches people constantly. Auth middleware that issues a redirect on an expired session turns an action call into a mystery response with an HTML body, and the client-side error is completely uninformative. Handle the POST case explicitly.

      20
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
  • @gpio_gwen · 3w ago

    Rule of thumb: actions are for your own UI, route handlers are for anything with another consumer. Mixing that up is how people end up trying to version a server action.

    24
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
  • @layer_shift_lu · 3w ago

    One downside nobody mentions until they are staring at a dashboard: every action shows up in your metrics as a POST to the page route, so all of them share one latency series. If you care, tag the span or log the action name yourself.

    14
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report