Uh oh!
There was an error while loading. Please reload this page.
feat: use seroval for SSR - #4600
Conversation
also stream all queries in react-router-with-query
View your CI Pipeline Execution ↗ for commit 9220a3e
☁️ Nx Cloud last updated this comment at |
More templates
@tanstack/arktype-adapter@tanstack/directive-functions-plugin@tanstack/eslint-plugin-router@tanstack/history@tanstack/react-router@tanstack/react-router-devtools@tanstack/react-router-with-query@tanstack/react-start@tanstack/react-start-client@tanstack/react-start-plugin@tanstack/react-start-server@tanstack/router-cli@tanstack/router-core@tanstack/router-devtools@tanstack/router-devtools-core@tanstack/router-generator@tanstack/router-plugin@tanstack/router-utils@tanstack/router-vite-plugin@tanstack/server-functions-plugin@tanstack/solid-router@tanstack/solid-router-devtools@tanstack/solid-start@tanstack/solid-start-client@tanstack/solid-start-plugin@tanstack/solid-start-server@tanstack/start-client-core@tanstack/start-plugin-core@tanstack/start-server-core@tanstack/start-server-functions-client@tanstack/start-server-functions-fetcher@tanstack/start-server-functions-server@tanstack/valibot-adapter@tanstack/virtual-file-routes@tanstack/zod-adaptercommit: |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
| type: 'stream' | ||
| value?: ReadableStream & { controller?: ReadableStreamDefaultController } | ||
| export interface TsrSsrGlobal { | ||
| r?: DehydratedRouter |
There was a problem hiding this comment.
While it makes sense for the matches to have keys be shortened (i.e. i, b, l, etc.), I think these single callers may benefit from just being left with having descriptive names to represent their purpose (i.e. router/dehydratedRouter, close, whatever_v_is).
There was a problem hiding this comment.
renamed r to router, v is gone
added a comment to c ( the cleanup function), this is called per script injection and thus benefits from a short name
| import { isPlainObject } from '@tanstack/router-core' | ||
| export interface TsrSerializer { | ||
| export interface StartSerializer { |
There was a problem hiding this comment.
Why does the Serializer get moved to Start? why not keep it in router-core.
Wouldn't this same serializer benefit normal basic-file-based-ssr-streaming as well?
There was a problem hiding this comment.
this PR only uses seroval for SSR
for server functions, we still use the old serializer. in a followup PR, we'll move server functions over to seroval as well
| hydrate as queryHydrate, | ||
| } from '@tanstack/react-query' | ||
| import { isRedirect } from '@tanstack/router-core' | ||
| import '@tanstack/router-core/ssr/client' |
There was a problem hiding this comment.
what's the issue here?
There was a problem hiding this comment.
Is this intended to import this module like side effect without import specific functions, etc?
There was a problem hiding this comment.
the import is necessary to get the type import. is there any problem with that import?
There was a problem hiding this comment.
Sorry for disturbing.
I expected to see something like:
import { type SomeType } from '@tanstack/router-core/ssr/client'
instead of import '@tanstack/router-core/ssr/client'
gunnartorfis
commented
Jul 17, 2025
@schiller-manuel this breaks Clerk with Tanstack Start. The Clerk starter isn't working in the latest start version. The getAuth() function throws: https://github.com/TanStack/router/tree/main/examples/react/start-clerk-basic The reason I reach out here is that I want to point the Clerk team towards something if the fix lies no their end. |
AhmedBaset
commented
Jul 19, 2025
Is there a way to configure a custom serializer? seems like firebase' Timestamp is broken |
schiller-manuel
commented
Jul 19, 2025
@AhmedBaset not yet. there will be a way to add custom seroval plugins |
AhmedBaset
commented
Jul 19, 2025
Any fixes at the moment except downgrading? |
schiller-manuel
commented
Jul 19, 2025
don't return anything from loader / beforeLoad that contains custom classes |
ttessarolo
commented
Jul 23, 2025
@schiller-manuel for instance "clerkInitialState" is a custom class (or maybe QueryClient)? |
…dratedMatch `DehydratedMatch['b']` is typed as `MakeRouteMatch['__beforeLoadContext']`, an indexed-access into `RouteMatch['__beforeLoadContext']`. That field has been tagged `@internal` since TanStack#4600 (2025-07-11); TanStack#4907 (2025-08-10) then enabled `stripInternal` repo-wide specifically to remove `@internal` members from the published `.d.ts`. From `router-core@1.171.16` onward the published types no longer have `RouteMatch.__beforeLoadContext`, but `ssr/types.ts` (moved to its current path by TanStack#6118, content otherwise unchanged) still indexes into it, leaving a dangling reference. This went unnoticed by plain SPA consumers for weeks because nothing in the always-imported client path pulled `ssr/types.ts` into their type graph. TanStack#7805's `load-client.ts` rewrite (2026-08-04) changed that: it imports `TsrSsrGlobal` from `./ssr/types`, and `load-client.ts` is core hydration code every consumer's `tsc` walks, SSR or not. Combined with `skipLibCheck: false` (the TS default), that's enough to fail with: error TS2339: Property '__beforeLoadContext' does not exist on type 'MakeRouteMatch'. Since `__beforeLoadContext` is declared as `Record<string, unknown>` in source, give `b` that concrete type directly instead of indexing into the stripped member. Verified against a built package: the emitted `dist/esm/ssr/types.d.ts` no longer references the internal member, and a minimal consumer repro (`skipLibCheck: false`, importing `createRouter`/`createRootRoute`) type- checks cleanly with this dist swapped in.

also stream all queries in react-router-with-query