Four differences that change how you write code
Four differences that change how you write code in the Next.js to ShadowJS guide.
- No server components. Every component runs twice: to a string on the server for the first request, and in the
browser after hydration. There is no component that only runs on the server, no
"use client"boundary and no serialized component tree. Data reaches a component through a routeloaderanduseLoaderData; code that must stay on the server lives in a server function, an API route, or a file named*.server.ts. - Loaders run in the browser too. On the first request the server runs the loader and embeds its result in the
page. On a client navigation the router runs the loader in the browser. A loader therefore never touches a database
directly; it calls a server function, which the build turns into a
fetchin the browser bundle. - Server functions are explicit RPC. A server function has a stable URL (
/_dusk/fn/<id>), validates its input with a schema, and answers with a value, anHttpErroror a redirect. Nothing is revalidated for you: after a mutation you callrouter.invalidate(). - One handler.
createHandlerbuilds afetch(Request) => Responsefunction. Pages, API routes, server functions and middleware all go through it, so a CSRF check, a body limit or a header applies to all of them.