Repository navigation
[Bug?]: [v2] routerLoad (3rd createHandler argument) dropped during v2 rewrite β TanStack Router SSR returns HTTP 500Β #2221
Description
Duplicates
- I have searched the existing issues
Latest version
- I have tested the latest version
Current behavior π―
During the v2 rewrite (PR #1942, "Devinxi"), the 3rd argument to createHandler β routerLoad, introduced in #1840 to enable TanStack Router SSR β appears to have been removed without a replacement API or migration guide.
Any SolidStart v2 app using TanStack Router SSR with the official template's pattern returns HTTP 500 with TypeError: Cannot read properties of undefined (reading 'state'), because the router store is never initialized on the server.
Concretely:
createHandler(fn, options = {})now accepts only 2 arguments; the 3rd argument is silently dropped.- The router store never gets initialized on the server.
- SSR throws; server returns HTTP 500.
Expected behavior π€
Per the v1 behavior documented in #1840:
routerLoadis invoked at the top ofprovideRequestEvent, initializing the router store before render.- TanStack Router SSR works correctly; server returns HTTP 200 with rendered HTML.
Steps to reproduce πΉ
Steps:
- Create a SolidStart v2 app using the official
with-tanstack-routertemplate (@solidjs/start@2.0.0-beta.0, released 2026-07-15). - Note the template calls
createHandler(fn, undefined, routerLoad)insrc/entry-server.tsx:createHandler(fn, undefined, routerLoad)
- Make an SSR request:
curl http://localhost:3000/
- Actual: HTTP 500 with
TypeError: Cannot read properties of undefined (reading 'state'). - Root cause: The 3rd argument is ignored by the rewritten
createHandler, which now accepts only 2 arguments.
Quick verification β I built @solidjs/start locally from the patched handler.ts (restoring routerLoad) and tried it against the same template:
# Before patch (v2.0.0-beta.0)
$ curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/
500
# After patch (with routerLoad restored)
$ curl -s -o /dev/null -w "%{http_code}" http://localhost:3000/
200
$ curl -s http://localhost:3000/ | grep -o '<title>[^<]*</title>'
<title>SolidStart</title>After the patch: SSR renders correctly (HTTP 200, proper HTML), no SSR errors in console, client navigation works as expected.
Context π¦
Why this reads as an accidental regression (though I may be missing context):
- The DevinxiΒ #1942 PR body, code review, and linked issue don't mention removing
routerLoadanywhere β it may simply have been absorbed in a ~30k-line rewrite. - Official docs (
create-handler.mdx) still documentrouterLoad?: (event: FetchEvent) => Promise<void>as a valid parameter even after the rewrite. - The official v2
with-tanstack-routertemplate still callscreateHandler(fn, undefined, routerLoad), which no longer works. - I couldn't find any issue or PR that discusses an intentional removal.
- Git history of
packages/start/src/server/handler.ts: introduced β removed β no re-add.
Scope note: This seems distinct from #2145, #2206, and #2133 β those address the stream output layer ([object Object] serialization), whereas this is about the router initialization layer (the SSR hook that primes the router store before render). Different layer, likely a different fix.
Timeline:
| Date | Event | PR/Commit |
|---|---|---|
| 2025-03-03 | #1840 β "feat: add ssr for tanstack router" (@brenelz) introduces routerLoad as optional 3rd createHandler arg |
26e97be1 |
| 2025-11-07 | #1942 β "Devinxi" (@Brendonovich) full v2 rewrite of handler.ts (vinxi β h3). routerLoad removed; createBaseHandler arg order changed from (fn, createPageEvent, options, routerLoad) to (createPageEvent, fn, options). No replacement API or migration note. |
bb63bb39 |
| 2026-05-06 | solid-docs create-handler.mdx updated AFTER #1942 and STILL documents routerLoad?: (event: FetchEvent) => Promise<void> as a valid API |
(docs commit) |
| 2026-07-15 | @solidjs/start@2.0.0-beta.0 released |
(npm release) |
| 2026-07-17β18 | #2206 (@brenelz) stream output fix β UNRELATED to router initialization (fixes the stream transport layer, not the router init layer) | (separate issue) |
One possible direction : restore routerLoad as an optional, backward-compatible 3rd argument to createHandler:
export function createHandler(
fn: (context: PageEvent) => JSX.Element,
options: HandlerOptions | ((context: PageEvent) => HandlerOptions | Promise<HandlerOptions>) = {},
routerLoad?: (event: FetchEvent) => Promise<void>, // restored, optional
): H3 {
if (routerLoad) {
const _createPageEvent = createPageEvent;
const customCreatePageEvent = async (e: FetchEvent) => {
const pageEvent = await _createPageEvent(e);
await routerLoad(e);
return pageEvent;
};
return createBaseHandler(customCreatePageEvent, fn, options);
}
return createBaseHandler(createPageEvent, fn, options);
}When
optionsis an async function, users can technically callrouter.update()+await router.load()inside it β but that only really works for routers that expose those methods.routerLoadfelt like the cleaner general-purpose hook, which I assume is why #1840 added it.
If the team would prefer a more general onRequest/initSSR callback (or something else entirely), I'd be glad to go in whatever direction feels right.
A few things I'd love a steer on:
- Does restoring
routerLoad(or something like it) feel like the right call, or is there a differently-shaped SSR initializer the team would rather go with? - If something does get restored, would it make sense to sync the docs and the template at the same time? Right now the docs still list
routerLoadbut the runtime has dropped it. - Would it be worth revisiting
createBaseHandler's arg order too, or keep the v2 order and just restore the publiccreateHandlerentry point?
Happy to open a PR in whichever direction the team prefers β and very happy to be corrected if I've misread any of the history.
Your environment π
System:
OS: macOS 25.5.0
CPU: arm64
Binaries:
Node: 20.x
npmPackages:
@solidjs/start: 2.0.0-beta.0Related:
#1840 (introduced routerLoad)
#1942 (v2 rewrite, where routerLoad appears dropped)
#2206 / #2145 / #2133 (stream output layer, separate)
TanStack/router#3521 (original SSR feature request motivating #1840)
solid-cli/PR#78 (where this surfaced via the with-tanstack-router template)
Activity