Migrating from Next
These tables map the form and mutation features of Next to Silgi. They cover forms and handlers only; the tables on pages, data and the server in Migrating from Nuxt apply to any app. none means Silgi has no equivalent today.
The shape is one thing in Silgi: a handler, a typed function that runs on the server, exported from server/index.ts. A form posts to it (Form action={fn}), a component calls it (useAction(fn), useAsyncData(fn, input)), and with a route a URL answers it. It works without JavaScript, it is a public endpoint that must check who calls it, and it needs no directive.
| Next | Silgi | Differences |
|---|---|---|
"use server" at the top of a file or in a function | defineHandler exports of server/index.ts | there is no directive; a handler is a module-level export, and a closure over component variables is not supported |
<form action={serverAction}> | <Form action={fn}> | works without JavaScript; a plain <form action={fn}> calls the stub with JavaScript only |
useActionState(action, initial) | useAction(fn, { initial }) | state, failure, error, pending in all six libraries |
useFormStatus from react-dom | useFormStatus from @silgi/react | reads the Form it is in |
useOptimistic | React's useOptimistic, or useOptimistic from @silgi/react | Silgi's takes the running handler calls |
revalidatePath("/x") | refresh(event, fn, input) in the handler | primes the read the page makes next, so it sends nothing |
revalidateTag | none | |
redirect("/x") | redirect("/x") from silgi/app | return or throw it |
notFound() | throw createError({ status: 404 }) | |
cookies(), headers() | getCookie(event, …), getRequestHeader(event, …) | event is ctx.event |
| validate with Zod by hand | input: schema | any Standard Schema; 400 Validation failed with data.issues |
serverActions.bodySizeLimit | server.maxBodySize | default 1 MiB; a handler's form.maxBodySize replaces it for that handler |
serverActions.allowedOrigins | server.originCheck.allow | |
| a Server Action as a public endpoint | the same | authorize inside every handler; see Every handler is a public endpoint |
server-only package | server-only or silgi/server-only | the import guard fails the client build |
route handlers (route.ts) | a handler with a route | raw: true for a webhook or a raw body |
after() | none | |
| streaming a result from an action | return an AsyncIterable | the caller iterates with for await |