From 39d1efa68df54a333cab4a215d26a96796b2d5df Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Tue, 21 Oct 2025 01:55:10 +0200
Subject: [PATCH 01/33] test(solid-start): serialization-adapters suite

---
 .../serialization-adapters/.gitignore         |  20 ++
 .../serialization-adapters/.prettierignore    |   4 +
 .../serialization-adapters/package.json       |  31 +++
 .../playwright.config.ts                      |  34 +++
 .../serialization-adapters/postcss.config.mjs |   6 +
 .../serialization-adapters/src/CustomError.ts |  31 +++
 .../serialization-adapters/src/data.tsx       | 205 ++++++++++++++++++
 .../src/routeTree.gen.ts                      | 179 +++++++++++++++
 .../serialization-adapters/src/router.tsx     |  11 +
 .../src/routes/__root.tsx                     |  71 ++++++
 .../src/routes/index.tsx                      |  56 +++++
 .../routes/server-function/custom-error.tsx   |  69 ++++++
 .../src/routes/server-function/nested.tsx     |  34 +++
 .../src/routes/ssr/data-only.tsx              |  51 +++++
 .../src/routes/ssr/nested.tsx                 |  14 ++
 .../src/routes/ssr/stream.tsx                 |  31 +++
 .../serialization-adapters/src/start.tsx      |  16 ++
 .../serialization-adapters/src/styles/app.css |  22 ++
 .../tailwind.config.mjs                       |   4 +
 .../serialization-adapters/tests/app.spec.ts  | 112 ++++++++++
 .../serialization-adapters/tsconfig.json      |  23 ++
 .../serialization-adapters/vite.config.ts     |  17 ++
 pnpm-lock.yaml                                |  46 ++++
 23 files changed, 1087 insertions(+)
 create mode 100644 e2e/solid-start/serialization-adapters/.gitignore
 create mode 100644 e2e/solid-start/serialization-adapters/.prettierignore
 create mode 100644 e2e/solid-start/serialization-adapters/package.json
 create mode 100644 e2e/solid-start/serialization-adapters/playwright.config.ts
 create mode 100644 e2e/solid-start/serialization-adapters/postcss.config.mjs
 create mode 100644 e2e/solid-start/serialization-adapters/src/CustomError.ts
 create mode 100644 e2e/solid-start/serialization-adapters/src/data.tsx
 create mode 100644 e2e/solid-start/serialization-adapters/src/routeTree.gen.ts
 create mode 100644 e2e/solid-start/serialization-adapters/src/router.tsx
 create mode 100644 e2e/solid-start/serialization-adapters/src/routes/__root.tsx
 create mode 100644 e2e/solid-start/serialization-adapters/src/routes/index.tsx
 create mode 100644 e2e/solid-start/serialization-adapters/src/routes/server-function/custom-error.tsx
 create mode 100644 e2e/solid-start/serialization-adapters/src/routes/server-function/nested.tsx
 create mode 100644 e2e/solid-start/serialization-adapters/src/routes/ssr/data-only.tsx
 create mode 100644 e2e/solid-start/serialization-adapters/src/routes/ssr/nested.tsx
 create mode 100644 e2e/solid-start/serialization-adapters/src/routes/ssr/stream.tsx
 create mode 100644 e2e/solid-start/serialization-adapters/src/start.tsx
 create mode 100644 e2e/solid-start/serialization-adapters/src/styles/app.css
 create mode 100644 e2e/solid-start/serialization-adapters/tailwind.config.mjs
 create mode 100644 e2e/solid-start/serialization-adapters/tests/app.spec.ts
 create mode 100644 e2e/solid-start/serialization-adapters/tsconfig.json
 create mode 100644 e2e/solid-start/serialization-adapters/vite.config.ts

diff --git a/e2e/solid-start/serialization-adapters/.gitignore b/e2e/solid-start/serialization-adapters/.gitignore
new file mode 100644
index 0000000000..08eba9e706
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/.gitignore
@@ -0,0 +1,20 @@
+node_modules
+package-lock.json
+yarn.lock
+
+.DS_Store
+.cache
+.env
+.vercel
+.output
+/build/
+/api/
+/server/build
+/public/build# Sentry Config File
+.env.sentry-build-plugin
+/test-results/
+/playwright-report/
+/blob-report/
+/playwright/.cache/
+
+count.txt
diff --git a/e2e/solid-start/serialization-adapters/.prettierignore b/e2e/solid-start/serialization-adapters/.prettierignore
new file mode 100644
index 0000000000..2be5eaa6ec
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/.prettierignore
@@ -0,0 +1,4 @@
+**/build
+**/public
+pnpm-lock.yaml
+routeTree.gen.ts
\ No newline at end of file
diff --git a/e2e/solid-start/serialization-adapters/package.json b/e2e/solid-start/serialization-adapters/package.json
new file mode 100644
index 0000000000..26cda2301a
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/package.json
@@ -0,0 +1,31 @@
+{
+  "name": "tanstack-solid-start-e2e-serialization-adapters",
+  "private": true,
+  "sideEffects": false,
+  "type": "module",
+  "scripts": {
+    "dev": "vite dev --port 3000",
+    "dev:e2e": "vite dev",
+    "build": "vite build && tsc --noEmit",
+    "start": "pnpx srvx --prod -s ../client dist/server/server.js",
+    "test:e2e": "rm -rf port*.txt; playwright test --project=chromium"
+  },
+  "dependencies": {
+    "@tanstack/solid-router": "workspace:^",
+    "@tanstack/solid-router-devtools": "workspace:^",
+    "@tanstack/solid-start": "workspace:^",
+    "solid-js": "^1.9.5",
+    "vite": "^7.1.7",
+    "vite-tsconfig-paths": "^5.1.4",
+    "zod": "^3.24.2"
+  },
+  "devDependencies": {
+    "@tanstack/router-e2e-utils": "workspace:^",
+    "vite-plugin-solid": "^2.11.9",
+    "@types/node": "^22.10.2",
+    "postcss": "^8.5.1",
+    "srvx": "^0.8.6",
+    "tailwindcss": "^3.4.17",
+    "typescript": "^5.7.2"
+  }
+}
diff --git a/e2e/solid-start/serialization-adapters/playwright.config.ts b/e2e/solid-start/serialization-adapters/playwright.config.ts
new file mode 100644
index 0000000000..badd6db0eb
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/playwright.config.ts
@@ -0,0 +1,34 @@
+import { defineConfig, devices } from '@playwright/test'
+import { getTestServerPort } from '@tanstack/router-e2e-utils'
+import packageJson from './package.json' with { type: 'json' }
+
+const PORT = await getTestServerPort(packageJson.name)
+const baseURL = `http://localhost:${PORT}`
+/**
+ * See https://playwright.dev/docs/test-configuration.
+ */
+export default defineConfig({
+  testDir: './tests',
+  workers: 1,
+
+  reporter: [['line']],
+
+  use: {
+    /* Base URL to use in actions like `await page.goto('/')`. */
+    baseURL,
+  },
+
+  webServer: {
+    command: `VITE_SERVER_PORT=${PORT} pnpm build && NODE_ENV=production PORT=${PORT} VITE_SERVER_PORT=${PORT} pnpm start`,
+    url: baseURL,
+    reuseExistingServer: !process.env.CI,
+    stdout: 'pipe',
+  },
+
+  projects: [
+    {
+      name: 'chromium',
+      use: { ...devices['Desktop Chrome'] },
+    },
+  ],
+})
diff --git a/e2e/solid-start/serialization-adapters/postcss.config.mjs b/e2e/solid-start/serialization-adapters/postcss.config.mjs
new file mode 100644
index 0000000000..2e7af2b7f1
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/postcss.config.mjs
@@ -0,0 +1,6 @@
+export default {
+  plugins: {
+    tailwindcss: {},
+    autoprefixer: {},
+  },
+}
diff --git a/e2e/solid-start/serialization-adapters/src/CustomError.ts b/e2e/solid-start/serialization-adapters/src/CustomError.ts
new file mode 100644
index 0000000000..06104320b2
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/src/CustomError.ts
@@ -0,0 +1,31 @@
+import { createSerializationAdapter } from '@tanstack/solid-router'
+
+export class CustomError extends Error {
+  public foo: string
+  public bar: bigint
+
+  constructor(message: string, options: { foo: string; bar: bigint }) {
+    super(message)
+
+    Object.setPrototypeOf(this, new.target.prototype)
+
+    this.name = this.constructor.name
+    this.foo = options.foo
+    this.bar = options.bar
+  }
+}
+
+export const customErrorAdapter = createSerializationAdapter({
+  key: 'custom-error',
+  test: (v) => v instanceof CustomError,
+  toSerializable: ({ message, foo, bar }) => {
+    return {
+      message,
+      foo,
+      bar,
+    }
+  },
+  fromSerializable: ({ message, foo, bar }) => {
+    return new CustomError(message, { foo, bar })
+  },
+})
diff --git a/e2e/solid-start/serialization-adapters/src/data.tsx b/e2e/solid-start/serialization-adapters/src/data.tsx
new file mode 100644
index 0000000000..60293450af
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/src/data.tsx
@@ -0,0 +1,205 @@
+import { createSerializationAdapter } from '@tanstack/solid-router'
+
+export class Foo {
+  constructor(public value: string) {}
+}
+
+export interface Car {
+  __type: 'car'
+  make: string
+  model: string
+  year: number
+  honk: () => { message: string; make: string; model: string; year: number }
+}
+
+export function makeCar(opts: {
+  make: string
+  model: string
+  year: number
+}): Car {
+  return {
+    ...opts,
+    __type: 'car',
+    honk: () => {
+      return { message: `Honk! Honk!`, ...opts }
+    },
+  }
+}
+
+export const fooAdapter = createSerializationAdapter({
+  key: 'foo',
+  test: (value: any) => value instanceof Foo,
+  toSerializable: (foo) => foo.value,
+  fromSerializable: (value) => new Foo(value),
+})
+
+export const carAdapter = createSerializationAdapter({
+  key: 'car',
+  test: (value: any): value is Car =>
+    '__type' in (value as Car) && value.__type === 'car',
+  toSerializable: (car) => ({
+    make: car.make,
+    model: car.model,
+    year: car.year,
+  }),
+  fromSerializable: (value: { make: string; model: string; year: number }) =>
+    makeCar(value),
+})
+
+export function makeData() {
+  function makeFoo(suffix: string = '') {
+    return new Foo(typeof window === 'undefined' ? 'server' : 'client' + suffix)
+  }
+  return {
+    foo: {
+      singleInstance: makeFoo(),
+      array: [makeFoo('0'), makeFoo('1'), makeFoo('2')],
+      map: new Map([
+        [0, makeFoo('0')],
+        [1, makeFoo('1')],
+        [2, makeFoo('2')],
+      ]),
+      mapOfArrays: new Map([
+        [0, [makeFoo('0-a'), makeFoo('0-b')]],
+        [1, [makeFoo('1-a'), makeFoo('1-b')]],
+        [2, [makeFoo('2-a'), makeFoo('2-b')]],
+      ]),
+    },
+    car: {
+      singleInstance: makeCar({
+        make: 'Toyota',
+        model: 'Camry',
+        year: 2020,
+      }),
+      array: [
+        makeCar({ make: 'Honda', model: 'Accord', year: 2019 }),
+        makeCar({ make: 'Ford', model: 'Mustang', year: 2021 }),
+      ],
+      map: new Map([
+        [0, makeCar({ make: 'Chevrolet', model: 'Malibu', year: 2018 })],
+        [1, makeCar({ make: 'Nissan', model: 'Altima', year: 2020 })],
+        [2, makeCar({ make: 'Hyundai', model: 'Sonata', year: 2021 })],
+      ]),
+      mapOfArrays: new Map([
+        [0, [makeCar({ make: 'Kia', model: 'Optima', year: 2019 })]],
+        [1, [makeCar({ make: 'Subaru', model: 'Legacy', year: 2020 })]],
+        [2, [makeCar({ make: 'Volkswagen', model: 'Passat', year: 2021 })]],
+      ]),
+    },
+  }
+}
+export class NestedOuter {
+  constructor(public inner: NestedInner) {}
+  whisper() {
+    return this.inner.value.toLowerCase()
+  }
+}
+
+export class NestedInner {
+  constructor(public value: string) {}
+  shout() {
+    return this.value.toUpperCase()
+  }
+}
+
+export const nestedInnerAdapter = createSerializationAdapter({
+  key: 'nestedInner',
+  test: (value): value is NestedInner => value instanceof NestedInner,
+  toSerializable: (inner) => inner.value,
+  fromSerializable: (value) => new NestedInner(value),
+})
+
+export const nestedOuterAdapter = createSerializationAdapter({
+  key: 'nestedOuter',
+  extends: [nestedInnerAdapter],
+  test: (value) => value instanceof NestedOuter,
+  toSerializable: (outer) => outer.inner,
+  fromSerializable: (value) => new NestedOuter(value),
+})
+
+export function makeNested() {
+  return new NestedOuter(new NestedInner('Hello World'))
+}
+
+export function RenderData({
+  id,
+  data,
+}: {
+  id: string
+  data: ReturnType<typeof makeData>
+}) {
+  const localData = makeData()
+  return (
+    <div data-testid={`${id}-container`}>
+      <h3>Car</h3>
+      <h4>expected</h4>
+      <div data-testid={`${id}-car-expected`}>
+        {JSON.stringify({
+          make: localData.car.singleInstance.make,
+          model: localData.car.singleInstance.model,
+          year: localData.car.singleInstance.year,
+        })}
+      </div>
+      <h4>actual</h4>
+      <div data-testid={`${id}-car-actual`}>
+        {JSON.stringify({
+          make: data.car.singleInstance.make,
+          model: data.car.singleInstance.model,
+          year: data.car.singleInstance.year,
+        })}
+      </div>
+      <b>Foo</b>
+      <div data-testid={`${id}-foo`}>
+        {JSON.stringify({
+          value: data.foo.singleInstance.value,
+        })}
+      </div>
+    </div>
+  )
+}
+
+export function RenderNestedData({ nested }: { nested: NestedOuter }) {
+  {
+    const localData = makeNested()
+    const expectedShoutState = localData.inner.shout()
+    const expectedWhisperState = localData.whisper()
+    const shoutState = nested.inner.shout()
+    const whisperState = nested.whisper()
+
+    return (
+      <div data-testid="data-only-container">
+        <h2 data-testid="data-only-heading">data-only</h2>
+        <div data-testid="shout-container">
+          <h3>shout</h3>
+          <div>
+            expected:{' '}
+            <div data-testid="shout-expected-state">
+              {JSON.stringify(expectedShoutState)}
+            </div>
+          </div>
+          <div>
+            actual:{' '}
+            <div data-testid="shout-actual-state">
+              {JSON.stringify(shoutState)}
+            </div>
+          </div>
+        </div>
+        <div data-testid="whisper-container">
+          <h3>whisper</h3>
+          <div>
+            expected:{' '}
+            <div data-testid="whisper-expected-state">
+              {JSON.stringify(expectedWhisperState)}
+            </div>
+          </div>
+          <div>
+            actual:{' '}
+            <div data-testid="whisper-actual-state">
+              {JSON.stringify(whisperState)}
+            </div>
+          </div>
+        </div>
+      </div>
+    )
+  }
+}
diff --git a/e2e/solid-start/serialization-adapters/src/routeTree.gen.ts b/e2e/solid-start/serialization-adapters/src/routeTree.gen.ts
new file mode 100644
index 0000000000..09d0211154
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/src/routeTree.gen.ts
@@ -0,0 +1,179 @@
+/* eslint-disable */
+
+// @ts-nocheck
+
+// noinspection JSUnusedGlobalSymbols
+
+// This file was automatically generated by TanStack Router.
+// You should NOT make any changes in this file as it will be overwritten.
+// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
+
+import { Route as rootRouteImport } from './routes/__root'
+import { Route as IndexRouteImport } from './routes/index'
+import { Route as SsrStreamRouteImport } from './routes/ssr/stream'
+import { Route as SsrNestedRouteImport } from './routes/ssr/nested'
+import { Route as SsrDataOnlyRouteImport } from './routes/ssr/data-only'
+import { Route as ServerFunctionNestedRouteImport } from './routes/server-function/nested'
+import { Route as ServerFunctionCustomErrorRouteImport } from './routes/server-function/custom-error'
+
+const IndexRoute = IndexRouteImport.update({
+  id: '/',
+  path: '/',
+  getParentRoute: () => rootRouteImport,
+} as any)
+const SsrStreamRoute = SsrStreamRouteImport.update({
+  id: '/ssr/stream',
+  path: '/ssr/stream',
+  getParentRoute: () => rootRouteImport,
+} as any)
+const SsrNestedRoute = SsrNestedRouteImport.update({
+  id: '/ssr/nested',
+  path: '/ssr/nested',
+  getParentRoute: () => rootRouteImport,
+} as any)
+const SsrDataOnlyRoute = SsrDataOnlyRouteImport.update({
+  id: '/ssr/data-only',
+  path: '/ssr/data-only',
+  getParentRoute: () => rootRouteImport,
+} as any)
+const ServerFunctionNestedRoute = ServerFunctionNestedRouteImport.update({
+  id: '/server-function/nested',
+  path: '/server-function/nested',
+  getParentRoute: () => rootRouteImport,
+} as any)
+const ServerFunctionCustomErrorRoute =
+  ServerFunctionCustomErrorRouteImport.update({
+    id: '/server-function/custom-error',
+    path: '/server-function/custom-error',
+    getParentRoute: () => rootRouteImport,
+  } as any)
+
+export interface FileRoutesByFullPath {
+  '/': typeof IndexRoute
+  '/server-function/custom-error': typeof ServerFunctionCustomErrorRoute
+  '/server-function/nested': typeof ServerFunctionNestedRoute
+  '/ssr/data-only': typeof SsrDataOnlyRoute
+  '/ssr/nested': typeof SsrNestedRoute
+  '/ssr/stream': typeof SsrStreamRoute
+}
+export interface FileRoutesByTo {
+  '/': typeof IndexRoute
+  '/server-function/custom-error': typeof ServerFunctionCustomErrorRoute
+  '/server-function/nested': typeof ServerFunctionNestedRoute
+  '/ssr/data-only': typeof SsrDataOnlyRoute
+  '/ssr/nested': typeof SsrNestedRoute
+  '/ssr/stream': typeof SsrStreamRoute
+}
+export interface FileRoutesById {
+  __root__: typeof rootRouteImport
+  '/': typeof IndexRoute
+  '/server-function/custom-error': typeof ServerFunctionCustomErrorRoute
+  '/server-function/nested': typeof ServerFunctionNestedRoute
+  '/ssr/data-only': typeof SsrDataOnlyRoute
+  '/ssr/nested': typeof SsrNestedRoute
+  '/ssr/stream': typeof SsrStreamRoute
+}
+export interface FileRouteTypes {
+  fileRoutesByFullPath: FileRoutesByFullPath
+  fullPaths:
+    | '/'
+    | '/server-function/custom-error'
+    | '/server-function/nested'
+    | '/ssr/data-only'
+    | '/ssr/nested'
+    | '/ssr/stream'
+  fileRoutesByTo: FileRoutesByTo
+  to:
+    | '/'
+    | '/server-function/custom-error'
+    | '/server-function/nested'
+    | '/ssr/data-only'
+    | '/ssr/nested'
+    | '/ssr/stream'
+  id:
+    | '__root__'
+    | '/'
+    | '/server-function/custom-error'
+    | '/server-function/nested'
+    | '/ssr/data-only'
+    | '/ssr/nested'
+    | '/ssr/stream'
+  fileRoutesById: FileRoutesById
+}
+export interface RootRouteChildren {
+  IndexRoute: typeof IndexRoute
+  ServerFunctionCustomErrorRoute: typeof ServerFunctionCustomErrorRoute
+  ServerFunctionNestedRoute: typeof ServerFunctionNestedRoute
+  SsrDataOnlyRoute: typeof SsrDataOnlyRoute
+  SsrNestedRoute: typeof SsrNestedRoute
+  SsrStreamRoute: typeof SsrStreamRoute
+}
+
+declare module '@tanstack/solid-router' {
+  interface FileRoutesByPath {
+    '/': {
+      id: '/'
+      path: '/'
+      fullPath: '/'
+      preLoaderRoute: typeof IndexRouteImport
+      parentRoute: typeof rootRouteImport
+    }
+    '/ssr/stream': {
+      id: '/ssr/stream'
+      path: '/ssr/stream'
+      fullPath: '/ssr/stream'
+      preLoaderRoute: typeof SsrStreamRouteImport
+      parentRoute: typeof rootRouteImport
+    }
+    '/ssr/nested': {
+      id: '/ssr/nested'
+      path: '/ssr/nested'
+      fullPath: '/ssr/nested'
+      preLoaderRoute: typeof SsrNestedRouteImport
+      parentRoute: typeof rootRouteImport
+    }
+    '/ssr/data-only': {
+      id: '/ssr/data-only'
+      path: '/ssr/data-only'
+      fullPath: '/ssr/data-only'
+      preLoaderRoute: typeof SsrDataOnlyRouteImport
+      parentRoute: typeof rootRouteImport
+    }
+    '/server-function/nested': {
+      id: '/server-function/nested'
+      path: '/server-function/nested'
+      fullPath: '/server-function/nested'
+      preLoaderRoute: typeof ServerFunctionNestedRouteImport
+      parentRoute: typeof rootRouteImport
+    }
+    '/server-function/custom-error': {
+      id: '/server-function/custom-error'
+      path: '/server-function/custom-error'
+      fullPath: '/server-function/custom-error'
+      preLoaderRoute: typeof ServerFunctionCustomErrorRouteImport
+      parentRoute: typeof rootRouteImport
+    }
+  }
+}
+
+const rootRouteChildren: RootRouteChildren = {
+  IndexRoute: IndexRoute,
+  ServerFunctionCustomErrorRoute: ServerFunctionCustomErrorRoute,
+  ServerFunctionNestedRoute: ServerFunctionNestedRoute,
+  SsrDataOnlyRoute: SsrDataOnlyRoute,
+  SsrNestedRoute: SsrNestedRoute,
+  SsrStreamRoute: SsrStreamRoute,
+}
+export const routeTree = rootRouteImport
+  ._addFileChildren(rootRouteChildren)
+  ._addFileTypes<FileRouteTypes>()
+
+import type { getRouter } from './router.tsx'
+import type { startInstance } from './start.tsx'
+declare module '@tanstack/solid-start' {
+  interface Register {
+    ssr: true
+    router: Awaited<ReturnType<typeof getRouter>>
+    config: Awaited<ReturnType<typeof startInstance.getOptions>>
+  }
+}
diff --git a/e2e/solid-start/serialization-adapters/src/router.tsx b/e2e/solid-start/serialization-adapters/src/router.tsx
new file mode 100644
index 0000000000..b8757ff85b
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/src/router.tsx
@@ -0,0 +1,11 @@
+import { createRouter } from '@tanstack/solid-router'
+import { routeTree } from './routeTree.gen'
+
+export function getRouter() {
+  const router = createRouter({
+    routeTree,
+    scrollRestoration: true,
+  })
+
+  return router
+}
diff --git a/e2e/solid-start/serialization-adapters/src/routes/__root.tsx b/e2e/solid-start/serialization-adapters/src/routes/__root.tsx
new file mode 100644
index 0000000000..5a4159ecb1
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/src/routes/__root.tsx
@@ -0,0 +1,71 @@
+/// <reference types="vite/client" />
+import {
+  ClientOnly,
+  HeadContent,
+  Link,
+  Scripts,
+  createRootRoute,
+  useRouterState,
+} from '@tanstack/solid-router'
+import { TanStackRouterDevtools } from '@tanstack/solid-router-devtools'
+import type {JSX} from 'solid-js';
+import appCss from '~/styles/app.css?url'
+
+export const Route = createRootRoute({
+  head: () => ({
+    meta: [
+      {
+        charSet: 'utf-8',
+      },
+      {
+        name: 'viewport',
+        content: 'width=device-width, initial-scale=1',
+      },
+      {
+        title: 'Serialization Adapters E2E Test',
+      },
+    ],
+    links: [{ rel: 'stylesheet', href: appCss }],
+  }),
+  shellComponent: RootDocument,
+})
+
+function RootDocument({ children }: { children: JSX.Element }) {
+  const { isLoading, status } = useRouterState({
+    select: (state) => ({ isLoading: state.isLoading, status: state.status }),
+  })()
+  return (
+    <html>
+      <head>
+        <HeadContent />
+      </head>
+      <body>
+        <div class="p-2 flex gap-2 text-lg">
+          <h1>Serialization Adapters E2E Test</h1>
+          <Link
+            to="/"
+            activeProps={{
+              class: 'font-bold',
+            }}
+          >
+            Home
+          </Link>
+        </div>
+        <hr />
+        <ClientOnly>
+          <div>
+            router isLoading:{' '}
+            <b data-testid="router-isLoading">{isLoading ? 'true' : 'false'}</b>
+          </div>
+          <div>
+            router status: <b data-testid="router-status">{status}</b>
+          </div>
+        </ClientOnly>
+        <hr />
+        {children}
+        <Scripts />
+        <TanStackRouterDevtools position="bottom-right" />
+      </body>
+    </html>
+  )
+}
diff --git a/e2e/solid-start/serialization-adapters/src/routes/index.tsx b/e2e/solid-start/serialization-adapters/src/routes/index.tsx
new file mode 100644
index 0000000000..25f5da0c75
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/src/routes/index.tsx
@@ -0,0 +1,56 @@
+import { Link, createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/')({
+  component: Home,
+})
+
+function Home() {
+  return (
+    <>
+      <div>
+        <h2>SSR</h2>
+        <Link
+          data-testid="ssr-data-only-link"
+          to="/ssr/data-only"
+          reloadDocument={true}
+        >
+          Data Only
+        </Link>
+        <br />
+        <Link
+          data-testid="ssr-stream-link"
+          to="/ssr/stream"
+          reloadDocument={true}
+        >
+          Stream
+        </Link>
+        <br />
+        <Link
+          data-testid="ssr-nested-link"
+          to="/ssr/nested"
+          reloadDocument={true}
+        >
+          Nested Classes
+        </Link>
+      </div>
+      <div>
+        <h2>Server Functions</h2>
+        <Link
+          data-testid="server-function-custom-error-link"
+          to="/server-function/custom-error"
+          reloadDocument={true}
+        >
+          Custom Error Serialization
+        </Link>
+        <br />
+        <Link
+          data-testid="server-functions-nested-link"
+          to="/server-function/nested"
+          reloadDocument={true}
+        >
+          Nested Classes returned from Server Function
+        </Link>
+      </div>
+    </>
+  )
+}
diff --git a/e2e/solid-start/serialization-adapters/src/routes/server-function/custom-error.tsx b/e2e/solid-start/serialization-adapters/src/routes/server-function/custom-error.tsx
new file mode 100644
index 0000000000..f33949e642
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/src/routes/server-function/custom-error.tsx
@@ -0,0 +1,69 @@
+import { createFileRoute } from '@tanstack/solid-router'
+import { createServerFn } from '@tanstack/solid-start'
+import { setResponseStatus } from '@tanstack/solid-start/server'
+import { createSignal } from 'solid-js'
+import { z } from 'zod'
+import { CustomError } from '~/CustomError'
+
+const schema = z.object({ hello: z.string() })
+const serverFnThrowing = createServerFn()
+  .inputValidator(schema)
+  .handler(async ({ data }) => {
+    if (data.hello === 'world') {
+      return 'Hello, world!'
+    }
+    setResponseStatus(499)
+    throw new CustomError('Invalid input', { foo: 'bar', bar: BigInt(123) })
+  })
+
+export const Route = createFileRoute('/server-function/custom-error')({
+  component: RouteComponent,
+})
+
+function RouteComponent() {
+  const [validResponse, setValidResponse] = createSignal<any>(null)
+  const [invalidResponse, setInvalidResponse] = createSignal<CustomError | null>(
+    null,
+  )
+
+  return (
+    <div>
+      <button
+        data-testid="server-function-valid-input"
+        onClick={() =>
+          serverFnThrowing({ data: { hello: 'world' } }).then(setValidResponse)
+        }
+      >
+        trigger valid input
+      </button>
+      <div data-testid="server-function-valid-response">
+        {JSON.stringify(validResponse)}
+      </div>
+
+      <br />
+      <button
+        data-testid="server-function-invalid-input"
+        onClick={() =>
+          serverFnThrowing({ data: { hello: 'error' } }).catch((err) => {
+            if (err instanceof CustomError) {
+              setInvalidResponse(err)
+            } else {
+              throw new Error('expected CustomError')
+            }
+          })
+        }
+      >
+        trigger invalid input
+      </button>
+      <div data-testid="server-function-invalid-response">
+        {invalidResponse()
+          ? JSON.stringify({
+              message: invalidResponse()?.message,
+              foo: invalidResponse()?.foo,
+              bar: invalidResponse()?.bar.toString(),
+            })
+          : JSON.stringify(validResponse)}
+      </div>
+    </div>
+  )
+}
diff --git a/e2e/solid-start/serialization-adapters/src/routes/server-function/nested.tsx b/e2e/solid-start/serialization-adapters/src/routes/server-function/nested.tsx
new file mode 100644
index 0000000000..96cdabea41
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/src/routes/server-function/nested.tsx
@@ -0,0 +1,34 @@
+import { createFileRoute } from '@tanstack/solid-router'
+import { createServerFn } from '@tanstack/solid-start'
+import { createSignal } from 'solid-js'
+import type { NestedOuter } from '~/data'
+import { RenderNestedData, makeNested } from '~/data'
+
+const serverFnReturningNested = createServerFn().handler(() => {
+  return makeNested()
+})
+
+export const Route = createFileRoute('/server-function/nested')({
+  component: RouteComponent,
+})
+
+function RouteComponent() {
+  const [nestedResponse, setNestedResponse] = createSignal<NestedOuter>()
+
+  return (
+    <div>
+      <button
+        data-testid="server-function-trigger"
+        onClick={() => serverFnReturningNested().then(setNestedResponse)}
+      >
+        trigger
+      </button>
+
+      {nestedResponse() ? (
+        <RenderNestedData nested={nestedResponse()!} />
+      ) : (
+        <div data-testid="waiting-for-response">waiting for response...</div>
+      )}
+    </div>
+  )
+}
diff --git a/e2e/solid-start/serialization-adapters/src/routes/ssr/data-only.tsx b/e2e/solid-start/serialization-adapters/src/routes/ssr/data-only.tsx
new file mode 100644
index 0000000000..0e07e55219
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/src/routes/ssr/data-only.tsx
@@ -0,0 +1,51 @@
+import { Outlet, createFileRoute } from '@tanstack/solid-router'
+import { RenderData, makeData } from '~/data'
+
+export const Route = createFileRoute('/ssr/data-only')({
+  ssr: 'data-only',
+  beforeLoad: () => {
+    return makeData()
+  },
+  loader: ({ context }) => {
+    return context
+  },
+  component: () => {
+    const context = Route.useRouteContext()
+    const loaderData = Route.useLoaderData()
+
+    const localData = makeData()
+    const expectedHonkState = localData.car.singleInstance.honk()
+
+    const honkState = loaderData().car.singleInstance.honk()
+
+    return (
+      <div data-testid="data-only-container">
+        <h2 data-testid="data-only-heading">data-only</h2>
+        <div>
+          context: <RenderData id="context" data={context()} />
+        </div>
+        <div>
+          loader: <RenderData id="loader" data={loaderData()} />
+        </div>
+        <div data-testid="honk-container">
+          <h3>honk</h3>
+          <div>
+            expected:{' '}
+            <div data-testid="honk-expected-state">
+              {JSON.stringify(expectedHonkState)}
+            </div>
+          </div>
+          <div>
+            actual:{' '}
+            <div data-testid="honk-actual-state">
+              {JSON.stringify(honkState)}
+            </div>
+          </div>
+        </div>
+        <hr />
+        <Outlet />
+      </div>
+    )
+  },
+  pendingComponent: () => <div>posts Loading...</div>,
+})
diff --git a/e2e/solid-start/serialization-adapters/src/routes/ssr/nested.tsx b/e2e/solid-start/serialization-adapters/src/routes/ssr/nested.tsx
new file mode 100644
index 0000000000..ccc4655ea9
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/src/routes/ssr/nested.tsx
@@ -0,0 +1,14 @@
+import { createFileRoute } from '@tanstack/solid-router'
+import { RenderNestedData, makeNested } from '~/data'
+
+export const Route = createFileRoute('/ssr/nested')({
+  beforeLoad: () => {
+    return { nested: makeNested() }
+  },
+  loader: ({ context }) => {
+    return context
+  },
+  component: () => {
+    return <RenderNestedData nested={Route.useLoaderData()().nested} />
+  },
+})
diff --git a/e2e/solid-start/serialization-adapters/src/routes/ssr/stream.tsx b/e2e/solid-start/serialization-adapters/src/routes/ssr/stream.tsx
new file mode 100644
index 0000000000..21e6eed173
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/src/routes/ssr/stream.tsx
@@ -0,0 +1,31 @@
+import { Await, createFileRoute } from '@tanstack/solid-router'
+import { Suspense } from 'solid-js'
+import { RenderData, makeData } from '~/data'
+
+export const Route = createFileRoute('/ssr/stream')({
+  loader: () => {
+    const dataPromise = new Promise<ReturnType<typeof makeData>>((r) =>
+      setTimeout(() => r(makeData()), 1000),
+    )
+    return {
+      someString: 'hello world',
+      dataPromise,
+    }
+  },
+  component: RouteComponent,
+})
+
+function RouteComponent() {
+  const loaderData = Route.useLoaderData()
+  return (
+    <div>
+      <h3 data-testid="stream-heading">Stream</h3>
+      <div data-testid="some-data">{loaderData().someString}</div>
+      <Suspense fallback={<div>Loading...</div>}>
+        <Await promise={loaderData().dataPromise}>
+          {(data) => <RenderData id="stream" data={data} />}
+        </Await>
+      </Suspense>
+    </div>
+  )
+}
diff --git a/e2e/solid-start/serialization-adapters/src/start.tsx b/e2e/solid-start/serialization-adapters/src/start.tsx
new file mode 100644
index 0000000000..a1701b2d43
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/src/start.tsx
@@ -0,0 +1,16 @@
+import { createStart } from '@tanstack/solid-start'
+import { carAdapter, fooAdapter, nestedOuterAdapter } from './data'
+import { customErrorAdapter } from './CustomError'
+
+export const startInstance = createStart(() => {
+  return {
+    defaultSsr: true,
+    serializationAdapters: [
+      fooAdapter,
+      carAdapter,
+      customErrorAdapter,
+      // only register nestedOuterAdapter here, nestedInnerAdapter is registered as an "extends" of nestedOuterAdapter
+      nestedOuterAdapter,
+    ],
+  }
+})
diff --git a/e2e/solid-start/serialization-adapters/src/styles/app.css b/e2e/solid-start/serialization-adapters/src/styles/app.css
new file mode 100644
index 0000000000..c53c870665
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/src/styles/app.css
@@ -0,0 +1,22 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+@layer base {
+  html {
+    color-scheme: light dark;
+  }
+
+  * {
+    @apply border-gray-200 dark:border-gray-800;
+  }
+
+  html,
+  body {
+    @apply text-gray-900 bg-gray-50 dark:bg-gray-950 dark:text-gray-200;
+  }
+
+  .using-mouse * {
+    outline: none !important;
+  }
+}
diff --git a/e2e/solid-start/serialization-adapters/tailwind.config.mjs b/e2e/solid-start/serialization-adapters/tailwind.config.mjs
new file mode 100644
index 0000000000..e49f4eb776
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/tailwind.config.mjs
@@ -0,0 +1,4 @@
+/** @type {import('tailwindcss').Config} */
+export default {
+  content: ['./src/**/*.{js,jsx,ts,tsx}'],
+}
diff --git a/e2e/solid-start/serialization-adapters/tests/app.spec.ts b/e2e/solid-start/serialization-adapters/tests/app.spec.ts
new file mode 100644
index 0000000000..292212a4d1
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/tests/app.spec.ts
@@ -0,0 +1,112 @@
+import { expect } from '@playwright/test'
+import { test } from '@tanstack/router-e2e-utils'
+import type { Page } from '@playwright/test'
+
+async function awaitPageLoaded(page: Page) {
+  // wait for page to be loaded by waiting for the ClientOnly component to be rendered
+
+  await expect(page.getByTestId('router-isLoading')).toContainText('false')
+  await expect(page.getByTestId('router-status')).toContainText('idle')
+}
+async function checkData(page: Page, id: string) {
+  const expectedData = await page
+    .getByTestId(`${id}-car-expected`)
+    .textContent()
+  expect(expectedData).not.toBeNull()
+  await expect(page.getByTestId(`${id}-car-actual`)).toContainText(
+    expectedData!,
+  )
+
+  await expect(page.getByTestId(`${id}-foo`)).toContainText(
+    '{"value":"server"}',
+  )
+}
+
+async function checkNestedData(page: Page) {
+  const expectedShout = await page
+    .getByTestId(`shout-expected-state`)
+    .textContent()
+  expect(expectedShout).not.toBeNull()
+  await expect(page.getByTestId(`shout-actual-state`)).toContainText(
+    expectedShout!,
+  )
+
+  const expectedWhisper = await page
+    .getByTestId(`whisper-expected-state`)
+    .textContent()
+  expect(expectedWhisper).not.toBeNull()
+  await expect(page.getByTestId(`whisper-actual-state`)).toContainText(
+    expectedWhisper!,
+  )
+}
+test.use({
+  whitelistErrors: [
+    /Failed to load resource: the server responded with a status of 499/,
+  ],
+})
+test.describe('SSR serialization adapters', () => {
+  test(`data-only`, async ({ page }) => {
+    await page.goto('/ssr/data-only')
+    await awaitPageLoaded(page)
+
+    await Promise.all(
+      ['context', 'loader'].map(async (id) => checkData(page, id)),
+    )
+
+    const expectedHonkData = await page
+      .getByTestId('honk-expected-state')
+      .textContent()
+    expect(expectedHonkData).not.toBeNull()
+    await expect(page.getByTestId('honk-actual-state')).toContainText(
+      expectedHonkData!,
+    )
+  })
+
+  test('stream', async ({ page }) => {
+    await page.goto('/ssr/stream')
+    await awaitPageLoaded(page)
+    await checkData(page, 'stream')
+  })
+
+  test('nested', async ({ page }) => {
+    await page.goto('/ssr/nested')
+    await awaitPageLoaded(page)
+
+    await checkNestedData(page)
+  })
+})
+
+test.describe('server functions serialization adapters', () => {
+  test('custom error', async ({ page }) => {
+    await page.goto('/server-function/custom-error')
+    await awaitPageLoaded(page)
+
+    await expect(
+      page.getByTestId('server-function-valid-response'),
+    ).toContainText('null')
+    await expect(
+      page.getByTestId('server-function-invalid-response'),
+    ).toContainText('null')
+
+    await page.getByTestId('server-function-valid-input').click()
+    await expect(
+      page.getByTestId('server-function-valid-response'),
+    ).toContainText('Hello, world!')
+
+    await page.getByTestId('server-function-invalid-input').click()
+    await expect(
+      page.getByTestId('server-function-invalid-response'),
+    ).toContainText('{"message":"Invalid input","foo":"bar","bar":"123"}')
+  })
+  test('nested', async ({ page }) => {
+    await page.goto('/server-function/nested')
+    await awaitPageLoaded(page)
+
+    await expect(page.getByTestId('waiting-for-response')).toContainText(
+      'waiting for response...',
+    )
+
+    await page.getByTestId('server-function-trigger').click()
+    await checkNestedData(page)
+  })
+})
diff --git a/e2e/solid-start/serialization-adapters/tsconfig.json b/e2e/solid-start/serialization-adapters/tsconfig.json
new file mode 100644
index 0000000000..a40235b863
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/tsconfig.json
@@ -0,0 +1,23 @@
+{
+  "include": ["**/*.ts", "**/*.tsx"],
+  "compilerOptions": {
+    "strict": true,
+    "esModuleInterop": true,
+    "jsx": "preserve",
+    "jsxImportSource": "solid-js",
+    "module": "ESNext",
+    "moduleResolution": "Bundler",
+    "lib": ["DOM", "DOM.Iterable", "ES2022"],
+    "isolatedModules": true,
+    "resolveJsonModule": true,
+    "skipLibCheck": true,
+    "target": "ES2022",
+    "allowJs": true,
+    "forceConsistentCasingInFileNames": true,
+    "baseUrl": ".",
+    "paths": {
+      "~/*": ["./src/*"]
+    },
+    "noEmit": true
+  }
+}
diff --git a/e2e/solid-start/serialization-adapters/vite.config.ts b/e2e/solid-start/serialization-adapters/vite.config.ts
new file mode 100644
index 0000000000..20ffdb3d6e
--- /dev/null
+++ b/e2e/solid-start/serialization-adapters/vite.config.ts
@@ -0,0 +1,17 @@
+import { defineConfig } from 'vite'
+import { tanstackStart } from '@tanstack/solid-start/plugin/vite'
+import tsConfigPaths from 'vite-tsconfig-paths'
+import viteSolid from 'vite-plugin-solid'
+
+export default defineConfig({
+  server: {
+    port: 3000,
+  },
+  plugins: [
+    tsConfigPaths({
+      projects: ['./tsconfig.json'],
+    }),
+    tanstackStart(),
+    viteSolid({ ssr: true }),
+  ],
+})
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 1ac510e332..5504a6aceb 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -3130,6 +3130,52 @@ importers:
         specifier: ^5.1.4
         version: 5.1.4(typescript@5.8.3)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
 
+  e2e/solid-start/serialization-adapters:
+    dependencies:
+      '@tanstack/solid-router':
+        specifier: workspace:^
+        version: link:../../../packages/solid-router
+      '@tanstack/solid-router-devtools':
+        specifier: workspace:^
+        version: link:../../../packages/solid-router-devtools
+      '@tanstack/solid-start':
+        specifier: workspace:*
+        version: link:../../../packages/solid-start
+      solid-js:
+        specifier: ^1.9.5
+        version: 1.9.5
+      vite:
+        specifier: ^7.1.7
+        version: 7.1.7(@types/node@22.10.2)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
+      vite-tsconfig-paths:
+        specifier: ^5.1.4
+        version: 5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+      zod:
+        specifier: ^3.24.2
+        version: 3.25.57
+    devDependencies:
+      '@tanstack/router-e2e-utils':
+        specifier: workspace:^
+        version: link:../../e2e-utils
+      '@types/node':
+        specifier: 22.10.2
+        version: 22.10.2
+      postcss:
+        specifier: ^8.5.1
+        version: 8.5.6
+      srvx:
+        specifier: ^0.8.6
+        version: 0.8.15
+      tailwindcss:
+        specifier: ^3.4.17
+        version: 3.4.17
+      typescript:
+        specifier: ^5.7.2
+        version: 5.9.2
+      vite-plugin-solid:
+        specifier: ^2.11.9
+        version: 2.11.9(@testing-library/jest-dom@6.6.3)(solid-js@1.9.5)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+
   e2e/solid-start/server-functions:
     dependencies:
       '@tanstack/solid-query':

From 6df6f56be3dc9f86dc2e2823026d2c1401767570 Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Tue, 21 Oct 2025 02:20:49 +0200
Subject: [PATCH 02/33] add hydration

---
 e2e/solid-start/serialization-adapters/src/routes/__root.tsx | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/e2e/solid-start/serialization-adapters/src/routes/__root.tsx b/e2e/solid-start/serialization-adapters/src/routes/__root.tsx
index 5a4159ecb1..032043675d 100644
--- a/e2e/solid-start/serialization-adapters/src/routes/__root.tsx
+++ b/e2e/solid-start/serialization-adapters/src/routes/__root.tsx
@@ -8,6 +8,7 @@ import {
   useRouterState,
 } from '@tanstack/solid-router'
 import { TanStackRouterDevtools } from '@tanstack/solid-router-devtools'
+import { HydrationScript } from 'solid-js/web';
 import type {JSX} from 'solid-js';
 import appCss from '~/styles/app.css?url'
 
@@ -37,9 +38,10 @@ function RootDocument({ children }: { children: JSX.Element }) {
   return (
     <html>
       <head>
-        <HeadContent />
+        <HydrationScript />
       </head>
       <body>
+        <HeadContent />
         <div class="p-2 flex gap-2 text-lg">
           <h1>Serialization Adapters E2E Test</h1>
           <Link

From 230b4ffee10c20a8a8d5078a7440b869216e3e7c Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Wed, 22 Oct 2025 16:19:37 +0200
Subject: [PATCH 03/33] fix lockfile

---
 pnpm-lock.yaml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 5504a6aceb..c31b169228 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -3146,10 +3146,10 @@ importers:
         version: 1.9.5
       vite:
         specifier: ^7.1.7
-        version: 7.1.7(@types/node@22.10.2)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
+        version: 7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
       vite-tsconfig-paths:
         specifier: ^5.1.4
-        version: 5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+        version: 5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       zod:
         specifier: ^3.24.2
         version: 3.25.57
@@ -3168,13 +3168,13 @@ importers:
         version: 0.8.15
       tailwindcss:
         specifier: ^3.4.17
-        version: 3.4.17
+        version: 3.4.18(tsx@4.20.3)(yaml@2.8.1)
       typescript:
         specifier: ^5.7.2
         version: 5.9.2
       vite-plugin-solid:
         specifier: ^2.11.9
-        version: 2.11.9(@testing-library/jest-dom@6.6.3)(solid-js@1.9.5)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.0)(lightningcss@1.30.1)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+        version: 2.11.10(@testing-library/jest-dom@6.6.3)(solid-js@1.9.5)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
 
   e2e/solid-start/server-functions:
     dependencies:

From 12ad4aa1daf5fa77247426f471e81e756421f882 Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Wed, 22 Oct 2025 17:56:52 +0200
Subject: [PATCH 04/33] add ssrLoadFrom initial

---
 packages/solid-router/src/awaited.tsx | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/packages/solid-router/src/awaited.tsx b/packages/solid-router/src/awaited.tsx
index 42ef0498b6..2cd4d9db84 100644
--- a/packages/solid-router/src/awaited.tsx
+++ b/packages/solid-router/src/awaited.tsx
@@ -30,7 +30,9 @@ export function Await<T>(
     children: (result: T) => SolidNode
   },
 ) {
-  const [resource] = Solid.createResource(() => props.promise)
+  const [resource] = Solid.createResource(() => props.promise, {
+    ssrLoadFrom: 'initial',
+  })
 
   return (
     <Solid.Show fallback={props.fallback} when={resource()}>

From 62807c4f1f1094d5c40473902215aad62f25f24d Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Wed, 22 Oct 2025 18:06:34 +0200
Subject: [PATCH 05/33] use initla only on server

---
 packages/solid-router/src/awaited.tsx | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/packages/solid-router/src/awaited.tsx b/packages/solid-router/src/awaited.tsx
index 2cd4d9db84..5119a4cf04 100644
--- a/packages/solid-router/src/awaited.tsx
+++ b/packages/solid-router/src/awaited.tsx
@@ -30,8 +30,10 @@ export function Await<T>(
     children: (result: T) => SolidNode
   },
 ) {
+  // Use ssrLoadFrom: 'initial' only on the client during hydration
+  // This ensures serialized data is used, but server promises still work
   const [resource] = Solid.createResource(() => props.promise, {
-    ssrLoadFrom: 'initial',
+    ssrLoadFrom: typeof document !== 'undefined' ? 'initial' : 'server',
   })
 
   return (

From 8143d15c0084f6ce36701c35831e3355e2c5902f Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Wed, 22 Oct 2025 18:09:38 +0200
Subject: [PATCH 06/33] check  on TSR_DEFERRED_PROMISE

---
 packages/solid-router/src/awaited.tsx | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/packages/solid-router/src/awaited.tsx b/packages/solid-router/src/awaited.tsx
index 5119a4cf04..9bc13ff6ba 100644
--- a/packages/solid-router/src/awaited.tsx
+++ b/packages/solid-router/src/awaited.tsx
@@ -30,10 +30,17 @@ export function Await<T>(
     children: (result: T) => SolidNode
   },
 ) {
-  // Use ssrLoadFrom: 'initial' only on the client during hydration
-  // This ensures serialized data is used, but server promises still work
+  // Check if this is a deferred promise from TanStack Router
+  const isDeferred = TSR_DEFERRED_PROMISE in (props.promise as any)
+
+  // Use ssrLoadFrom: 'initial' only for deferred promises that have already resolved
+  // This ensures serialized data is used during hydration, but streaming promises still work
+  const ssrLoadFrom = isDeferred && (props.promise as any)[TSR_DEFERRED_PROMISE].status !== 'pending'
+    ? 'initial'
+    : 'server'
+
   const [resource] = Solid.createResource(() => props.promise, {
-    ssrLoadFrom: typeof document !== 'undefined' ? 'initial' : 'server',
+    ssrLoadFrom: typeof document !== 'undefined' ? ssrLoadFrom : 'server',
   })
 
   return (

From a6d46550658a71fcb1bd793a35e01bb388cf6c12 Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Wed, 22 Oct 2025 18:12:11 +0200
Subject: [PATCH 07/33] more clear client/server split

---
 packages/solid-router/src/awaited.tsx | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/packages/solid-router/src/awaited.tsx b/packages/solid-router/src/awaited.tsx
index 9bc13ff6ba..3315dc126f 100644
--- a/packages/solid-router/src/awaited.tsx
+++ b/packages/solid-router/src/awaited.tsx
@@ -30,17 +30,20 @@ export function Await<T>(
     children: (result: T) => SolidNode
   },
 ) {
-  // Check if this is a deferred promise from TanStack Router
-  const isDeferred = TSR_DEFERRED_PROMISE in (props.promise as any)
-
-  // Use ssrLoadFrom: 'initial' only for deferred promises that have already resolved
+  // On the client, check if this is a deferred promise that has already resolved
+  // Use ssrLoadFrom: 'initial' only for resolved deferred promises
   // This ensures serialized data is used during hydration, but streaming promises still work
-  const ssrLoadFrom = isDeferred && (props.promise as any)[TSR_DEFERRED_PROMISE].status !== 'pending'
-    ? 'initial'
-    : 'server'
+  let ssrLoadFrom: 'initial' | 'server' = 'server'
+
+  if (typeof document !== 'undefined') {
+    const isDeferred = TSR_DEFERRED_PROMISE in (props.promise as any)
+    if (isDeferred && (props.promise as any)[TSR_DEFERRED_PROMISE].status !== 'pending') {
+      ssrLoadFrom = 'initial'
+    }
+  }
 
   const [resource] = Solid.createResource(() => props.promise, {
-    ssrLoadFrom: typeof document !== 'undefined' ? ssrLoadFrom : 'server',
+    ssrLoadFrom,
   })
 
   return (

From e9719e8a41c39a3da4c624629fa740987444e56d Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Wed, 22 Oct 2025 18:14:01 +0200
Subject: [PATCH 08/33] reset awaited

---
 packages/solid-router/src/awaited.tsx | 16 +---------------
 1 file changed, 1 insertion(+), 15 deletions(-)

diff --git a/packages/solid-router/src/awaited.tsx b/packages/solid-router/src/awaited.tsx
index 3315dc126f..42ef0498b6 100644
--- a/packages/solid-router/src/awaited.tsx
+++ b/packages/solid-router/src/awaited.tsx
@@ -30,21 +30,7 @@ export function Await<T>(
     children: (result: T) => SolidNode
   },
 ) {
-  // On the client, check if this is a deferred promise that has already resolved
-  // Use ssrLoadFrom: 'initial' only for resolved deferred promises
-  // This ensures serialized data is used during hydration, but streaming promises still work
-  let ssrLoadFrom: 'initial' | 'server' = 'server'
-
-  if (typeof document !== 'undefined') {
-    const isDeferred = TSR_DEFERRED_PROMISE in (props.promise as any)
-    if (isDeferred && (props.promise as any)[TSR_DEFERRED_PROMISE].status !== 'pending') {
-      ssrLoadFrom = 'initial'
-    }
-  }
-
-  const [resource] = Solid.createResource(() => props.promise, {
-    ssrLoadFrom,
-  })
+  const [resource] = Solid.createResource(() => props.promise)
 
   return (
     <Solid.Show fallback={props.fallback} when={resource()}>

From 291e2d4d66e16fabf8c64239a562be1ff59bc430 Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Wed, 22 Oct 2025 20:20:35 +0200
Subject: [PATCH 09/33] defer stream

---
 packages/solid-router/src/awaited.tsx | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/packages/solid-router/src/awaited.tsx b/packages/solid-router/src/awaited.tsx
index 42ef0498b6..dac91983a8 100644
--- a/packages/solid-router/src/awaited.tsx
+++ b/packages/solid-router/src/awaited.tsx
@@ -30,7 +30,13 @@ export function Await<T>(
     children: (result: T) => SolidNode
   },
 ) {
-  const [resource] = Solid.createResource(() => props.promise)
+  // Ensure the promise is wrapped with defer() to track its state
+  // This is idempotent - if already deferred, it returns the same promise
+  const deferredPromise = Solid.createMemo(() => defer(props.promise))
+
+  const [resource] = Solid.createResource(deferredPromise, {
+    deferStream: true,
+  })
 
   return (
     <Solid.Show fallback={props.fallback} when={resource()}>

From ec5dd8bdf0fe063a455170e182cd9fb305acab4e Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Wed, 22 Oct 2025 20:32:15 +0200
Subject: [PATCH 10/33] call signal

---
 .../src/routes/server-function/custom-error.tsx               | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/e2e/solid-start/serialization-adapters/src/routes/server-function/custom-error.tsx b/e2e/solid-start/serialization-adapters/src/routes/server-function/custom-error.tsx
index f33949e642..07fff5df76 100644
--- a/e2e/solid-start/serialization-adapters/src/routes/server-function/custom-error.tsx
+++ b/e2e/solid-start/serialization-adapters/src/routes/server-function/custom-error.tsx
@@ -37,7 +37,7 @@ function RouteComponent() {
         trigger valid input
       </button>
       <div data-testid="server-function-valid-response">
-        {JSON.stringify(validResponse)}
+        {JSON.stringify(validResponse())}
       </div>
 
       <br />
@@ -62,7 +62,7 @@ function RouteComponent() {
               foo: invalidResponse()?.foo,
               bar: invalidResponse()?.bar.toString(),
             })
-          : JSON.stringify(validResponse)}
+          : JSON.stringify(invalidResponse())}
       </div>
     </div>
   )

From 4050d97b1851dc97df7473b99bf46a4a34bfaa5e Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Wed, 22 Oct 2025 20:50:19 +0200
Subject: [PATCH 11/33] remove deferStream

---
 packages/solid-router/src/awaited.tsx | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/packages/solid-router/src/awaited.tsx b/packages/solid-router/src/awaited.tsx
index dac91983a8..efa0b13985 100644
--- a/packages/solid-router/src/awaited.tsx
+++ b/packages/solid-router/src/awaited.tsx
@@ -30,13 +30,11 @@ export function Await<T>(
     children: (result: T) => SolidNode
   },
 ) {
-  // Ensure the promise is wrapped with defer() to track its state
+  // Wrap the promise with defer() to ensure it's tracked properly
   // This is idempotent - if already deferred, it returns the same promise
   const deferredPromise = Solid.createMemo(() => defer(props.promise))
 
-  const [resource] = Solid.createResource(deferredPromise, {
-    deferStream: true,
-  })
+  const [resource] = Solid.createResource(deferredPromise)
 
   return (
     <Solid.Show fallback={props.fallback} when={resource()}>

From 860ab378e92bd5357279cf783f9bfeb25b159c63 Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Wed, 22 Oct 2025 20:59:42 +0200
Subject: [PATCH 12/33] Revert "remove deferStream"

This reverts commit 96dca8b27ac8bfb78258459e181747dbc1924e26.
---
 packages/solid-router/src/awaited.tsx | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/packages/solid-router/src/awaited.tsx b/packages/solid-router/src/awaited.tsx
index efa0b13985..dac91983a8 100644
--- a/packages/solid-router/src/awaited.tsx
+++ b/packages/solid-router/src/awaited.tsx
@@ -30,11 +30,13 @@ export function Await<T>(
     children: (result: T) => SolidNode
   },
 ) {
-  // Wrap the promise with defer() to ensure it's tracked properly
+  // Ensure the promise is wrapped with defer() to track its state
   // This is idempotent - if already deferred, it returns the same promise
   const deferredPromise = Solid.createMemo(() => defer(props.promise))
 
-  const [resource] = Solid.createResource(deferredPromise)
+  const [resource] = Solid.createResource(deferredPromise, {
+    deferStream: true,
+  })
 
   return (
     <Solid.Show fallback={props.fallback} when={resource()}>

From 9fc9745f9231e2d5935b80a11c9fca372f99df43 Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Wed, 22 Oct 2025 21:38:21 +0200
Subject: [PATCH 13/33] simpler awaited

---
 packages/solid-router/src/awaited.tsx | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/packages/solid-router/src/awaited.tsx b/packages/solid-router/src/awaited.tsx
index dac91983a8..892c67b19c 100644
--- a/packages/solid-router/src/awaited.tsx
+++ b/packages/solid-router/src/awaited.tsx
@@ -30,13 +30,14 @@ export function Await<T>(
     children: (result: T) => SolidNode
   },
 ) {
-  // Ensure the promise is wrapped with defer() to track its state
-  // This is idempotent - if already deferred, it returns the same promise
-  const deferredPromise = Solid.createMemo(() => defer(props.promise))
-
-  const [resource] = Solid.createResource(deferredPromise, {
-    deferStream: true,
-  })
+  const [resource] = Solid.createResource(
+    () => defer(props.promise),
+    // Simple passthrough - just return the promise for Solid to await
+    (p) => p,
+    {
+      deferStream: true,
+    },
+  )
 
   return (
     <Solid.Show fallback={props.fallback} when={resource()}>

From 333ed61f6745465fbf6b503282e9e8a92e99c506 Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Thu, 23 Oct 2025 00:15:21 +0200
Subject: [PATCH 14/33] use loweracse charset

---
 e2e/solid-start/serialization-adapters/src/routes/__root.tsx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/e2e/solid-start/serialization-adapters/src/routes/__root.tsx b/e2e/solid-start/serialization-adapters/src/routes/__root.tsx
index 032043675d..1beb580700 100644
--- a/e2e/solid-start/serialization-adapters/src/routes/__root.tsx
+++ b/e2e/solid-start/serialization-adapters/src/routes/__root.tsx
@@ -15,8 +15,8 @@ import appCss from '~/styles/app.css?url'
 export const Route = createRootRoute({
   head: () => ({
     meta: [
-      {
-        charSet: 'utf-8',
+    {
+        charset: 'utf-8',
       },
       {
         name: 'viewport',

From 706f2dee3a47079f2087311f9fdb5489a71de966 Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Thu, 23 Oct 2025 02:10:52 +0200
Subject: [PATCH 15/33] lockfile

---
 pnpm-lock.yaml | 62 +++++++++++++++++++-------------------------------
 1 file changed, 23 insertions(+), 39 deletions(-)

diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c31b169228..f15175528e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -3142,14 +3142,14 @@ importers:
         specifier: workspace:*
         version: link:../../../packages/solid-start
       solid-js:
-        specifier: ^1.9.5
-        version: 1.9.5
+        specifier: 1.9.9
+        version: 1.9.9
       vite:
         specifier: ^7.1.7
-        version: 7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
+        version: 7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
       vite-tsconfig-paths:
         specifier: ^5.1.4
-        version: 5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+        version: 5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       zod:
         specifier: ^3.24.2
         version: 3.25.57
@@ -3174,7 +3174,7 @@ importers:
         version: 5.9.2
       vite-plugin-solid:
         specifier: ^2.11.9
-        version: 2.11.10(@testing-library/jest-dom@6.6.3)(solid-js@1.9.5)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+        version: 2.11.10(@testing-library/jest-dom@6.6.3)(solid-js@1.9.9)(vite@7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
 
   e2e/solid-start/server-functions:
     dependencies:
@@ -4867,7 +4867,7 @@ importers:
         version: 19.0.3(@types/react@19.0.8)
       '@vitejs/plugin-react':
         specifier: ^4.3.4
-        version: 4.3.4(vite@7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+        version: 4.3.4(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       autoprefixer:
         specifier: ^10.4.20
         version: 10.4.20(postcss@8.5.3)
@@ -4882,10 +4882,10 @@ importers:
         version: 5.8.2
       vite:
         specifier: ^7.1.7
-        version: 7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
+        version: 7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
       vite-plugin-dts:
         specifier: 4.0.3
-        version: 4.0.3(@types/node@22.10.2)(rollup@4.52.5)(typescript@5.8.2)(vite@7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+        version: 4.0.3(@types/node@22.10.2)(rollup@4.52.5)(typescript@5.8.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
 
   examples/react/router-monorepo-react-query/packages/post-feature:
     dependencies:
@@ -24063,17 +24063,6 @@ snapshots:
       - rollup
       - supports-color
 
-  '@vitejs/plugin-react@4.3.4(vite@7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))':
-    dependencies:
-      '@babel/core': 7.27.4
-      '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.27.4)
-      '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.27.4)
-      '@types/babel__core': 7.20.5
-      react-refresh: 0.14.2
-      vite: 7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
-    transitivePeerDependencies:
-      - supports-color
-
   '@vitejs/plugin-react@4.3.4(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))':
     dependencies:
       '@babel/core': 7.27.4
@@ -30001,26 +29990,6 @@ snapshots:
       - tsx
       - yaml
 
-  vite-plugin-dts@4.0.3(@types/node@22.10.2)(rollup@4.52.5)(typescript@5.8.2)(vite@7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)):
-    dependencies:
-      '@microsoft/api-extractor': 7.47.4(@types/node@22.10.2)
-      '@rollup/pluginutils': 5.1.4(rollup@4.52.5)
-      '@volar/typescript': 2.4.11
-      '@vue/language-core': 2.0.29(typescript@5.8.2)
-      compare-versions: 6.1.1
-      debug: 4.4.3
-      kolorist: 1.8.0
-      local-pkg: 0.5.1
-      magic-string: 0.30.19
-      typescript: 5.8.2
-      vue-tsc: 2.0.29(typescript@5.8.2)
-    optionalDependencies:
-      vite: 7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
-    transitivePeerDependencies:
-      - '@types/node'
-      - rollup
-      - supports-color
-
   vite-plugin-dts@4.0.3(@types/node@22.10.2)(rollup@4.52.5)(typescript@5.8.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)):
     dependencies:
       '@microsoft/api-extractor': 7.47.4(@types/node@22.10.2)
@@ -30102,6 +30071,17 @@ snapshots:
       - supports-color
       - typescript
 
+  vite-tsconfig-paths@5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)):
+    dependencies:
+      debug: 4.4.0
+      globrex: 0.1.2
+      tsconfck: 3.1.4(typescript@5.9.2)
+    optionalDependencies:
+      vite: 7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
+    transitivePeerDependencies:
+      - supports-color
+      - typescript
+
   vite-tsconfig-paths@5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)):
     dependencies:
       debug: 4.4.0
@@ -30147,6 +30127,10 @@ snapshots:
       tsx: 4.20.3
       yaml: 2.8.1
 
+  vitefu@1.1.1(vite@7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)):
+    optionalDependencies:
+      vite: 7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
+
   vitefu@1.1.1(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)):
     optionalDependencies:
       vite: 7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)

From 44f513b11855eee9117041095ae777b7dc888fe1 Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Thu, 23 Oct 2025 02:12:31 +0200
Subject: [PATCH 16/33] update to 1.9.9

---
 e2e/solid-start/serialization-adapters/package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/e2e/solid-start/serialization-adapters/package.json b/e2e/solid-start/serialization-adapters/package.json
index 26cda2301a..fbd4be4fe7 100644
--- a/e2e/solid-start/serialization-adapters/package.json
+++ b/e2e/solid-start/serialization-adapters/package.json
@@ -14,7 +14,7 @@
     "@tanstack/solid-router": "workspace:^",
     "@tanstack/solid-router-devtools": "workspace:^",
     "@tanstack/solid-start": "workspace:^",
-    "solid-js": "^1.9.5",
+    "solid-js": "^1.9.9",
     "vite": "^7.1.7",
     "vite-tsconfig-paths": "^5.1.4",
     "zod": "^3.24.2"

From 349dedbef6d35a93be34c45038f52e740b703f4f Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Thu, 23 Oct 2025 02:13:55 +0200
Subject: [PATCH 17/33] install

---
 pnpm-lock.yaml | 24 ++++++------------------
 1 file changed, 6 insertions(+), 18 deletions(-)

diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f15175528e..4bd97fccd2 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -15814,14 +15814,6 @@ packages:
     resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==}
     hasBin: true
 
-  jiti@2.4.2:
-    resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
-    hasBin: true
-
-  jiti@2.6.0:
-    resolution: {integrity: sha512-VXe6RjJkBPj0ohtqaO8vSWP3ZhAKo66fKrFNCll4BTcwljPLz03pCbaNKfzGP5MbrCYcbJ7v0nOYYwUzTEIdXQ==}
-    hasBin: true
-
   jiti@2.6.1:
     resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
     hasBin: true
@@ -23112,7 +23104,7 @@ snapshots:
     dependencies:
       '@jridgewell/remapping': 2.3.5
       enhanced-resolve: 5.18.3
-      jiti: 2.6.0
+      jiti: 2.6.1
       lightningcss: 1.30.1
       magic-string: 0.30.19
       source-map-js: 1.2.1
@@ -23132,7 +23124,7 @@ snapshots:
     dependencies:
       '@ampproject/remapping': 2.3.0
       enhanced-resolve: 5.18.1
-      jiti: 2.4.2
+      jiti: 2.6.1
       lightningcss: 1.29.2
       magic-string: 0.30.17
       source-map-js: 1.2.1
@@ -24852,7 +24844,7 @@ snapshots:
       dotenv: 17.2.2
       exsolve: 1.0.7
       giget: 2.0.0
-      jiti: 2.6.0
+      jiti: 2.6.1
       ohash: 2.0.11
       pathe: 2.0.3
       perfect-debounce: 2.0.0
@@ -26999,10 +26991,6 @@ snapshots:
 
   jiti@1.21.7: {}
 
-  jiti@2.4.2: {}
-
-  jiti@2.6.0: {}
-
   jiti@2.6.1: {}
 
   jju@1.4.0: {}
@@ -27365,7 +27353,7 @@ snapshots:
       get-port-please: 3.2.0
       h3: 1.15.4
       http-shutdown: 1.2.2
-      jiti: 2.6.0
+      jiti: 2.6.1
       mlly: 1.8.0
       node-forge: 1.3.1
       pathe: 1.1.2
@@ -27850,7 +27838,7 @@ snapshots:
       hookable: 5.5.3
       httpxy: 0.1.7
       ioredis: 5.8.0
-      jiti: 2.6.0
+      jiti: 2.6.1
       klona: 2.0.6
       knitwork: 1.2.0
       listhen: 1.9.0
@@ -29875,7 +29863,7 @@ snapshots:
     dependencies:
       citty: 0.1.6
       defu: 6.1.4
-      jiti: 2.6.0
+      jiti: 2.6.1
       knitwork: 1.2.0
       scule: 1.3.0
 

From 61be233209a3b20675df113e5a6533891edd0fe2 Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Thu, 23 Oct 2025 02:22:21 +0200
Subject: [PATCH 18/33] bump tailwind to v4

---
 .../serialization-adapters/package.json       |  7 +-
 .../serialization-adapters/postcss.config.mjs |  3 +-
 .../src/routes/index.tsx                      | 55 +-------------
 .../src/routes/ssr/nested.tsx                 | 15 ++--
 .../src/routes/ssr/stream.tsx                 | 26 +------
 .../serialization-adapters/src/styles/app.css | 22 +++++-
 .../tailwind.config.mjs                       |  4 -
 pnpm-lock.yaml                                | 75 ++++++++++++-------
 8 files changed, 82 insertions(+), 125 deletions(-)
 delete mode 100644 e2e/solid-start/serialization-adapters/tailwind.config.mjs

diff --git a/e2e/solid-start/serialization-adapters/package.json b/e2e/solid-start/serialization-adapters/package.json
index fbd4be4fe7..6b53df71cb 100644
--- a/e2e/solid-start/serialization-adapters/package.json
+++ b/e2e/solid-start/serialization-adapters/package.json
@@ -20,12 +20,13 @@
     "zod": "^3.24.2"
   },
   "devDependencies": {
+    "@tailwindcss/postcss": "^4.1.15",
     "@tanstack/router-e2e-utils": "workspace:^",
-    "vite-plugin-solid": "^2.11.9",
     "@types/node": "^22.10.2",
     "postcss": "^8.5.1",
     "srvx": "^0.8.6",
-    "tailwindcss": "^3.4.17",
-    "typescript": "^5.7.2"
+    "tailwindcss": "^4.1.15",
+    "typescript": "^5.7.2",
+    "vite-plugin-solid": "^2.11.9"
   }
 }
diff --git a/e2e/solid-start/serialization-adapters/postcss.config.mjs b/e2e/solid-start/serialization-adapters/postcss.config.mjs
index 2e7af2b7f1..a7f73a2d1d 100644
--- a/e2e/solid-start/serialization-adapters/postcss.config.mjs
+++ b/e2e/solid-start/serialization-adapters/postcss.config.mjs
@@ -1,6 +1,5 @@
 export default {
   plugins: {
-    tailwindcss: {},
-    autoprefixer: {},
+    '@tailwindcss/postcss': {},
   },
 }
diff --git a/e2e/solid-start/serialization-adapters/src/routes/index.tsx b/e2e/solid-start/serialization-adapters/src/routes/index.tsx
index 25f5da0c75..da62dac950 100644
--- a/e2e/solid-start/serialization-adapters/src/routes/index.tsx
+++ b/e2e/solid-start/serialization-adapters/src/routes/index.tsx
@@ -1,56 +1,9 @@
-import { Link, createFileRoute } from '@tanstack/solid-router'
+import { createFileRoute } from '@tanstack/solid-router'
 
 export const Route = createFileRoute('/')({
-  component: Home,
+  component: RouteComponent,
 })
 
-function Home() {
-  return (
-    <>
-      <div>
-        <h2>SSR</h2>
-        <Link
-          data-testid="ssr-data-only-link"
-          to="/ssr/data-only"
-          reloadDocument={true}
-        >
-          Data Only
-        </Link>
-        <br />
-        <Link
-          data-testid="ssr-stream-link"
-          to="/ssr/stream"
-          reloadDocument={true}
-        >
-          Stream
-        </Link>
-        <br />
-        <Link
-          data-testid="ssr-nested-link"
-          to="/ssr/nested"
-          reloadDocument={true}
-        >
-          Nested Classes
-        </Link>
-      </div>
-      <div>
-        <h2>Server Functions</h2>
-        <Link
-          data-testid="server-function-custom-error-link"
-          to="/server-function/custom-error"
-          reloadDocument={true}
-        >
-          Custom Error Serialization
-        </Link>
-        <br />
-        <Link
-          data-testid="server-functions-nested-link"
-          to="/server-function/nested"
-          reloadDocument={true}
-        >
-          Nested Classes returned from Server Function
-        </Link>
-      </div>
-    </>
-  )
+function RouteComponent() {
+  return <div>Hello "/"!</div>
 }
diff --git a/e2e/solid-start/serialization-adapters/src/routes/ssr/nested.tsx b/e2e/solid-start/serialization-adapters/src/routes/ssr/nested.tsx
index ccc4655ea9..46807400fa 100644
--- a/e2e/solid-start/serialization-adapters/src/routes/ssr/nested.tsx
+++ b/e2e/solid-start/serialization-adapters/src/routes/ssr/nested.tsx
@@ -1,14 +1,9 @@
 import { createFileRoute } from '@tanstack/solid-router'
-import { RenderNestedData, makeNested } from '~/data'
 
 export const Route = createFileRoute('/ssr/nested')({
-  beforeLoad: () => {
-    return { nested: makeNested() }
-  },
-  loader: ({ context }) => {
-    return context
-  },
-  component: () => {
-    return <RenderNestedData nested={Route.useLoaderData()().nested} />
-  },
+  component: RouteComponent,
 })
+
+function RouteComponent() {
+  return <div>Hello "/ssr/nested"!</div>
+}
diff --git a/e2e/solid-start/serialization-adapters/src/routes/ssr/stream.tsx b/e2e/solid-start/serialization-adapters/src/routes/ssr/stream.tsx
index 21e6eed173..b38570f4ff 100644
--- a/e2e/solid-start/serialization-adapters/src/routes/ssr/stream.tsx
+++ b/e2e/solid-start/serialization-adapters/src/routes/ssr/stream.tsx
@@ -1,31 +1,9 @@
-import { Await, createFileRoute } from '@tanstack/solid-router'
-import { Suspense } from 'solid-js'
-import { RenderData, makeData } from '~/data'
+import { createFileRoute } from '@tanstack/solid-router'
 
 export const Route = createFileRoute('/ssr/stream')({
-  loader: () => {
-    const dataPromise = new Promise<ReturnType<typeof makeData>>((r) =>
-      setTimeout(() => r(makeData()), 1000),
-    )
-    return {
-      someString: 'hello world',
-      dataPromise,
-    }
-  },
   component: RouteComponent,
 })
 
 function RouteComponent() {
-  const loaderData = Route.useLoaderData()
-  return (
-    <div>
-      <h3 data-testid="stream-heading">Stream</h3>
-      <div data-testid="some-data">{loaderData().someString}</div>
-      <Suspense fallback={<div>Loading...</div>}>
-        <Await promise={loaderData().dataPromise}>
-          {(data) => <RenderData id="stream" data={data} />}
-        </Await>
-      </Suspense>
-    </div>
-  )
+  return <div>Hello "/ssr/stream"!</div>
 }
diff --git a/e2e/solid-start/serialization-adapters/src/styles/app.css b/e2e/solid-start/serialization-adapters/src/styles/app.css
index c53c870665..fbb4ba08a5 100644
--- a/e2e/solid-start/serialization-adapters/src/styles/app.css
+++ b/e2e/solid-start/serialization-adapters/src/styles/app.css
@@ -1,6 +1,22 @@
-@tailwind base;
-@tailwind components;
-@tailwind utilities;
+@import 'tailwindcss';
+
+/*
+  The default border color has changed to `currentcolor` in Tailwind CSS v4,
+  so we've added these compatibility styles to make sure everything still
+  looks the same as it did with Tailwind CSS v3.
+
+  If we ever want to remove these styles, we need to add an explicit border
+  color utility to any element that depends on these defaults.
+*/
+@layer base {
+  *,
+  ::after,
+  ::before,
+  ::backdrop,
+  ::file-selector-button {
+    border-color: var(--color-gray-200, currentcolor);
+  }
+}
 
 @layer base {
   html {
diff --git a/e2e/solid-start/serialization-adapters/tailwind.config.mjs b/e2e/solid-start/serialization-adapters/tailwind.config.mjs
deleted file mode 100644
index e49f4eb776..0000000000
--- a/e2e/solid-start/serialization-adapters/tailwind.config.mjs
+++ /dev/null
@@ -1,4 +0,0 @@
-/** @type {import('tailwindcss').Config} */
-export default {
-  content: ['./src/**/*.{js,jsx,ts,tsx}'],
-}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 4bd97fccd2..1d41020e42 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -3146,14 +3146,17 @@ importers:
         version: 1.9.9
       vite:
         specifier: ^7.1.7
-        version: 7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
+        version: 7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
       vite-tsconfig-paths:
         specifier: ^5.1.4
-        version: 5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+        version: 5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       zod:
         specifier: ^3.24.2
         version: 3.25.57
     devDependencies:
+      '@tailwindcss/postcss':
+        specifier: ^4.1.15
+        version: 4.1.15
       '@tanstack/router-e2e-utils':
         specifier: workspace:^
         version: link:../../e2e-utils
@@ -3167,14 +3170,14 @@ importers:
         specifier: ^0.8.6
         version: 0.8.15
       tailwindcss:
-        specifier: ^3.4.17
-        version: 3.4.18(tsx@4.20.3)(yaml@2.8.1)
+        specifier: ^4.1.15
+        version: 4.1.15
       typescript:
         specifier: ^5.7.2
         version: 5.9.2
       vite-plugin-solid:
         specifier: ^2.11.9
-        version: 2.11.10(@testing-library/jest-dom@6.6.3)(solid-js@1.9.9)(vite@7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+        version: 2.11.10(@testing-library/jest-dom@6.6.3)(solid-js@1.9.9)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
 
   e2e/solid-start/server-functions:
     dependencies:
@@ -4867,7 +4870,7 @@ importers:
         version: 19.0.3(@types/react@19.0.8)
       '@vitejs/plugin-react':
         specifier: ^4.3.4
-        version: 4.3.4(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+        version: 4.3.4(vite@7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       autoprefixer:
         specifier: ^10.4.20
         version: 10.4.20(postcss@8.5.3)
@@ -4882,10 +4885,10 @@ importers:
         version: 5.8.2
       vite:
         specifier: ^7.1.7
-        version: 7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
+        version: 7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
       vite-plugin-dts:
         specifier: 4.0.3
-        version: 4.0.3(@types/node@22.10.2)(rollup@4.52.5)(typescript@5.8.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+        version: 4.0.3(@types/node@22.10.2)(rollup@4.52.5)(typescript@5.8.2)(vite@7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
 
   examples/react/router-monorepo-react-query/packages/post-feature:
     dependencies:
@@ -5844,7 +5847,7 @@ importers:
         version: 7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
       vitest:
         specifier: ^3.2.4
-        version: 3.2.4(@types/node@22.10.2)(@vitest/browser@3.0.6)(@vitest/ui@3.0.6)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.7.0(@types/node@22.10.2)(typescript@5.9.2))(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
+        version: 3.2.4(@types/node@22.10.2)(@vitest/browser@3.0.6(@types/node@22.10.2)(playwright@1.52.0)(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))(vitest@3.2.4))(@vitest/ui@3.0.6(vitest@3.2.4))(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.7.0(@types/node@22.10.2)(typescript@5.9.2))(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
       web-vitals:
         specifier: ^5.1.0
         version: 5.1.0
@@ -24055,6 +24058,17 @@ snapshots:
       - rollup
       - supports-color
 
+  '@vitejs/plugin-react@4.3.4(vite@7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))':
+    dependencies:
+      '@babel/core': 7.27.4
+      '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.27.4)
+      '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.27.4)
+      '@types/babel__core': 7.20.5
+      react-refresh: 0.14.2
+      vite: 7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
+    transitivePeerDependencies:
+      - supports-color
+
   '@vitejs/plugin-react@4.3.4(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))':
     dependencies:
       '@babel/core': 7.27.4
@@ -29978,6 +29992,26 @@ snapshots:
       - tsx
       - yaml
 
+  vite-plugin-dts@4.0.3(@types/node@22.10.2)(rollup@4.52.5)(typescript@5.8.2)(vite@7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)):
+    dependencies:
+      '@microsoft/api-extractor': 7.47.4(@types/node@22.10.2)
+      '@rollup/pluginutils': 5.1.4(rollup@4.52.5)
+      '@volar/typescript': 2.4.11
+      '@vue/language-core': 2.0.29(typescript@5.8.2)
+      compare-versions: 6.1.1
+      debug: 4.4.3
+      kolorist: 1.8.0
+      local-pkg: 0.5.1
+      magic-string: 0.30.19
+      typescript: 5.8.2
+      vue-tsc: 2.0.29(typescript@5.8.2)
+    optionalDependencies:
+      vite: 7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
+    transitivePeerDependencies:
+      - '@types/node'
+      - rollup
+      - supports-color
+
   vite-plugin-dts@4.0.3(@types/node@22.10.2)(rollup@4.52.5)(typescript@5.8.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)):
     dependencies:
       '@microsoft/api-extractor': 7.47.4(@types/node@22.10.2)
@@ -30059,17 +30093,6 @@ snapshots:
       - supports-color
       - typescript
 
-  vite-tsconfig-paths@5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)):
-    dependencies:
-      debug: 4.4.0
-      globrex: 0.1.2
-      tsconfck: 3.1.4(typescript@5.9.2)
-    optionalDependencies:
-      vite: 7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
-    transitivePeerDependencies:
-      - supports-color
-      - typescript
-
   vite-tsconfig-paths@5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)):
     dependencies:
       debug: 4.4.0
@@ -30115,15 +30138,11 @@ snapshots:
       tsx: 4.20.3
       yaml: 2.8.1
 
-  vitefu@1.1.1(vite@7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)):
-    optionalDependencies:
-      vite: 7.1.7(@types/node@22.10.2)(jiti@1.21.7)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
-
   vitefu@1.1.1(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)):
     optionalDependencies:
       vite: 7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
 
-  vitest@3.2.4(@types/node@22.10.2)(@vitest/browser@3.0.6)(@vitest/ui@3.0.6)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.30.2)(msw@2.7.0(@types/node@22.10.2)(typescript@5.9.2))(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1):
+  vitest@3.2.4(@types/node@22.10.2)(@vitest/browser@3.0.6(@types/node@22.10.2)(playwright@1.52.0)(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))(vitest@3.2.4))(@vitest/ui@3.0.6(vitest@3.2.4))(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.7.0(@types/node@22.10.2)(typescript@5.9.2))(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1):
     dependencies:
       '@types/chai': 5.2.2
       '@vitest/expect': 3.2.4
@@ -30152,7 +30171,7 @@ snapshots:
       '@types/node': 22.10.2
       '@vitest/browser': 3.0.6(@types/node@22.10.2)(playwright@1.52.0)(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))(vitest@3.2.4)
       '@vitest/ui': 3.0.6(vitest@3.2.4)
-      jsdom: 25.0.1
+      jsdom: 27.0.0(postcss@8.5.6)
     transitivePeerDependencies:
       - jiti
       - less
@@ -30167,7 +30186,7 @@ snapshots:
       - tsx
       - yaml
 
-  vitest@3.2.4(@types/node@22.10.2)(@vitest/browser@3.0.6)(@vitest/ui@3.0.6)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.7.0(@types/node@22.10.2)(typescript@5.9.2))(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1):
+  vitest@3.2.4(@types/node@22.10.2)(@vitest/browser@3.0.6)(@vitest/ui@3.0.6)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.30.2)(msw@2.7.0(@types/node@22.10.2)(typescript@5.9.2))(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1):
     dependencies:
       '@types/chai': 5.2.2
       '@vitest/expect': 3.2.4
@@ -30196,7 +30215,7 @@ snapshots:
       '@types/node': 22.10.2
       '@vitest/browser': 3.0.6(@types/node@22.10.2)(playwright@1.52.0)(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))(vitest@3.2.4)
       '@vitest/ui': 3.0.6(vitest@3.2.4)
-      jsdom: 27.0.0(postcss@8.5.6)
+      jsdom: 25.0.1
     transitivePeerDependencies:
       - jiti
       - less

From 1835e5914844af9d42388e54c8d7c5eb13a7a493 Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Thu, 23 Oct 2025 02:27:42 +0200
Subject: [PATCH 19/33] reset awaited

---
 packages/solid-router/src/awaited.tsx | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/packages/solid-router/src/awaited.tsx b/packages/solid-router/src/awaited.tsx
index 892c67b19c..42ef0498b6 100644
--- a/packages/solid-router/src/awaited.tsx
+++ b/packages/solid-router/src/awaited.tsx
@@ -30,14 +30,7 @@ export function Await<T>(
     children: (result: T) => SolidNode
   },
 ) {
-  const [resource] = Solid.createResource(
-    () => defer(props.promise),
-    // Simple passthrough - just return the promise for Solid to await
-    (p) => p,
-    {
-      deferStream: true,
-    },
-  )
+  const [resource] = Solid.createResource(() => props.promise)
 
   return (
     <Solid.Show fallback={props.fallback} when={resource()}>

From a954cccc87a6b13519b1dac38cd60891f4959c7a Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Thu, 23 Oct 2025 02:32:47 +0200
Subject: [PATCH 20/33] add routes

---
 .../src/routes/ssr/nested.tsx                 | 16 ++++++++----
 .../src/routes/ssr/stream.tsx                 | 26 +++++++++++++++++--
 2 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/e2e/solid-start/serialization-adapters/src/routes/ssr/nested.tsx b/e2e/solid-start/serialization-adapters/src/routes/ssr/nested.tsx
index 46807400fa..026f9c52d1 100644
--- a/e2e/solid-start/serialization-adapters/src/routes/ssr/nested.tsx
+++ b/e2e/solid-start/serialization-adapters/src/routes/ssr/nested.tsx
@@ -1,9 +1,15 @@
 import { createFileRoute } from '@tanstack/solid-router'
+import { RenderNestedData, makeNested } from '~/data'
 
 export const Route = createFileRoute('/ssr/nested')({
-  component: RouteComponent,
+  beforeLoad: () => {
+    return { nested: makeNested() }
+  },
+  loader: ({ context }) => {
+    return context
+  },
+  component: () => {
+    const loaderData = Route.useLoaderData()
+    return <RenderNestedData nested={loaderData().nested} />
+  },
 })
-
-function RouteComponent() {
-  return <div>Hello "/ssr/nested"!</div>
-}
diff --git a/e2e/solid-start/serialization-adapters/src/routes/ssr/stream.tsx b/e2e/solid-start/serialization-adapters/src/routes/ssr/stream.tsx
index b38570f4ff..21e6eed173 100644
--- a/e2e/solid-start/serialization-adapters/src/routes/ssr/stream.tsx
+++ b/e2e/solid-start/serialization-adapters/src/routes/ssr/stream.tsx
@@ -1,9 +1,31 @@
-import { createFileRoute } from '@tanstack/solid-router'
+import { Await, createFileRoute } from '@tanstack/solid-router'
+import { Suspense } from 'solid-js'
+import { RenderData, makeData } from '~/data'
 
 export const Route = createFileRoute('/ssr/stream')({
+  loader: () => {
+    const dataPromise = new Promise<ReturnType<typeof makeData>>((r) =>
+      setTimeout(() => r(makeData()), 1000),
+    )
+    return {
+      someString: 'hello world',
+      dataPromise,
+    }
+  },
   component: RouteComponent,
 })
 
 function RouteComponent() {
-  return <div>Hello "/ssr/stream"!</div>
+  const loaderData = Route.useLoaderData()
+  return (
+    <div>
+      <h3 data-testid="stream-heading">Stream</h3>
+      <div data-testid="some-data">{loaderData().someString}</div>
+      <Suspense fallback={<div>Loading...</div>}>
+        <Await promise={loaderData().dataPromise}>
+          {(data) => <RenderData id="stream" data={data} />}
+        </Await>
+      </Suspense>
+    </div>
+  )
 }

From 77310bb9c5fdf33b5c4bd22117bf22ccd758446f Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Thu, 23 Oct 2025 02:34:46 +0200
Subject: [PATCH 21/33] add back index

---
 .../src/routes/index.tsx                      | 55 +++++++++++++++++--
 1 file changed, 51 insertions(+), 4 deletions(-)

diff --git a/e2e/solid-start/serialization-adapters/src/routes/index.tsx b/e2e/solid-start/serialization-adapters/src/routes/index.tsx
index da62dac950..25f5da0c75 100644
--- a/e2e/solid-start/serialization-adapters/src/routes/index.tsx
+++ b/e2e/solid-start/serialization-adapters/src/routes/index.tsx
@@ -1,9 +1,56 @@
-import { createFileRoute } from '@tanstack/solid-router'
+import { Link, createFileRoute } from '@tanstack/solid-router'
 
 export const Route = createFileRoute('/')({
-  component: RouteComponent,
+  component: Home,
 })
 
-function RouteComponent() {
-  return <div>Hello "/"!</div>
+function Home() {
+  return (
+    <>
+      <div>
+        <h2>SSR</h2>
+        <Link
+          data-testid="ssr-data-only-link"
+          to="/ssr/data-only"
+          reloadDocument={true}
+        >
+          Data Only
+        </Link>
+        <br />
+        <Link
+          data-testid="ssr-stream-link"
+          to="/ssr/stream"
+          reloadDocument={true}
+        >
+          Stream
+        </Link>
+        <br />
+        <Link
+          data-testid="ssr-nested-link"
+          to="/ssr/nested"
+          reloadDocument={true}
+        >
+          Nested Classes
+        </Link>
+      </div>
+      <div>
+        <h2>Server Functions</h2>
+        <Link
+          data-testid="server-function-custom-error-link"
+          to="/server-function/custom-error"
+          reloadDocument={true}
+        >
+          Custom Error Serialization
+        </Link>
+        <br />
+        <Link
+          data-testid="server-functions-nested-link"
+          to="/server-function/nested"
+          reloadDocument={true}
+        >
+          Nested Classes returned from Server Function
+        </Link>
+      </div>
+    </>
+  )
 }

From ec14ecb187da6620de468b2fa7792c9c7d30d5b8 Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Thu, 23 Oct 2025 02:36:22 +0200
Subject: [PATCH 22/33] Revert "reset awaited"

This reverts commit fbfe5f6080e55027cebbd4b1b3a4ec979277882a.
---
 packages/solid-router/src/awaited.tsx | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/packages/solid-router/src/awaited.tsx b/packages/solid-router/src/awaited.tsx
index 42ef0498b6..892c67b19c 100644
--- a/packages/solid-router/src/awaited.tsx
+++ b/packages/solid-router/src/awaited.tsx
@@ -30,7 +30,14 @@ export function Await<T>(
     children: (result: T) => SolidNode
   },
 ) {
-  const [resource] = Solid.createResource(() => props.promise)
+  const [resource] = Solid.createResource(
+    () => defer(props.promise),
+    // Simple passthrough - just return the promise for Solid to await
+    (p) => p,
+    {
+      deferStream: true,
+    },
+  )
 
   return (
     <Solid.Show fallback={props.fallback} when={resource()}>

From eb19e594d661ad47e98879938816ec39c1dbf6bb Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Thu, 23 Oct 2025 02:43:13 +0200
Subject: [PATCH 23/33] add seroval to pnpm overrides

---
 pnpm-lock.yaml | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 1d41020e42..e1c2de534c 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -5847,7 +5847,7 @@ importers:
         version: 7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
       vitest:
         specifier: ^3.2.4
-        version: 3.2.4(@types/node@22.10.2)(@vitest/browser@3.0.6(@types/node@22.10.2)(playwright@1.52.0)(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))(vitest@3.2.4))(@vitest/ui@3.0.6(vitest@3.2.4))(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.7.0(@types/node@22.10.2)(typescript@5.9.2))(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
+        version: 3.2.4(@types/node@22.10.2)(@vitest/browser@3.0.6)(@vitest/ui@3.0.6)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.7.0(@types/node@22.10.2)(typescript@5.9.2))(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
       web-vitals:
         specifier: ^5.1.0
         version: 5.1.0
@@ -7882,7 +7882,7 @@ importers:
         specifier: ^2.0.0
         version: 2.0.0
       seroval:
-        specifier: ^1.3.2
+        specifier: 1.3.2
         version: 1.3.2
       seroval-plugins:
         specifier: ^1.3.2
@@ -8360,7 +8360,7 @@ importers:
         specifier: workspace:*
         version: link:../start-storage-context
       seroval:
-        specifier: ^1.3.2
+        specifier: 1.3.2
         version: 1.3.2
       tiny-invariant:
         specifier: ^1.3.3
@@ -8463,7 +8463,7 @@ importers:
         specifier: npm:h3@2.0.0-beta.4
         version: h3@2.0.0-beta.4(crossws@0.4.1(srvx@0.8.15))
       seroval:
-        specifier: ^1.3.2
+        specifier: 1.3.2
         version: 1.3.2
       tiny-invariant:
         specifier: ^1.3.3
@@ -8485,7 +8485,7 @@ importers:
         specifier: workspace:*
         version: link:../start-client-core
       seroval:
-        specifier: ^1.3.2
+        specifier: 1.3.2
         version: 1.3.2
 
   packages/start-storage-context:
@@ -17583,7 +17583,7 @@ packages:
     resolution: {integrity: sha512-0QvCV2lM3aj/U3YozDiVwx9zpH0q8A60CTWIv4Jszj/givcudPb48B+rkU5D51NJ0pTpweGMttHjboPa9/zoIQ==}
     engines: {node: '>=10'}
     peerDependencies:
-      seroval: ^1.0
+      seroval: 1.3.2
 
   seroval@1.3.2:
     resolution: {integrity: sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==}
@@ -30142,7 +30142,7 @@ snapshots:
     optionalDependencies:
       vite: 7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
 
-  vitest@3.2.4(@types/node@22.10.2)(@vitest/browser@3.0.6(@types/node@22.10.2)(playwright@1.52.0)(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))(vitest@3.2.4))(@vitest/ui@3.0.6(vitest@3.2.4))(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.7.0(@types/node@22.10.2)(typescript@5.9.2))(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1):
+  vitest@3.2.4(@types/node@22.10.2)(@vitest/browser@3.0.6)(@vitest/ui@3.0.6)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.30.2)(msw@2.7.0(@types/node@22.10.2)(typescript@5.9.2))(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1):
     dependencies:
       '@types/chai': 5.2.2
       '@vitest/expect': 3.2.4
@@ -30171,7 +30171,7 @@ snapshots:
       '@types/node': 22.10.2
       '@vitest/browser': 3.0.6(@types/node@22.10.2)(playwright@1.52.0)(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))(vitest@3.2.4)
       '@vitest/ui': 3.0.6(vitest@3.2.4)
-      jsdom: 27.0.0(postcss@8.5.6)
+      jsdom: 25.0.1
     transitivePeerDependencies:
       - jiti
       - less
@@ -30186,7 +30186,7 @@ snapshots:
       - tsx
       - yaml
 
-  vitest@3.2.4(@types/node@22.10.2)(@vitest/browser@3.0.6)(@vitest/ui@3.0.6)(jiti@2.6.1)(jsdom@25.0.1)(lightningcss@1.30.2)(msw@2.7.0(@types/node@22.10.2)(typescript@5.9.2))(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1):
+  vitest@3.2.4(@types/node@22.10.2)(@vitest/browser@3.0.6)(@vitest/ui@3.0.6)(jiti@2.6.1)(jsdom@27.0.0(postcss@8.5.6))(lightningcss@1.30.2)(msw@2.7.0(@types/node@22.10.2)(typescript@5.9.2))(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1):
     dependencies:
       '@types/chai': 5.2.2
       '@vitest/expect': 3.2.4
@@ -30215,7 +30215,7 @@ snapshots:
       '@types/node': 22.10.2
       '@vitest/browser': 3.0.6(@types/node@22.10.2)(playwright@1.52.0)(typescript@5.9.2)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))(vitest@3.2.4)
       '@vitest/ui': 3.0.6(vitest@3.2.4)
-      jsdom: 25.0.1
+      jsdom: 27.0.0(postcss@8.5.6)
     transitivePeerDependencies:
       - jiti
       - less

From 3e7d446946d35a56d2fa423afebed67373b7d3c7 Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Thu, 23 Oct 2025 03:24:38 +0200
Subject: [PATCH 24/33] add error component

---
 e2e/solid-start/serialization-adapters/src/routes/index.tsx    | 3 ++-
 .../serialization-adapters/src/routes/ssr/stream.tsx           | 2 ++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/e2e/solid-start/serialization-adapters/src/routes/index.tsx b/e2e/solid-start/serialization-adapters/src/routes/index.tsx
index 25f5da0c75..397c4bba7b 100644
--- a/e2e/solid-start/serialization-adapters/src/routes/index.tsx
+++ b/e2e/solid-start/serialization-adapters/src/routes/index.tsx
@@ -1,7 +1,8 @@
 import { Link, createFileRoute } from '@tanstack/solid-router'
 
 export const Route = createFileRoute('/')({
-  component: Home,
+    component: Home,
+    errorComponent: (e)=><div>{e.error.message} </div>,
 })
 
 function Home() {
diff --git a/e2e/solid-start/serialization-adapters/src/routes/ssr/stream.tsx b/e2e/solid-start/serialization-adapters/src/routes/ssr/stream.tsx
index 21e6eed173..5c35a28acb 100644
--- a/e2e/solid-start/serialization-adapters/src/routes/ssr/stream.tsx
+++ b/e2e/solid-start/serialization-adapters/src/routes/ssr/stream.tsx
@@ -12,6 +12,8 @@ export const Route = createFileRoute('/ssr/stream')({
       dataPromise,
     }
   },
+
+    errorComponent: (e)=><div>{e.error.message} </div>,
   component: RouteComponent,
 })
 

From 333ae5afa86a750973ce7089d42cc4c0d7da399d Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Thu, 23 Oct 2025 04:31:56 +0200
Subject: [PATCH 25/33] add synx/async to the transformer

---
 packages/router-core/src/ssr/serializer/transformer.ts | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/packages/router-core/src/ssr/serializer/transformer.ts b/packages/router-core/src/ssr/serializer/transformer.ts
index df86f965ed..f37acc70f4 100644
--- a/packages/router-core/src/ssr/serializer/transformer.ts
+++ b/packages/router-core/src/ssr/serializer/transformer.ts
@@ -167,6 +167,12 @@ export function makeSsrSerovalPlugin(
     tag: '$TSR/t/' + serializationAdapter.key,
     test: serializationAdapter.test,
     parse: {
+      sync(value, ctx) {
+        return ctx.parse(serializationAdapter.toSerializable(value))
+      },
+      async async(value, ctx) {
+        return await ctx.parse(serializationAdapter.toSerializable(value))
+      },
       stream(value, ctx) {
         return ctx.parse(serializationAdapter.toSerializable(value))
       },

From 20d7aaa41464c9202b7d838afc64d47c81bb3243 Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Thu, 23 Oct 2025 05:02:12 +0200
Subject: [PATCH 26/33] bump seroval

---
 e2e/solid-start/serialization-adapters/package.json | 1 +
 packages/router-core/package.json                   | 2 +-
 packages/start-client-core/package.json             | 2 +-
 packages/start-server-core/package.json             | 2 +-
 packages/start-static-server-functions/package.json | 2 +-
 pnpm-lock.yaml                                      | 3 +++
 6 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/e2e/solid-start/serialization-adapters/package.json b/e2e/solid-start/serialization-adapters/package.json
index 6b53df71cb..4dc07f190a 100644
--- a/e2e/solid-start/serialization-adapters/package.json
+++ b/e2e/solid-start/serialization-adapters/package.json
@@ -24,6 +24,7 @@
     "@tanstack/router-e2e-utils": "workspace:^",
     "@types/node": "^22.10.2",
     "postcss": "^8.5.1",
+    "seroval": "^1.3.3",
     "srvx": "^0.8.6",
     "tailwindcss": "^4.1.15",
     "typescript": "^5.7.2",
diff --git a/packages/router-core/package.json b/packages/router-core/package.json
index 04c5d348be..ab12b31121 100644
--- a/packages/router-core/package.json
+++ b/packages/router-core/package.json
@@ -82,7 +82,7 @@
     "@tanstack/history": "workspace:*",
     "@tanstack/store": "^0.7.0",
     "cookie-es": "^2.0.0",
-    "seroval": "^1.3.2",
+    "seroval": "^1.3.3",
     "seroval-plugins": "^1.3.2",
     "tiny-invariant": "^1.3.3",
     "tiny-warning": "^1.0.3"
diff --git a/packages/start-client-core/package.json b/packages/start-client-core/package.json
index 0d955d5ea2..8f6ed67029 100644
--- a/packages/start-client-core/package.json
+++ b/packages/start-client-core/package.json
@@ -81,7 +81,7 @@
   "dependencies": {
     "@tanstack/router-core": "workspace:*",
     "@tanstack/start-storage-context": "workspace:*",
-    "seroval": "^1.3.2",
+    "seroval": "^1.3.3",
     "tiny-invariant": "^1.3.3",
     "tiny-warning": "^1.0.3"
   }
diff --git a/packages/start-server-core/package.json b/packages/start-server-core/package.json
index 9c4bcbbfc2..8bb7ce189f 100644
--- a/packages/start-server-core/package.json
+++ b/packages/start-server-core/package.json
@@ -74,7 +74,7 @@
     "@tanstack/start-client-core": "workspace:*",
     "@tanstack/start-storage-context": "workspace:*",
     "h3-v2": "npm:h3@2.0.0-beta.4",
-    "seroval": "^1.3.2",
+    "seroval": "^1.3.3",
     "tiny-invariant": "^1.3.3"
   },
   "devDependencies": {
diff --git a/packages/start-static-server-functions/package.json b/packages/start-static-server-functions/package.json
index a62e4ccc37..f51af5a504 100644
--- a/packages/start-static-server-functions/package.json
+++ b/packages/start-static-server-functions/package.json
@@ -60,6 +60,6 @@
   },
   "dependencies": {
     "@tanstack/start-client-core": "workspace:*",
-    "seroval": "^1.3.2"
+    "seroval": "^1.3.3"
   }
 }
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e1c2de534c..4fab88efa7 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -3166,6 +3166,9 @@ importers:
       postcss:
         specifier: ^8.5.1
         version: 8.5.6
+      seroval:
+        specifier: 1.3.2
+        version: 1.3.2
       srvx:
         specifier: ^0.8.6
         version: 0.8.15

From 6357bab421ab12570ee4244cc5ba4a870e1ea818 Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Thu, 23 Oct 2025 13:19:59 +0200
Subject: [PATCH 27/33] seroval 1.3.2

---
 e2e/solid-start/serialization-adapters/package.json | 2 +-
 packages/router-core/package.json                   | 2 +-
 packages/start-client-core/package.json             | 2 +-
 packages/start-server-core/package.json             | 2 +-
 packages/start-static-server-functions/package.json | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/e2e/solid-start/serialization-adapters/package.json b/e2e/solid-start/serialization-adapters/package.json
index 4dc07f190a..dd6455e9a9 100644
--- a/e2e/solid-start/serialization-adapters/package.json
+++ b/e2e/solid-start/serialization-adapters/package.json
@@ -24,7 +24,7 @@
     "@tanstack/router-e2e-utils": "workspace:^",
     "@types/node": "^22.10.2",
     "postcss": "^8.5.1",
-    "seroval": "^1.3.3",
+    "seroval": "^1.3.2",
     "srvx": "^0.8.6",
     "tailwindcss": "^4.1.15",
     "typescript": "^5.7.2",
diff --git a/packages/router-core/package.json b/packages/router-core/package.json
index ab12b31121..04c5d348be 100644
--- a/packages/router-core/package.json
+++ b/packages/router-core/package.json
@@ -82,7 +82,7 @@
     "@tanstack/history": "workspace:*",
     "@tanstack/store": "^0.7.0",
     "cookie-es": "^2.0.0",
-    "seroval": "^1.3.3",
+    "seroval": "^1.3.2",
     "seroval-plugins": "^1.3.2",
     "tiny-invariant": "^1.3.3",
     "tiny-warning": "^1.0.3"
diff --git a/packages/start-client-core/package.json b/packages/start-client-core/package.json
index 8f6ed67029..0d955d5ea2 100644
--- a/packages/start-client-core/package.json
+++ b/packages/start-client-core/package.json
@@ -81,7 +81,7 @@
   "dependencies": {
     "@tanstack/router-core": "workspace:*",
     "@tanstack/start-storage-context": "workspace:*",
-    "seroval": "^1.3.3",
+    "seroval": "^1.3.2",
     "tiny-invariant": "^1.3.3",
     "tiny-warning": "^1.0.3"
   }
diff --git a/packages/start-server-core/package.json b/packages/start-server-core/package.json
index 8bb7ce189f..9c4bcbbfc2 100644
--- a/packages/start-server-core/package.json
+++ b/packages/start-server-core/package.json
@@ -74,7 +74,7 @@
     "@tanstack/start-client-core": "workspace:*",
     "@tanstack/start-storage-context": "workspace:*",
     "h3-v2": "npm:h3@2.0.0-beta.4",
-    "seroval": "^1.3.3",
+    "seroval": "^1.3.2",
     "tiny-invariant": "^1.3.3"
   },
   "devDependencies": {
diff --git a/packages/start-static-server-functions/package.json b/packages/start-static-server-functions/package.json
index f51af5a504..a62e4ccc37 100644
--- a/packages/start-static-server-functions/package.json
+++ b/packages/start-static-server-functions/package.json
@@ -60,6 +60,6 @@
   },
   "dependencies": {
     "@tanstack/start-client-core": "workspace:*",
-    "seroval": "^1.3.3"
+    "seroval": "^1.3.2"
   }
 }

From 265ff5e2b8cfc21f2852bdf845545a0c69ded6bb Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Thu, 23 Oct 2025 17:04:28 +0200
Subject: [PATCH 28/33] add not found component

---
 e2e/solid-start/serialization-adapters/src/routes/__root.tsx | 1 +
 1 file changed, 1 insertion(+)

diff --git a/e2e/solid-start/serialization-adapters/src/routes/__root.tsx b/e2e/solid-start/serialization-adapters/src/routes/__root.tsx
index 1beb580700..b3fd7de4cc 100644
--- a/e2e/solid-start/serialization-adapters/src/routes/__root.tsx
+++ b/e2e/solid-start/serialization-adapters/src/routes/__root.tsx
@@ -29,6 +29,7 @@ export const Route = createRootRoute({
     links: [{ rel: 'stylesheet', href: appCss }],
   }),
   shellComponent: RootDocument,
+  notFoundComponent: (e) => <div>404 - Not Found {JSON.stringify(e.data)}</div>,
 })
 
 function RootDocument({ children }: { children: JSX.Element }) {

From 74793804532079ffd7405d7f69c827b3d75c8b65 Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Thu, 23 Oct 2025 21:42:52 +0200
Subject: [PATCH 29/33] pass seroval plugins down to solid ssr

---
 packages/solid-router/src/ssr/renderRouterToStream.tsx | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/packages/solid-router/src/ssr/renderRouterToStream.tsx b/packages/solid-router/src/ssr/renderRouterToStream.tsx
index 8f5a8c2c56..8bec8cc0bc 100644
--- a/packages/solid-router/src/ssr/renderRouterToStream.tsx
+++ b/packages/solid-router/src/ssr/renderRouterToStream.tsx
@@ -1,6 +1,7 @@
 import * as Solid from 'solid-js/web'
 import { isbot } from 'isbot'
 import { transformReadableStreamWithRouter } from '@tanstack/router-core/ssr/server'
+import { makeSsrSerovalPlugin } from '@tanstack/router-core'
 import type { JSXElement } from 'solid-js'
 import type { ReadableStream } from 'node:stream/web'
 import type { AnyRouter } from '@tanstack/router-core'
@@ -20,6 +21,12 @@ export const renderRouterToStream = async ({
 
   const docType = Solid.ssr('<!DOCTYPE html>')
 
+  const serializationAdapters = (router.options as any)?.serializationAdapters || (router.options.ssr as any)?.serializationAdapters
+  const serovalPlugins = serializationAdapters?.map((adapter: any) => {
+    const plugin = makeSsrSerovalPlugin(adapter, { didRun: false })
+    return plugin
+  })
+  
   const stream = Solid.renderToStream(
     () => (
       <>
@@ -29,7 +36,8 @@ export const renderRouterToStream = async ({
     ),
     {
       nonce: router.options.ssr?.nonce,
-    },
+      plugins: serovalPlugins,
+    } as any,
   )
 
   if (isbot(request.headers.get('User-Agent'))) {

From 14dd99498437d482a36344145fe2844c87052d21 Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Mon, 27 Oct 2025 22:19:50 +0100
Subject: [PATCH 30/33] revert changes to router-core

---
 packages/router-core/src/ssr/serializer/transformer.ts | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/packages/router-core/src/ssr/serializer/transformer.ts b/packages/router-core/src/ssr/serializer/transformer.ts
index f37acc70f4..df86f965ed 100644
--- a/packages/router-core/src/ssr/serializer/transformer.ts
+++ b/packages/router-core/src/ssr/serializer/transformer.ts
@@ -167,12 +167,6 @@ export function makeSsrSerovalPlugin(
     tag: '$TSR/t/' + serializationAdapter.key,
     test: serializationAdapter.test,
     parse: {
-      sync(value, ctx) {
-        return ctx.parse(serializationAdapter.toSerializable(value))
-      },
-      async async(value, ctx) {
-        return await ctx.parse(serializationAdapter.toSerializable(value))
-      },
       stream(value, ctx) {
         return ctx.parse(serializationAdapter.toSerializable(value))
       },

From fdb188cf54e1d550ec70f557c014fa740aa8755e Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Mon, 27 Oct 2025 23:04:53 +0100
Subject: [PATCH 31/33] lcokfile

---
 .../serialization-adapters/package.json        |  2 +-
 pnpm-lock.yaml                                 | 18 +++++++++---------
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/e2e/solid-start/serialization-adapters/package.json b/e2e/solid-start/serialization-adapters/package.json
index dd6455e9a9..40cef1c37f 100644
--- a/e2e/solid-start/serialization-adapters/package.json
+++ b/e2e/solid-start/serialization-adapters/package.json
@@ -14,7 +14,7 @@
     "@tanstack/solid-router": "workspace:^",
     "@tanstack/solid-router-devtools": "workspace:^",
     "@tanstack/solid-start": "workspace:^",
-    "solid-js": "^1.9.9",
+    "solid-js": "^1.9.10",
     "vite": "^7.1.7",
     "vite-tsconfig-paths": "^5.1.4",
     "zod": "^3.24.2"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 4fab88efa7..e8a7931e64 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -3142,8 +3142,8 @@ importers:
         specifier: workspace:*
         version: link:../../../packages/solid-start
       solid-js:
-        specifier: 1.9.9
-        version: 1.9.9
+        specifier: 1.9.10
+        version: 1.9.10
       vite:
         specifier: ^7.1.7
         version: 7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1)
@@ -3167,7 +3167,7 @@ importers:
         specifier: ^8.5.1
         version: 8.5.6
       seroval:
-        specifier: 1.3.2
+        specifier: ^1.3.2
         version: 1.3.2
       srvx:
         specifier: ^0.8.6
@@ -3180,7 +3180,7 @@ importers:
         version: 5.9.2
       vite-plugin-solid:
         specifier: ^2.11.9
-        version: 2.11.10(@testing-library/jest-dom@6.6.3)(solid-js@1.9.9)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+        version: 2.11.10(@testing-library/jest-dom@6.6.3)(solid-js@1.9.10)(vite@7.1.7(@types/node@22.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
 
   e2e/solid-start/server-functions:
     dependencies:
@@ -7885,7 +7885,7 @@ importers:
         specifier: ^2.0.0
         version: 2.0.0
       seroval:
-        specifier: 1.3.2
+        specifier: ^1.3.2
         version: 1.3.2
       seroval-plugins:
         specifier: ^1.3.2
@@ -8363,7 +8363,7 @@ importers:
         specifier: workspace:*
         version: link:../start-storage-context
       seroval:
-        specifier: 1.3.2
+        specifier: ^1.3.2
         version: 1.3.2
       tiny-invariant:
         specifier: ^1.3.3
@@ -8466,7 +8466,7 @@ importers:
         specifier: npm:h3@2.0.0-beta.4
         version: h3@2.0.0-beta.4(crossws@0.4.1(srvx@0.8.15))
       seroval:
-        specifier: 1.3.2
+        specifier: ^1.3.2
         version: 1.3.2
       tiny-invariant:
         specifier: ^1.3.3
@@ -8488,7 +8488,7 @@ importers:
         specifier: workspace:*
         version: link:../start-client-core
       seroval:
-        specifier: 1.3.2
+        specifier: ^1.3.2
         version: 1.3.2
 
   packages/start-storage-context:
@@ -17586,7 +17586,7 @@ packages:
     resolution: {integrity: sha512-0QvCV2lM3aj/U3YozDiVwx9zpH0q8A60CTWIv4Jszj/givcudPb48B+rkU5D51NJ0pTpweGMttHjboPa9/zoIQ==}
     engines: {node: '>=10'}
     peerDependencies:
-      seroval: 1.3.2
+      seroval: ^1.0
 
   seroval@1.3.2:
     resolution: {integrity: sha512-RbcPH1n5cfwKrru7v7+zrZvjLurgHhGyso3HTyGtRivGWgYjbOmGuivCQaORNELjNONoK35nj28EoWul9sb1zQ==}

From 6f0b1d162646efd632d9673e32852366f03df6fb Mon Sep 17 00:00:00 2001
From: Birk Skyum <birk.skyum@pm.me>
Date: Mon, 27 Oct 2025 23:14:52 +0100
Subject: [PATCH 32/33] also add serialization plugins to renderRouterToString

---
 .../solid-router/src/ssr/renderRouterToString.tsx   | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/packages/solid-router/src/ssr/renderRouterToString.tsx b/packages/solid-router/src/ssr/renderRouterToString.tsx
index 1ba1db46df..8124d84909 100644
--- a/packages/solid-router/src/ssr/renderRouterToString.tsx
+++ b/packages/solid-router/src/ssr/renderRouterToString.tsx
@@ -1,6 +1,7 @@
 import * as Solid from 'solid-js/web'
+import { makeSsrSerovalPlugin } from '@tanstack/router-core'
+import type {AnyRouter} from '@tanstack/router-core';
 import type { JSXElement } from 'solid-js'
-import type { AnyRouter } from '@tanstack/router-core'
 
 export const renderRouterToString = async ({
   router,
@@ -12,9 +13,17 @@ export const renderRouterToString = async ({
   children: () => JSXElement
 }) => {
   try {
+
+    const serializationAdapters = (router.options as any)?.serializationAdapters || (router.options.ssr as any)?.serializationAdapters
+    const serovalPlugins = serializationAdapters?.map((adapter: any) => {
+      const plugin = makeSsrSerovalPlugin(adapter, { didRun: false })
+      return plugin
+    })
+
     let html = Solid.renderToString(children, {
       nonce: router.options.ssr?.nonce,
-    })
+      plugins: serovalPlugins,
+    } as any)
     router.serverSsr!.setRenderFinished()
     const injectedHtml = await Promise.all(router.serverSsr!.injectedHtml).then(
       (htmls) => htmls.join(''),

From 199c360dae176092769b091ee7bfc339f1b9334a Mon Sep 17 00:00:00 2001
From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com>
Date: Mon, 27 Oct 2025 22:15:52 +0000
Subject: [PATCH 33/33] ci: apply automated fixes

---
 .../serialization-adapters/src/routes/__root.tsx           | 6 +++---
 .../serialization-adapters/src/routes/index.tsx            | 4 ++--
 .../src/routes/server-function/custom-error.tsx            | 5 ++---
 .../serialization-adapters/src/routes/ssr/stream.tsx       | 2 +-
 packages/solid-router/src/ssr/renderRouterToStream.tsx     | 6 ++++--
 packages/solid-router/src/ssr/renderRouterToString.tsx     | 7 ++++---
 6 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/e2e/solid-start/serialization-adapters/src/routes/__root.tsx b/e2e/solid-start/serialization-adapters/src/routes/__root.tsx
index b3fd7de4cc..efd3a0abd5 100644
--- a/e2e/solid-start/serialization-adapters/src/routes/__root.tsx
+++ b/e2e/solid-start/serialization-adapters/src/routes/__root.tsx
@@ -8,14 +8,14 @@ import {
   useRouterState,
 } from '@tanstack/solid-router'
 import { TanStackRouterDevtools } from '@tanstack/solid-router-devtools'
-import { HydrationScript } from 'solid-js/web';
-import type {JSX} from 'solid-js';
+import { HydrationScript } from 'solid-js/web'
+import type { JSX } from 'solid-js'
 import appCss from '~/styles/app.css?url'
 
 export const Route = createRootRoute({
   head: () => ({
     meta: [
-    {
+      {
         charset: 'utf-8',
       },
       {
diff --git a/e2e/solid-start/serialization-adapters/src/routes/index.tsx b/e2e/solid-start/serialization-adapters/src/routes/index.tsx
index 397c4bba7b..7a7fc72ce0 100644
--- a/e2e/solid-start/serialization-adapters/src/routes/index.tsx
+++ b/e2e/solid-start/serialization-adapters/src/routes/index.tsx
@@ -1,8 +1,8 @@
 import { Link, createFileRoute } from '@tanstack/solid-router'
 
 export const Route = createFileRoute('/')({
-    component: Home,
-    errorComponent: (e)=><div>{e.error.message} </div>,
+  component: Home,
+  errorComponent: (e) => <div>{e.error.message} </div>,
 })
 
 function Home() {
diff --git a/e2e/solid-start/serialization-adapters/src/routes/server-function/custom-error.tsx b/e2e/solid-start/serialization-adapters/src/routes/server-function/custom-error.tsx
index 07fff5df76..ce24279720 100644
--- a/e2e/solid-start/serialization-adapters/src/routes/server-function/custom-error.tsx
+++ b/e2e/solid-start/serialization-adapters/src/routes/server-function/custom-error.tsx
@@ -22,9 +22,8 @@ export const Route = createFileRoute('/server-function/custom-error')({
 
 function RouteComponent() {
   const [validResponse, setValidResponse] = createSignal<any>(null)
-  const [invalidResponse, setInvalidResponse] = createSignal<CustomError | null>(
-    null,
-  )
+  const [invalidResponse, setInvalidResponse] =
+    createSignal<CustomError | null>(null)
 
   return (
     <div>
diff --git a/e2e/solid-start/serialization-adapters/src/routes/ssr/stream.tsx b/e2e/solid-start/serialization-adapters/src/routes/ssr/stream.tsx
index 5c35a28acb..473818eef6 100644
--- a/e2e/solid-start/serialization-adapters/src/routes/ssr/stream.tsx
+++ b/e2e/solid-start/serialization-adapters/src/routes/ssr/stream.tsx
@@ -13,7 +13,7 @@ export const Route = createFileRoute('/ssr/stream')({
     }
   },
 
-    errorComponent: (e)=><div>{e.error.message} </div>,
+  errorComponent: (e) => <div>{e.error.message} </div>,
   component: RouteComponent,
 })
 
diff --git a/packages/solid-router/src/ssr/renderRouterToStream.tsx b/packages/solid-router/src/ssr/renderRouterToStream.tsx
index 8bec8cc0bc..5c3e403060 100644
--- a/packages/solid-router/src/ssr/renderRouterToStream.tsx
+++ b/packages/solid-router/src/ssr/renderRouterToStream.tsx
@@ -21,12 +21,14 @@ export const renderRouterToStream = async ({
 
   const docType = Solid.ssr('<!DOCTYPE html>')
 
-  const serializationAdapters = (router.options as any)?.serializationAdapters || (router.options.ssr as any)?.serializationAdapters
+  const serializationAdapters =
+    (router.options as any)?.serializationAdapters ||
+    (router.options.ssr as any)?.serializationAdapters
   const serovalPlugins = serializationAdapters?.map((adapter: any) => {
     const plugin = makeSsrSerovalPlugin(adapter, { didRun: false })
     return plugin
   })
-  
+
   const stream = Solid.renderToStream(
     () => (
       <>
diff --git a/packages/solid-router/src/ssr/renderRouterToString.tsx b/packages/solid-router/src/ssr/renderRouterToString.tsx
index 8124d84909..4394062fed 100644
--- a/packages/solid-router/src/ssr/renderRouterToString.tsx
+++ b/packages/solid-router/src/ssr/renderRouterToString.tsx
@@ -1,6 +1,6 @@
 import * as Solid from 'solid-js/web'
 import { makeSsrSerovalPlugin } from '@tanstack/router-core'
-import type {AnyRouter} from '@tanstack/router-core';
+import type { AnyRouter } from '@tanstack/router-core'
 import type { JSXElement } from 'solid-js'
 
 export const renderRouterToString = async ({
@@ -13,8 +13,9 @@ export const renderRouterToString = async ({
   children: () => JSXElement
 }) => {
   try {
-
-    const serializationAdapters = (router.options as any)?.serializationAdapters || (router.options.ssr as any)?.serializationAdapters
+    const serializationAdapters =
+      (router.options as any)?.serializationAdapters ||
+      (router.options.ssr as any)?.serializationAdapters
     const serovalPlugins = serializationAdapters?.map((adapter: any) => {
       const plugin = makeSsrSerovalPlugin(adapter, { didRun: false })
       return plugin
