Skip to main content
ConvexQueryClient supports SSR by using ConvexHttpClient to fetch query results on the server. On the client, the WebSocket subscription takes over and keeps data live.

How it works

  • On the server (typeof window === "undefined"), convexQueryClient.queryFn() uses ConvexHttpClient to make HTTP requests instead of opening a WebSocket subscription.
  • By default, SSR fetches use consistent mode: multiple queries are fetched from the same logical database snapshot. This prevents inconsistencies when your UI joins data across multiple queries.
  • You can opt out with dangerouslyUseInconsistentQueriesDuringSSR: true for a faster but potentially inconsistent SSR render.

Basic SSR setup

Construct ConvexQueryClient with a serverFetch option to supply a custom fetch implementation for server-side HTTP requests.

Consistent vs. inconsistent SSR queries

Why consistent queries matter

When your React code joins data from multiple queries, both queries must reflect the same database state. In consistent mode, Convex guarantees this on the server.
In inconsistent mode, favChannelIds could reference channel IDs that don’t yet exist in channels because the two HTTP requests may have hit different database snapshots.

Using with TanStack Start

In TanStack Start, use createServerOnlyFn to ensure the serverFetch implementation is never bundled into the client.
The serverFetch option should be server-only code. In TanStack Start, wrap it with createServerOnlyFn to avoid bundling it on the client.
During client-side navigation, the WebSocket subscription is used — SSR only affects the initial server render.