Browse documentation

Server and client boundaries

Know which FlowPanel values stay on the server and what reaches browser components.

FlowPanel uses React Server Components and route handlers to keep database and policy work on the server. Client components receive a narrow serializable model for interaction.

ValueBoundary
Adapter, database client, auth config, secretsServer only
Resource policies, scope predicates, action run, widget queriesServer only
Server column renderersExecute on server; rendered result may cross
Declared row fields and client metadataSerialized when needed by the current surface
Table/form/drawer state and client hooksBrowser
SSE event channel and payloadBrowser after server authorization

Config is not client data

Do not import flowpanel.config.ts from a "use client" module. It can close over database clients, environment variables, functions, and React server renderers. The Next runtime derives a serializable client metadata view instead.

Renderers can bridge intentionally

A column renderer runs on the server and may return ordinary server-rendered content. It can also return a client component, provided its props are serializable. Pass the minimum display/interaction model—not the complete row or request context.

Forms resolve server values before rendering

Dynamic choices, field visibility, roles, and create defaults are resolved on the server. Non-serializable validators and default functions are not sent to the browser. Submission repeats policy and validation instead of trusting the rendered form.

Client hooks call public boundaries

Table, mutation, and realtime hooks use the configured API base and stream path. Providers can change those mount points without exposing the server config. Errors returned to clients should be safe for operators; unexpected internal detail belongs in server logs.

SSE is a notification boundary

Realtime payloads must be serializable and size-bounded. Prefer an action and ID that causes an authorized refetch over broadcasting row data. Every subscriber to a channel can receive its payload after stream authorization.

When a customization needs browser state, isolate the client component and keep its data/mutation functions behind an authorized server route. See Column renderers and Typed client reference.