diff --git a/docs/router/framework/react/api/router.md b/docs/router/api/router.md
similarity index 100%
rename from docs/router/framework/react/api/router.md
rename to docs/router/api/router.md
diff --git a/docs/router/framework/react/api/router/ActiveLinkOptionsType.md b/docs/router/api/router/ActiveLinkOptionsType.md
similarity index 100%
rename from docs/router/framework/react/api/router/ActiveLinkOptionsType.md
rename to docs/router/api/router/ActiveLinkOptionsType.md
diff --git a/docs/router/framework/react/api/router/AsyncRouteComponentType.md b/docs/router/api/router/AsyncRouteComponentType.md
similarity index 100%
rename from docs/router/framework/react/api/router/AsyncRouteComponentType.md
rename to docs/router/api/router/AsyncRouteComponentType.md
diff --git a/docs/router/framework/react/api/router/FileRouteClass.md b/docs/router/api/router/FileRouteClass.md
similarity index 100%
rename from docs/router/framework/react/api/router/FileRouteClass.md
rename to docs/router/api/router/FileRouteClass.md
diff --git a/docs/router/framework/react/api/router/LinkOptionsType.md b/docs/router/api/router/LinkOptionsType.md
similarity index 100%
rename from docs/router/framework/react/api/router/LinkOptionsType.md
rename to docs/router/api/router/LinkOptionsType.md
diff --git a/docs/router/framework/react/api/router/LinkPropsType.md b/docs/router/api/router/LinkPropsType.md
similarity index 100%
rename from docs/router/framework/react/api/router/LinkPropsType.md
rename to docs/router/api/router/LinkPropsType.md
diff --git a/docs/router/framework/react/api/router/MatchRouteOptionsType.md b/docs/router/api/router/MatchRouteOptionsType.md
similarity index 100%
rename from docs/router/framework/react/api/router/MatchRouteOptionsType.md
rename to docs/router/api/router/MatchRouteOptionsType.md
diff --git a/docs/router/framework/react/api/router/NavigateOptionsType.md b/docs/router/api/router/NavigateOptionsType.md
similarity index 100%
rename from docs/router/framework/react/api/router/NavigateOptionsType.md
rename to docs/router/api/router/NavigateOptionsType.md
diff --git a/docs/router/framework/react/api/router/NotFoundErrorType.md b/docs/router/api/router/NotFoundErrorType.md
similarity index 100%
rename from docs/router/framework/react/api/router/NotFoundErrorType.md
rename to docs/router/api/router/NotFoundErrorType.md
diff --git a/docs/router/framework/react/api/router/NotFoundRouteClass.md b/docs/router/api/router/NotFoundRouteClass.md
similarity index 100%
rename from docs/router/framework/react/api/router/NotFoundRouteClass.md
rename to docs/router/api/router/NotFoundRouteClass.md
diff --git a/docs/router/framework/react/api/router/ParsedHistoryStateType.md b/docs/router/api/router/ParsedHistoryStateType.md
similarity index 100%
rename from docs/router/framework/react/api/router/ParsedHistoryStateType.md
rename to docs/router/api/router/ParsedHistoryStateType.md
diff --git a/docs/router/framework/react/api/router/ParsedLocationType.md b/docs/router/api/router/ParsedLocationType.md
similarity index 100%
rename from docs/router/framework/react/api/router/ParsedLocationType.md
rename to docs/router/api/router/ParsedLocationType.md
diff --git a/docs/router/framework/react/api/router/RedirectType.md b/docs/router/api/router/RedirectType.md
similarity index 100%
rename from docs/router/framework/react/api/router/RedirectType.md
rename to docs/router/api/router/RedirectType.md
diff --git a/docs/router/framework/react/api/router/RegisterType.md b/docs/router/api/router/RegisterType.md
similarity index 100%
rename from docs/router/framework/react/api/router/RegisterType.md
rename to docs/router/api/router/RegisterType.md
diff --git a/docs/router/framework/react/api/router/RootRouteClass.md b/docs/router/api/router/RootRouteClass.md
similarity index 100%
rename from docs/router/framework/react/api/router/RootRouteClass.md
rename to docs/router/api/router/RootRouteClass.md
diff --git a/docs/router/framework/react/api/router/RouteApiClass.md b/docs/router/api/router/RouteApiClass.md
similarity index 100%
rename from docs/router/framework/react/api/router/RouteApiClass.md
rename to docs/router/api/router/RouteApiClass.md
diff --git a/docs/router/framework/react/api/router/RouteApiType.md b/docs/router/api/router/RouteApiType.md
similarity index 100%
rename from docs/router/framework/react/api/router/RouteApiType.md
rename to docs/router/api/router/RouteApiType.md
diff --git a/docs/router/framework/react/api/router/RouteClass.md b/docs/router/api/router/RouteClass.md
similarity index 100%
rename from docs/router/framework/react/api/router/RouteClass.md
rename to docs/router/api/router/RouteClass.md
diff --git a/docs/router/framework/react/api/router/RouteMaskType.md b/docs/router/api/router/RouteMaskType.md
similarity index 100%
rename from docs/router/framework/react/api/router/RouteMaskType.md
rename to docs/router/api/router/RouteMaskType.md
diff --git a/docs/router/framework/react/api/router/RouteMatchType.md b/docs/router/api/router/RouteMatchType.md
similarity index 100%
rename from docs/router/framework/react/api/router/RouteMatchType.md
rename to docs/router/api/router/RouteMatchType.md
diff --git a/docs/router/framework/react/api/router/RouteOptionsType.md b/docs/router/api/router/RouteOptionsType.md
similarity index 100%
rename from docs/router/framework/react/api/router/RouteOptionsType.md
rename to docs/router/api/router/RouteOptionsType.md
diff --git a/docs/router/framework/react/api/router/RouteType.md b/docs/router/api/router/RouteType.md
similarity index 100%
rename from docs/router/framework/react/api/router/RouteType.md
rename to docs/router/api/router/RouteType.md
diff --git a/docs/router/framework/react/api/router/RouterClass.md b/docs/router/api/router/RouterClass.md
similarity index 100%
rename from docs/router/framework/react/api/router/RouterClass.md
rename to docs/router/api/router/RouterClass.md
diff --git a/docs/router/framework/react/api/router/RouterEventsType.md b/docs/router/api/router/RouterEventsType.md
similarity index 100%
rename from docs/router/framework/react/api/router/RouterEventsType.md
rename to docs/router/api/router/RouterEventsType.md
diff --git a/docs/router/framework/react/api/router/RouterOptionsType.md b/docs/router/api/router/RouterOptionsType.md
similarity index 91%
rename from docs/router/framework/react/api/router/RouterOptionsType.md
rename to docs/router/api/router/RouterOptionsType.md
index 62c1a7cd4e..49ff706d2b 100644
--- a/docs/router/framework/react/api/router/RouterOptionsType.md
+++ b/docs/router/api/router/RouterOptionsType.md
@@ -144,6 +144,41 @@ The `RouterOptions` type accepts an object with the following properties and met
 - When `true`, disables the global catch boundary that normally wraps all route matches. This allows unhandled errors to bubble up to top-level error handlers in the browser.
 - Useful for testing tools, error reporting services, and debugging scenarios.
 
+### `protocolAllowlist` property
+
+- Type: `Array<string>`
+- Optional
+- Defaults to `DEFAULT_PROTOCOL_ALLOWLIST` which includes:
+  - Web navigation: `http:`, `https:`
+  - Common browser-safe actions: `mailto:`, `tel:`
+- An array of URL protocols that are allowed in links, redirects, and navigation. Absolute URLs with protocols not in this list are rejected to prevent security vulnerabilities like XSS attacks.
+- This check is applied across router navigation APIs, including:
+  - `<Link to="...">`
+  - `navigate({ to: ... })` and `navigate({ href: ... })`
+  - `redirect({ to: ... })` and `redirect({ href: ... })`
+- Protocol entries must match `URL.protocol` format (lowercase with a trailing `:`), for example `blob:` or `data:`. If you configure `protocolAllowlist: ['blob']` (without `:`), links using `blob:` will still be blocked.
+
+**Example**
+
+```tsx
+import {
+  createRouter,
+  DEFAULT_PROTOCOL_ALLOWLIST,
+} from '@tanstack/react-router'
+
+// Use a custom allowlist (replaces the default)
+const router = createRouter({
+  routeTree,
+  protocolAllowlist: ['https:', 'mailto:'],
+})
+
+// Or extend the default allowlist
+const router = createRouter({
+  routeTree,
+  protocolAllowlist: [...DEFAULT_PROTOCOL_ALLOWLIST, 'ftp:'],
+})
+```
+
 ### `defaultViewTransition` property
 
 - Type: `boolean | ViewTransitionOptions`
diff --git a/docs/router/framework/react/api/router/RouterStateType.md b/docs/router/api/router/RouterStateType.md
similarity index 74%
rename from docs/router/framework/react/api/router/RouterStateType.md
rename to docs/router/api/router/RouterStateType.md
index 6c4d2aca93..65dd31db9a 100644
--- a/docs/router/framework/react/api/router/RouterStateType.md
+++ b/docs/router/api/router/RouterStateType.md
@@ -3,7 +3,7 @@ id: RouterStateType
 title: RouterState type
 ---
 
-The `RouterState` type represents shape of the internal state of the router. The Router's internal state is useful, if you need to access certain internals of the router, such as any pending matches, is the router in its loading state, etc.
+The `RouterState` type represents shape of the internal state of the router. The Router's internal state is useful if you need to access certain internals of the router, such as whether it is currently loading.
 
 ```tsx
 type RouterState = {
@@ -11,7 +11,6 @@ type RouterState = {
   isLoading: boolean
   isTransitioning: boolean
   matches: Array<RouteMatch>
-  pendingMatches: Array<RouteMatch>
   location: ParsedLocation
   resolvedLocation: ParsedLocation
 }
@@ -21,6 +20,14 @@ type RouterState = {
 
 The `RouterState` type contains all of the properties that are available on the router state.
 
+## Migration notes
+
+If you previously used `router.state.pendingMatches`, use one of these patterns instead:
+
+- `router.state.status === 'pending'` to detect an in-flight navigation.
+- `router.state.isLoading` to detect active loading work.
+- `router.matchRoute(...)` with `{ pending: true }` when you need to match against the pending location.
+
 ### `status` property
 
 - Type: `'pending' | 'idle'`
@@ -41,11 +48,6 @@ The `RouterState` type contains all of the properties that are available on the
 - Type: [`Array<RouteMatch>`](./RouteMatchType.md)
 - An array of all of the route matches that have been resolved and are currently active.
 
-### `pendingMatches` property
-
-- Type: [`Array<RouteMatch>`](./RouteMatchType.md)
-- An array of all of the route matches that are currently pending.
-
 ### `location` property
 
 - Type: [`ParsedLocation`](./ParsedLocationType.md)
diff --git a/docs/router/framework/react/api/router/RouterType.md b/docs/router/api/router/RouterType.md
similarity index 100%
rename from docs/router/framework/react/api/router/RouterType.md
rename to docs/router/api/router/RouterType.md
diff --git a/docs/router/framework/react/api/router/ToMaskOptionsType.md b/docs/router/api/router/ToMaskOptionsType.md
similarity index 100%
rename from docs/router/framework/react/api/router/ToMaskOptionsType.md
rename to docs/router/api/router/ToMaskOptionsType.md
diff --git a/docs/router/framework/react/api/router/ToOptionsType.md b/docs/router/api/router/ToOptionsType.md
similarity index 100%
rename from docs/router/framework/react/api/router/ToOptionsType.md
rename to docs/router/api/router/ToOptionsType.md
diff --git a/docs/router/framework/react/api/router/UseMatchRouteOptionsType.md b/docs/router/api/router/UseMatchRouteOptionsType.md
similarity index 100%
rename from docs/router/framework/react/api/router/UseMatchRouteOptionsType.md
rename to docs/router/api/router/UseMatchRouteOptionsType.md
diff --git a/docs/router/framework/react/api/router/ViewTransitionOptionsType.md b/docs/router/api/router/ViewTransitionOptionsType.md
similarity index 100%
rename from docs/router/framework/react/api/router/ViewTransitionOptionsType.md
rename to docs/router/api/router/ViewTransitionOptionsType.md
diff --git a/docs/router/framework/react/api/router/awaitComponent.md b/docs/router/api/router/awaitComponent.md
similarity index 100%
rename from docs/router/framework/react/api/router/awaitComponent.md
rename to docs/router/api/router/awaitComponent.md
diff --git a/docs/router/framework/react/api/router/catchBoundaryComponent.md b/docs/router/api/router/catchBoundaryComponent.md
similarity index 100%
rename from docs/router/framework/react/api/router/catchBoundaryComponent.md
rename to docs/router/api/router/catchBoundaryComponent.md
diff --git a/docs/router/framework/react/api/router/catchNotFoundComponent.md b/docs/router/api/router/catchNotFoundComponent.md
similarity index 100%
rename from docs/router/framework/react/api/router/catchNotFoundComponent.md
rename to docs/router/api/router/catchNotFoundComponent.md
diff --git a/docs/router/framework/react/api/router/clientOnlyComponent.md b/docs/router/api/router/clientOnlyComponent.md
similarity index 100%
rename from docs/router/framework/react/api/router/clientOnlyComponent.md
rename to docs/router/api/router/clientOnlyComponent.md
diff --git a/docs/router/framework/react/api/router/createFileRouteFunction.md b/docs/router/api/router/createFileRouteFunction.md
similarity index 100%
rename from docs/router/framework/react/api/router/createFileRouteFunction.md
rename to docs/router/api/router/createFileRouteFunction.md
diff --git a/docs/router/framework/react/api/router/createLazyFileRouteFunction.md b/docs/router/api/router/createLazyFileRouteFunction.md
similarity index 100%
rename from docs/router/framework/react/api/router/createLazyFileRouteFunction.md
rename to docs/router/api/router/createLazyFileRouteFunction.md
diff --git a/docs/router/framework/react/api/router/createLazyRouteFunction.md b/docs/router/api/router/createLazyRouteFunction.md
similarity index 100%
rename from docs/router/framework/react/api/router/createLazyRouteFunction.md
rename to docs/router/api/router/createLazyRouteFunction.md
diff --git a/docs/router/framework/react/api/router/createRootRouteFunction.md b/docs/router/api/router/createRootRouteFunction.md
similarity index 100%
rename from docs/router/framework/react/api/router/createRootRouteFunction.md
rename to docs/router/api/router/createRootRouteFunction.md
diff --git a/docs/router/framework/react/api/router/createRootRouteWithContextFunction.md b/docs/router/api/router/createRootRouteWithContextFunction.md
similarity index 100%
rename from docs/router/framework/react/api/router/createRootRouteWithContextFunction.md
rename to docs/router/api/router/createRootRouteWithContextFunction.md
diff --git a/docs/router/framework/react/api/router/createRouteFunction.md b/docs/router/api/router/createRouteFunction.md
similarity index 100%
rename from docs/router/framework/react/api/router/createRouteFunction.md
rename to docs/router/api/router/createRouteFunction.md
diff --git a/docs/router/framework/react/api/router/createRouteMaskFunction.md b/docs/router/api/router/createRouteMaskFunction.md
similarity index 100%
rename from docs/router/framework/react/api/router/createRouteMaskFunction.md
rename to docs/router/api/router/createRouteMaskFunction.md
diff --git a/docs/router/framework/react/api/router/createRouterFunction.md b/docs/router/api/router/createRouterFunction.md
similarity index 100%
rename from docs/router/framework/react/api/router/createRouterFunction.md
rename to docs/router/api/router/createRouterFunction.md
diff --git a/docs/router/framework/react/api/router/defaultGlobalNotFoundComponent.md b/docs/router/api/router/defaultGlobalNotFoundComponent.md
similarity index 100%
rename from docs/router/framework/react/api/router/defaultGlobalNotFoundComponent.md
rename to docs/router/api/router/defaultGlobalNotFoundComponent.md
diff --git a/docs/router/framework/react/api/router/deferFunction.md b/docs/router/api/router/deferFunction.md
similarity index 100%
rename from docs/router/framework/react/api/router/deferFunction.md
rename to docs/router/api/router/deferFunction.md
diff --git a/docs/router/framework/react/api/router/errorComponentComponent.md b/docs/router/api/router/errorComponentComponent.md
similarity index 100%
rename from docs/router/framework/react/api/router/errorComponentComponent.md
rename to docs/router/api/router/errorComponentComponent.md
diff --git a/docs/router/framework/react/api/router/getRouteApiFunction.md b/docs/router/api/router/getRouteApiFunction.md
similarity index 100%
rename from docs/router/framework/react/api/router/getRouteApiFunction.md
rename to docs/router/api/router/getRouteApiFunction.md
diff --git a/docs/router/framework/react/api/router/historyStateInterface.md b/docs/router/api/router/historyStateInterface.md
similarity index 100%
rename from docs/router/framework/react/api/router/historyStateInterface.md
rename to docs/router/api/router/historyStateInterface.md
diff --git a/docs/router/framework/react/api/router/isNotFoundFunction.md b/docs/router/api/router/isNotFoundFunction.md
similarity index 100%
rename from docs/router/framework/react/api/router/isNotFoundFunction.md
rename to docs/router/api/router/isNotFoundFunction.md
diff --git a/docs/router/framework/react/api/router/isRedirectFunction.md b/docs/router/api/router/isRedirectFunction.md
similarity index 100%
rename from docs/router/framework/react/api/router/isRedirectFunction.md
rename to docs/router/api/router/isRedirectFunction.md
diff --git a/docs/router/framework/react/api/router/lazyRouteComponentFunction.md b/docs/router/api/router/lazyRouteComponentFunction.md
similarity index 100%
rename from docs/router/framework/react/api/router/lazyRouteComponentFunction.md
rename to docs/router/api/router/lazyRouteComponentFunction.md
diff --git a/docs/router/framework/react/api/router/linkComponent.md b/docs/router/api/router/linkComponent.md
similarity index 100%
rename from docs/router/framework/react/api/router/linkComponent.md
rename to docs/router/api/router/linkComponent.md
diff --git a/docs/router/framework/react/api/router/linkOptions.md b/docs/router/api/router/linkOptions.md
similarity index 100%
rename from docs/router/framework/react/api/router/linkOptions.md
rename to docs/router/api/router/linkOptions.md
diff --git a/docs/router/framework/react/api/router/matchRouteComponent.md b/docs/router/api/router/matchRouteComponent.md
similarity index 100%
rename from docs/router/framework/react/api/router/matchRouteComponent.md
rename to docs/router/api/router/matchRouteComponent.md
diff --git a/docs/router/framework/react/api/router/navigateComponent.md b/docs/router/api/router/navigateComponent.md
similarity index 100%
rename from docs/router/framework/react/api/router/navigateComponent.md
rename to docs/router/api/router/navigateComponent.md
diff --git a/docs/router/framework/react/api/router/notFoundComponentComponent.md b/docs/router/api/router/notFoundComponentComponent.md
similarity index 100%
rename from docs/router/framework/react/api/router/notFoundComponentComponent.md
rename to docs/router/api/router/notFoundComponentComponent.md
diff --git a/docs/router/framework/react/api/router/notFoundFunction.md b/docs/router/api/router/notFoundFunction.md
similarity index 100%
rename from docs/router/framework/react/api/router/notFoundFunction.md
rename to docs/router/api/router/notFoundFunction.md
diff --git a/docs/router/framework/react/api/router/outletComponent.md b/docs/router/api/router/outletComponent.md
similarity index 100%
rename from docs/router/framework/react/api/router/outletComponent.md
rename to docs/router/api/router/outletComponent.md
diff --git a/docs/router/framework/react/api/router/redirectFunction.md b/docs/router/api/router/redirectFunction.md
similarity index 100%
rename from docs/router/framework/react/api/router/redirectFunction.md
rename to docs/router/api/router/redirectFunction.md
diff --git a/docs/router/framework/react/api/router/retainSearchParamsFunction.md b/docs/router/api/router/retainSearchParamsFunction.md
similarity index 100%
rename from docs/router/framework/react/api/router/retainSearchParamsFunction.md
rename to docs/router/api/router/retainSearchParamsFunction.md
diff --git a/docs/router/framework/react/api/router/rootRouteWithContextFunction.md b/docs/router/api/router/rootRouteWithContextFunction.md
similarity index 100%
rename from docs/router/framework/react/api/router/rootRouteWithContextFunction.md
rename to docs/router/api/router/rootRouteWithContextFunction.md
diff --git a/docs/router/framework/react/api/router/stripSearchParamsFunction.md b/docs/router/api/router/stripSearchParamsFunction.md
similarity index 100%
rename from docs/router/framework/react/api/router/stripSearchParamsFunction.md
rename to docs/router/api/router/stripSearchParamsFunction.md
diff --git a/docs/router/framework/react/api/router/useAwaitedHook.md b/docs/router/api/router/useAwaitedHook.md
similarity index 100%
rename from docs/router/framework/react/api/router/useAwaitedHook.md
rename to docs/router/api/router/useAwaitedHook.md
diff --git a/docs/router/framework/react/api/router/useBlockerHook.md b/docs/router/api/router/useBlockerHook.md
similarity index 100%
rename from docs/router/framework/react/api/router/useBlockerHook.md
rename to docs/router/api/router/useBlockerHook.md
diff --git a/docs/router/framework/react/api/router/useCanGoBack.md b/docs/router/api/router/useCanGoBack.md
similarity index 100%
rename from docs/router/framework/react/api/router/useCanGoBack.md
rename to docs/router/api/router/useCanGoBack.md
diff --git a/docs/router/framework/react/api/router/useChildMatchesHook.md b/docs/router/api/router/useChildMatchesHook.md
similarity index 88%
rename from docs/router/framework/react/api/router/useChildMatchesHook.md
rename to docs/router/api/router/useChildMatchesHook.md
index cf31d21016..93b6a5fc49 100644
--- a/docs/router/framework/react/api/router/useChildMatchesHook.md
+++ b/docs/router/api/router/useChildMatchesHook.md
@@ -5,9 +5,6 @@ title: useChildMatches hook
 
 The `useChildMatches` hook returns all of the child [`RouteMatch`](./RouteMatchType.md) objects from the closest match down to the leaf-most match. **It does not include the current match, which can be obtained using the `useMatch` hook.**
 
-> [!IMPORTANT]
-> If the router has pending matches and they are showing their pending component fallbacks, `router.state.pendingMatches` will used instead of `router.state.matches`.
-
 ## useChildMatches options
 
 The `useChildMatches` hook accepts a single _optional_ argument, an `options` object.
diff --git a/docs/router/framework/react/api/router/useLinkPropsHook.md b/docs/router/api/router/useLinkPropsHook.md
similarity index 100%
rename from docs/router/framework/react/api/router/useLinkPropsHook.md
rename to docs/router/api/router/useLinkPropsHook.md
diff --git a/docs/router/framework/react/api/router/useLoaderDataHook.md b/docs/router/api/router/useLoaderDataHook.md
similarity index 100%
rename from docs/router/framework/react/api/router/useLoaderDataHook.md
rename to docs/router/api/router/useLoaderDataHook.md
diff --git a/docs/router/framework/react/api/router/useLoaderDepsHook.md b/docs/router/api/router/useLoaderDepsHook.md
similarity index 100%
rename from docs/router/framework/react/api/router/useLoaderDepsHook.md
rename to docs/router/api/router/useLoaderDepsHook.md
diff --git a/docs/router/framework/react/api/router/useLocationHook.md b/docs/router/api/router/useLocationHook.md
similarity index 100%
rename from docs/router/framework/react/api/router/useLocationHook.md
rename to docs/router/api/router/useLocationHook.md
diff --git a/docs/router/framework/react/api/router/useMatchHook.md b/docs/router/api/router/useMatchHook.md
similarity index 100%
rename from docs/router/framework/react/api/router/useMatchHook.md
rename to docs/router/api/router/useMatchHook.md
diff --git a/docs/router/framework/react/api/router/useMatchRouteHook.md b/docs/router/api/router/useMatchRouteHook.md
similarity index 100%
rename from docs/router/framework/react/api/router/useMatchRouteHook.md
rename to docs/router/api/router/useMatchRouteHook.md
diff --git a/docs/router/framework/react/api/router/useMatchesHook.md b/docs/router/api/router/useMatchesHook.md
similarity index 100%
rename from docs/router/framework/react/api/router/useMatchesHook.md
rename to docs/router/api/router/useMatchesHook.md
diff --git a/docs/router/framework/react/api/router/useNavigateHook.md b/docs/router/api/router/useNavigateHook.md
similarity index 100%
rename from docs/router/framework/react/api/router/useNavigateHook.md
rename to docs/router/api/router/useNavigateHook.md
diff --git a/docs/router/framework/react/api/router/useParamsHook.md b/docs/router/api/router/useParamsHook.md
similarity index 100%
rename from docs/router/framework/react/api/router/useParamsHook.md
rename to docs/router/api/router/useParamsHook.md
diff --git a/docs/router/framework/react/api/router/useParentMatchesHook.md b/docs/router/api/router/useParentMatchesHook.md
similarity index 88%
rename from docs/router/framework/react/api/router/useParentMatchesHook.md
rename to docs/router/api/router/useParentMatchesHook.md
index fe4068f397..d22063b3ca 100644
--- a/docs/router/framework/react/api/router/useParentMatchesHook.md
+++ b/docs/router/api/router/useParentMatchesHook.md
@@ -5,9 +5,6 @@ title: useParentMatches hook
 
 The `useParentMatches` hook returns all of the parent [`RouteMatch`](./RouteMatchType.md) objects from the root down to the immediate parent of the current match in context. **It does not include the current match, which can be obtained using the `useMatch` hook.**
 
-> [!IMPORTANT]
-> If the router has pending matches and they are showing their pending component fallbacks, `router.state.pendingMatches` will used instead of `router.state.matches`.
-
 ## useParentMatches options
 
 The `useParentMatches` hook accepts an optional `options` object.
diff --git a/docs/router/framework/react/api/router/useRouteContextHook.md b/docs/router/api/router/useRouteContextHook.md
similarity index 100%
rename from docs/router/framework/react/api/router/useRouteContextHook.md
rename to docs/router/api/router/useRouteContextHook.md
diff --git a/docs/router/framework/react/api/router/useRouterHook.md b/docs/router/api/router/useRouterHook.md
similarity index 100%
rename from docs/router/framework/react/api/router/useRouterHook.md
rename to docs/router/api/router/useRouterHook.md
diff --git a/docs/router/framework/react/api/router/useRouterStateHook.md b/docs/router/api/router/useRouterStateHook.md
similarity index 100%
rename from docs/router/framework/react/api/router/useRouterStateHook.md
rename to docs/router/api/router/useRouterStateHook.md
diff --git a/docs/router/framework/react/api/router/useSearchHook.md b/docs/router/api/router/useSearchHook.md
similarity index 100%
rename from docs/router/framework/react/api/router/useSearchHook.md
rename to docs/router/api/router/useSearchHook.md
diff --git a/docs/router/framework/react/comparison.md b/docs/router/comparison.md
similarity index 97%
rename from docs/router/framework/react/comparison.md
rename to docs/router/comparison.md
index a6b61e59f0..84a2119162 100644
--- a/docs/router/framework/react/comparison.md
+++ b/docs/router/comparison.md
@@ -1,5 +1,5 @@
 ---
-title: Comparison | TanStack Router & TanStack Start vs Next.js vs React Router / Remix
+title: Comparison
 toc: false
 ---
 
@@ -17,6 +17,12 @@ Feature/Capability Key:
 - 🔶 Possible, but requires custom code/implementation/casting
 - 🛑 Not officially supported
 
+<!-- ::start:framework -->
+
+# React
+
+## Comparison | TanStack Router & TanStack Start vs Next.js vs React Router / Remix
+
 |                                                | TanStack Router / Start                          | React Router DOM [_(Website)_][router]                | Next.JS [_(Website)_][nextjs]                         |
 | ---------------------------------------------- | ------------------------------------------------ | ----------------------------------------------------- | ----------------------------------------------------- |
 | Github Repo / Stars                            | [![][stars-tanstack-router]][gh-tanstack-router] | [![][stars-router]][gh-router]                        | [![][stars-nextjs]][gh-nextjs]                        |
@@ -94,3 +100,11 @@ Feature/Capability Key:
 [gh-nextjs]: https://github.com/vercel/next.js
 [stars-nextjs]: https://img.shields.io/github/stars/vercel/next.js?label=%F0%9F%8C%9F
 [bpl-nextjs]: https://bundlephobia.com/result?p=next
+
+# Solid
+
+---
+
+We don't have a comparison table for Solid just yet. If you're interested in helping us create one, please reach out in the [TanStack Discord](https://tanstack.com/discord) or open a PR with your proposed comparison!
+
+<!-- ::end:framework -->
diff --git a/docs/router/config.json b/docs/router/config.json
index 808c3fe38f..2957e04035 100644
--- a/docs/router/config.json
+++ b/docs/router/config.json
@@ -8,103 +8,79 @@
   "sections": [
     {
       "label": "Getting Started",
-      "children": [],
+      "children": [
+        {
+          "label": "Overview",
+          "to": "overview"
+        },
+        {
+          "label": "Quick Start",
+          "to": "quick-start"
+        },
+        {
+          "label": "Devtools",
+          "to": "devtools"
+        },
+        {
+          "label": "Decisions on DX",
+          "to": "decisions-on-dx"
+        },
+        {
+          "label": "LLM Assistance Support",
+          "to": "llm-support"
+        },
+        {
+          "label": "Comparison",
+          "to": "comparison"
+        },
+        {
+          "label": "Frequently Asked Questions",
+          "to": "faq"
+        }
+      ],
       "frameworks": [
         {
           "label": "react",
-          "children": [
-            {
-              "label": "Overview",
-              "to": "framework/react/overview"
-            },
-            {
-              "label": "Quick Start",
-              "to": "framework/react/quick-start"
-            },
-            {
-              "label": "Devtools",
-              "to": "framework/react/devtools"
-            },
-            {
-              "label": "Decisions on DX",
-              "to": "framework/react/decisions-on-dx"
-            },
-            {
-              "label": "LLM Assistance Support",
-              "to": "framework/react/llm-support"
-            },
-            {
-              "label": "Comparison",
-              "to": "framework/react/comparison"
-            },
-            {
-              "label": "Frequently Asked Questions",
-              "to": "framework/react/faq"
-            }
-          ]
+          "children": []
         },
         {
           "label": "solid",
-          "children": [
-            {
-              "label": "Overview",
-              "to": "framework/solid/overview"
-            },
-            {
-              "label": "Quick Start",
-              "to": "framework/solid/quick-start"
-            },
-            {
-              "label": "Devtools",
-              "to": "framework/solid/devtools"
-            },
-            {
-              "label": "Decisions on DX",
-              "to": "framework/solid/decisions-on-dx"
-            },
-            {
-              "label": "LLM Assistance Support",
-              "to": "framework/solid/llm-support"
-            },
-            {
-              "label": "Frequently Asked Questions",
-              "to": "framework/solid/faq"
-            }
-          ]
+          "children": []
         }
       ]
     },
     {
       "label": "Installation Guides",
-      "children": [],
+      "children": [
+        {
+          "label": "Manual Setup",
+          "to": "installation/manual"
+        },
+        {
+          "label": "Vite",
+          "to": "installation/with-vite"
+        },
+        {
+          "label": "Rspack/Rsbuild",
+          "to": "installation/with-rspack"
+        },
+        {
+          "label": "Webpack",
+          "to": "installation/with-webpack"
+        },
+        {
+          "label": "Esbuild",
+          "to": "installation/with-esbuild"
+        },
+        {
+          "label": "Router CLI",
+          "to": "installation/with-router-cli"
+        }
+      ],
       "frameworks": [
         {
           "label": "react",
           "children": [
-            {
-              "label": "Manual Setup",
-              "to": "framework/react/installation/manual"
-            },
-            {
-              "label": "Vite",
-              "to": "framework/react/installation/with-vite"
-            },
-            {
-              "label": "Rspack/Rsbuild",
-              "to": "framework/react/installation/with-rspack"
-            },
-            {
-              "label": "Webpack",
-              "to": "framework/react/installation/with-webpack"
-            },
-            {
-              "label": "Esbuild",
-              "to": "framework/react/installation/with-esbuild"
-            },
-            {
-              "label": "Router CLI",
-              "to": "framework/react/installation/with-router-cli"
-            },
             {
               "label": "Migrate from React Router",
               "to": "framework/react/installation/migrate-from-react-router"
@@ -117,334 +93,187 @@
         },
         {
           "label": "solid",
-          "children": [
-            {
-              "label": "Manual Setup",
-              "to": "framework/solid/installation/manual"
-            },
-            {
-              "label": "Vite",
-              "to": "framework/solid/installation/with-vite"
-            },
-            {
-              "label": "Router CLI",
-              "to": "framework/solid/installation/with-router-cli"
-            }
-          ]
+          "children": []
         }
       ]
     },
     {
       "label": "Routing",
-      "children": [],
+      "children": [
+        {
+          "label": "Routing Concepts",
+          "to": "routing/routing-concepts"
+        },
+        {
+          "label": "Route Trees",
+          "to": "routing/route-trees"
+        },
+        {
+          "label": "Route Matching",
+          "to": "routing/route-matching"
+        },
+        {
+          "label": "File-Based Routing",
+          "to": "routing/file-based-routing"
+        },
+        {
+          "label": "Virtual File Routes",
+          "to": "routing/virtual-file-routes"
+        },
+        {
+          "label": "Code-Based Routing",
+          "to": "routing/code-based-routing"
+        },
+        {
+          "label": "File Naming Conventions",
+          "to": "routing/file-naming-conventions"
+        }
+      ],
       "frameworks": [
         {
           "label": "react",
-          "children": [
-            {
-              "label": "Routing Concepts",
-              "to": "framework/react/routing/routing-concepts"
-            },
-            {
-              "label": "Route Trees",
-              "to": "framework/react/routing/route-trees"
-            },
-            {
-              "label": "Route Matching",
-              "to": "framework/react/routing/route-matching"
-            },
-            {
-              "label": "File-Based Routing",
-              "to": "framework/react/routing/file-based-routing"
-            },
-            {
-              "label": "Virtual File Routes",
-              "to": "framework/react/routing/virtual-file-routes"
-            },
-            {
-              "label": "Code-Based Routing",
-              "to": "framework/react/routing/code-based-routing"
-            },
-            {
-              "label": "File Naming Conventions",
-              "to": "framework/react/routing/file-naming-conventions"
-            }
-          ]
+          "children": []
         },
         {
           "label": "solid",
-          "children": [
-            {
-              "label": "Routing Concepts",
-              "to": "framework/solid/routing/routing-concepts"
-            },
-            {
-              "label": "Route Trees",
-              "to": "framework/solid/routing/route-trees"
-            },
-            {
-              "label": "Route Matching",
-              "to": "framework/solid/routing/route-matching"
-            },
-            {
-              "label": "File-Based Routing",
-              "to": "framework/solid/routing/file-based-routing"
-            },
-            {
-              "label": "Virtual File Routes",
-              "to": "framework/solid/routing/virtual-file-routes"
-            },
-            {
-              "label": "Code-Based Routing",
-              "to": "framework/solid/routing/code-based-routing"
-            },
-            {
-              "label": "File Naming Conventions",
-              "to": "framework/solid/routing/file-naming-conventions"
-            }
-          ]
+          "children": []
         }
       ]
     },
     {
       "label": "Guides",
-      "children": [],
+      "children": [
+        {
+          "label": "Code Splitting",
+          "to": "guide/code-splitting"
+        },
+        {
+          "label": "Automatic Code Splitting",
+          "to": "guide/automatic-code-splitting"
+        },
+        {
+          "label": "Creating a Router",
+          "to": "guide/creating-a-router"
+        },
+        {
+          "label": "Outlets",
+          "to": "guide/outlets"
+        },
+        {
+          "label": "Navigation",
+          "to": "guide/navigation"
+        },
+        {
+          "label": "Path Params",
+          "to": "guide/path-params"
+        },
+        {
+          "label": "Search Params",
+          "to": "guide/search-params"
+        },
+        {
+          "label": "Link Options",
+          "to": "guide/link-options"
+        },
+        {
+          "label": "Custom Links",
+          "to": "guide/custom-link"
+        },
+        {
+          "label": "Data Loading",
+          "to": "guide/data-loading"
+        },
+        {
+          "label": "Deferred Data Loading",
+          "to": "guide/deferred-data-loading"
+        },
+        {
+          "label": "External Data Loading",
+          "to": "guide/external-data-loading"
+        },
+        {
+          "label": "Data Mutations",
+          "to": "guide/data-mutations"
+        },
+        {
+          "label": "Type Safety",
+          "to": "guide/type-safety"
+        },
+        {
+          "label": "Type Utilities",
+          "to": "guide/type-utilities"
+        },
+        {
+          "label": "Preloading",
+          "to": "guide/preloading"
+        },
+        {
+          "label": "Document Head Management",
+          "to": "guide/document-head-management"
+        },
+        {
+          "label": "Route Masking",
+          "to": "guide/route-masking"
+        },
+        {
+          "label": "Navigation Blocking",
+          "to": "guide/navigation-blocking"
+        },
+        {
+          "label": "Custom Search Param Serialization",
+          "to": "guide/custom-search-param-serialization"
+        },
+        {
+          "label": "History Types",
+          "to": "guide/history-types"
+        },
+        {
+          "label": "Router Context",
+          "to": "guide/router-context"
+        },
+        {
+          "label": "Not Found Errors",
+          "to": "guide/not-found-errors"
+        },
+        {
+          "label": "Authenticated Routes",
+          "to": "guide/authenticated-routes"
+        },
+        {
+          "label": "Scroll Restoration",
+          "to": "guide/scroll-restoration"
+        },
+        {
+          "label": "Static Route Data",
+          "to": "guide/static-route-data"
+        },
+        {
+          "label": "SSR",
+          "to": "guide/ssr"
+        },
+        {
+          "label": "Render Optimizations",
+          "to": "guide/render-optimizations"
+        }
+      ],
       "frameworks": [
         {
           "label": "react",
-          "children": [
-            {
-              "label": "Code Splitting",
-              "to": "framework/react/guide/code-splitting"
-            },
-            {
-              "label": "Automatic Code Splitting",
-              "to": "framework/react/guide/automatic-code-splitting"
-            },
-            {
-              "label": "Creating a Router",
-              "to": "framework/react/guide/creating-a-router"
-            },
-            {
-              "label": "Outlets",
-              "to": "framework/react/guide/outlets"
-            },
-            {
-              "label": "Navigation",
-              "to": "framework/react/guide/navigation"
-            },
-            {
-              "label": "Path Params",
-              "to": "framework/react/guide/path-params"
-            },
-            {
-              "label": "Search Params",
-              "to": "framework/react/guide/search-params"
-            },
-            {
-              "label": "Link Options",
-              "to": "framework/react/guide/link-options"
-            },
-            {
-              "label": "Custom Links",
-              "to": "framework/react/guide/custom-link"
-            },
-            {
-              "label": "Data Loading",
-              "to": "framework/react/guide/data-loading"
-            },
-            {
-              "label": "Deferred Data Loading",
-              "to": "framework/react/guide/deferred-data-loading"
-            },
-            {
-              "label": "External Data Loading",
-              "to": "framework/react/guide/external-data-loading"
-            },
-            {
-              "label": "Data Mutations",
-              "to": "framework/react/guide/data-mutations"
-            },
-            {
-              "label": "Type Safety",
-              "to": "framework/react/guide/type-safety"
-            },
-            {
-              "label": "Type Utilities",
-              "to": "framework/react/guide/type-utilities"
-            },
-            {
-              "label": "Preloading",
-              "to": "framework/react/guide/preloading"
-            },
-            {
-              "label": "Document Head Management",
-              "to": "framework/react/guide/document-head-management"
-            },
-            {
-              "label": "Route Masking",
-              "to": "framework/react/guide/route-masking"
-            },
-            {
-              "label": "Navigation Blocking",
-              "to": "framework/react/guide/navigation-blocking"
-            },
-            {
-              "label": "Custom Search Param Serialization",
-              "to": "framework/react/guide/custom-search-param-serialization"
-            },
-            {
-              "label": "History Types",
-              "to": "framework/react/guide/history-types"
-            },
-            {
-              "label": "Router Context",
-              "to": "framework/react/guide/router-context"
-            },
-            {
-              "label": "Not Found Errors",
-              "to": "framework/react/guide/not-found-errors"
-            },
-            {
-              "label": "Authenticated Routes",
-              "to": "framework/react/guide/authenticated-routes"
-            },
-            {
-              "label": "Scroll Restoration",
-              "to": "framework/react/guide/scroll-restoration"
-            },
-            {
-              "label": "Static Route Data",
-              "to": "framework/react/guide/static-route-data"
-            },
-            {
-              "label": "SSR",
-              "to": "framework/react/guide/ssr"
-            },
-            {
-              "label": "Render Optimizations",
-              "to": "framework/react/guide/render-optimizations"
-            }
-          ]
+          "children": []
         },
         {
           "label": "solid",
-          "children": [
-            {
-              "label": "Code Splitting",
-              "to": "framework/solid/guide/code-splitting"
-            },
-            {
-              "label": "Automatic Code Splitting",
-              "to": "framework/solid/guide/automatic-code-splitting"
-            },
-            {
-              "label": "Creating a Router",
-              "to": "framework/solid/guide/creating-a-router"
-            },
-            {
-              "label": "Outlets",
-              "to": "framework/solid/guide/outlets"
-            },
-            {
-              "label": "Navigation",
-              "to": "framework/solid/guide/navigation"
-            },
-            {
-              "label": "Path Params",
-              "to": "framework/solid/guide/path-params"
-            },
-            {
-              "label": "Search Params",
-              "to": "framework/solid/guide/search-params"
-            },
-            {
-              "label": "Link Options",
-              "to": "framework/solid/guide/link-options"
-            },
-            {
-              "label": "Custom Links",
-              "to": "framework/solid/guide/custom-link"
-            },
-            {
-              "label": "Data Loading",
-              "to": "framework/solid/guide/data-loading"
-            },
-            {
-              "label": "Deferred Data Loading",
-              "to": "framework/solid/guide/deferred-data-loading"
-            },
-            {
-              "label": "External Data Loading",
-              "to": "framework/solid/guide/external-data-loading"
-            },
-            {
-              "label": "Data Mutations",
-              "to": "framework/solid/guide/data-mutations"
-            },
-            {
-              "label": "Type Safety",
-              "to": "framework/solid/guide/type-safety"
-            },
-            {
-              "label": "Type Utilities",
-              "to": "framework/solid/guide/type-utilities"
-            },
-            {
-              "label": "Preloading",
-              "to": "framework/solid/guide/preloading"
-            },
-            {
-              "label": "Document Head Management",
-              "to": "framework/solid/guide/document-head-management"
-            },
-            {
-              "label": "Route Masking",
-              "to": "framework/solid/guide/route-masking"
-            },
-            {
-              "label": "Navigation Blocking",
-              "to": "framework/solid/guide/navigation-blocking"
-            },
-            {
-              "label": "Custom Search Param Serialization",
-              "to": "framework/solid/guide/custom-search-param-serialization"
-            },
-            {
-              "label": "History Types",
-              "to": "framework/solid/guide/history-types"
-            },
-            {
-              "label": "Router Context",
-              "to": "framework/solid/guide/router-context"
-            },
-            {
-              "label": "Not Found Errors",
-              "to": "framework/solid/guide/not-found-errors"
-            },
-            {
-              "label": "Authenticated Routes",
-              "to": "framework/solid/guide/authenticated-routes"
-            },
-            {
-              "label": "Scroll Restoration",
-              "to": "framework/solid/guide/scroll-restoration"
-            },
-            {
-              "label": "Static Route Data",
-              "to": "framework/solid/guide/static-route-data"
-            },
-            {
-              "label": "SSR",
-              "to": "framework/solid/guide/ssr"
-            }
-          ]
+          "children": []
         }
       ]
     },
     {
       "label": "API",
       "children": [
+        {
+          "label": "Router",
+          "to": "api/router"
+        },
         {
           "label": "File-Based Routing",
           "to": "api/file-based-routing"
@@ -453,12 +282,7 @@
       "frameworks": [
         {
           "label": "react",
-          "children": [
-            {
-              "label": "Router",
-              "to": "framework/react/api/router"
-            }
-          ]
+          "children": []
         },
         {
           "label": "solid",
@@ -468,16 +292,16 @@
     },
     {
       "label": "Integrations",
-      "children": [],
+      "children": [
+        {
+          "label": "TanStack Query",
+          "to": "integrations/query"
+        }
+      ],
       "frameworks": [
         {
           "label": "react",
-          "children": [
-            {
-              "label": "TanStack Query",
-              "to": "integrations/query"
-            }
-          ]
+          "children": []
         },
         {
           "label": "solid",
diff --git a/docs/router/framework/react/decisions-on-dx.md b/docs/router/decisions-on-dx.md
similarity index 96%
rename from docs/router/framework/react/decisions-on-dx.md
rename to docs/router/decisions-on-dx.md
index cdc82ec3bb..26c366a9da 100644
--- a/docs/router/framework/react/decisions-on-dx.md
+++ b/docs/router/decisions-on-dx.md
@@ -14,9 +14,12 @@ And they are all valid questions. For the most part, people are used to using ro
 
 But TanStack Router is different. It's not your average routing library. It's not your average state management library. It's not your average anything.
 
+> [!TIP]
+> The examples in this guide use React for components and code snippets, but the same principles apply to Solid. The only difference is in the syntax and API of the framework, but the underlying concepts and design decisions are the same.
+
 ## TanStack Router's origin story
 
-It's important to remember that TanStack Router's origins stem from [Nozzle.io](https://nozzle.io)'s need for a client-side routing solution that offered a first-in-class _URL Search Parameters_ experience without compromising on the **_type-safety_** that was required to power its complex dashboards.
+It's important to remember that TanStack Router's origins stem from [Nozzle.io](https://nozzle.io?utm_source=tanstack)'s need for a client-side routing solution that offered a first-in-class _URL Search Parameters_ experience without compromising on the **_type-safety_** that was required to power its complex dashboards.
 
 And so, from TanStack Router's very inception, every facet of its design was meticulously thought out to ensure that its type-safety and developer experience were second to none.
 
diff --git a/docs/router/framework/react/devtools.md b/docs/router/devtools.md
similarity index 65%
rename from docs/router/framework/react/devtools.md
rename to docs/router/devtools.md
index a3992cfd60..1ad33fb7a6 100644
--- a/docs/router/framework/react/devtools.md
+++ b/docs/router/devtools.md
@@ -12,48 +12,66 @@ When you begin your TanStack Router journey, you'll want these devtools by your
 
 The devtools are a separate package that you need to install:
 
-```sh
-npm install @tanstack/react-router-devtools
-```
+<!-- ::start:tabs variant="package-manager" -->
 
-or
+react: @tanstack/react-router-devtools
+solid: @tanstack/solid-router-devtools
 
-```sh
-pnpm add @tanstack/react-router-devtools
-```
+<!-- ::end:tabs -->
 
-or
+## Import the Devtools
 
-```sh
-yarn add @tanstack/react-router-devtools
-```
+<!-- ::start:framework -->
 
-or
+# React
 
-```sh
-bun add @tanstack/react-router-devtools
+```tsx
+import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
 ```
 
-## Import the Devtools
+# Solid
 
-```js
-import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
+```tsx
+import { TanStackRouterDevtools } from '@tanstack/solid-router-devtools'
 ```
 
+<!-- ::end:framework -->
+
 ## Using Devtools in production
 
 The Devtools, if imported as `TanStackRouterDevtools` will not be shown in production. If you want to have devtools in an environment with `process.env.NODE_ENV === 'production'`, use instead `TanStackRouterDevtoolsInProd`, which has all the same options:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { TanStackRouterDevtoolsInProd } from '@tanstack/react-router-devtools'
 ```
 
-## Using inside of the `RouterProvider`
+# Solid
+
+```tsx
+import { TanStackRouterDevtoolsInProd } from '@tanstack/solid-router-devtools'
+```
+
+<!-- ::end:framework -->
+
+## Using the Devtools in the root route
 
 The easiest way for the devtools to work is to render them inside of your root route (or any other route). This will automatically connect the devtools to the router instance.
 
-```tsx
-const rootRoute = createRootRoute({
+<!-- ::start:framework -->
+
+# React
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/routes/__root.tsx"
+import { createRootRoute, Outlet } from '@tanstack/react-router'
+import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
+
+export const Route = createRootRoute({
   component: () => (
     <>
       <Outlet />
@@ -61,24 +79,40 @@ const rootRoute = createRootRoute({
     </>
   ),
 })
+```
 
-const routeTree = rootRoute.addChildren([
-  // ... other routes
-])
+<!-- ::end:tabs -->
 
-const router = createRouter({
-  routeTree,
-})
+# Solid
 
-function App() {
-  return <RouterProvider router={router} />
-}
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/routes/__root.tsx"
+import { createRootRoute, Outlet } from '@tanstack/solid-router'
+import { TanStackRouterDevtools } from '@tanstack/solid-router-devtools'
+
+export const Route = createRootRoute({
+  component: () => (
+    <>
+      <Outlet />
+      <TanStackRouterDevtools />
+    </>
+  ),
+})
 ```
 
+<!-- ::end:tabs -->
+
+<!-- ::end:framework -->
+
 ## Manually passing the Router Instance
 
 If rendering the devtools inside of the `RouterProvider` isn't your cup of tea, a `router` prop for the devtools accepts the same `router` instance you pass to the `Router` component. This makes it possible to place the devtools anywhere on the page, not just inside the provider:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 function App() {
   return (
@@ -90,25 +124,57 @@ function App() {
 }
 ```
 
+# Solid
+
+```tsx
+function App() {
+  return (
+    <>
+      <RouterProvider router={router} />
+      <TanStackRouterDevtools router={router} />
+    </>
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 ## Floating Mode
 
 Floating Mode will mount the devtools as a fixed, floating element in your app and provide a toggle in the corner of the screen to show and hide the devtools. This toggle state will be stored and remembered in localStorage across reloads.
 
-Place the following code as high in your React app as you can. The closer it is to the root of the page, the better it will work!
+Place the following code as high in your app as you can. The closer it is to the root of the page, the better it will work!
 
-```js
-import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
+<!-- ::start:framework -->
+
+# React
+
+```tsx
+function App() {
+  return (
+    <>
+      <RouterProvider router={router} />
+      <TanStackRouterDevtools initialIsOpen={false} />
+    </>
+  )
+}
+```
+
+# Solid
 
+```tsx
 function App() {
   return (
     <>
-      <Router />
+      <RouterProvider router={router} />
       <TanStackRouterDevtools initialIsOpen={false} />
     </>
   )
 }
 ```
 
+<!-- ::end:framework -->
+
 ### Devtools Options
 
 - `router: Router`
@@ -136,32 +202,63 @@ function App() {
 
 To control the position of the devtools, import the `TanStackRouterDevtoolsPanel`:
 
-```js
+<!-- ::start:framework -->
+
+# React
+
+```tsx
 import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools'
 ```
 
+# Solid
+
+```tsx
+import { TanStackRouterDevtoolsPanel } from '@tanstack/solid-router-devtools'
+```
+
+<!-- ::end:framework -->
+
 It can then be attached to provided shadow DOM target:
 
-```js
+<!-- ::start:framework -->
+
+# React
+
+```tsx
+<TanStackRouterDevtoolsPanel
+  shadowDOMTarget={shadowContainer}
+  router={router}
+/>
+```
+
+# Solid
+
+```tsx
 <TanStackRouterDevtoolsPanel
   shadowDOMTarget={shadowContainer}
   router={router}
 />
 ```
 
+<!-- ::end:framework -->
+
 Click [here](https://tanstack.com/router/latest/docs/framework/react/examples/basic-devtools-panel) to see a live example of this in StackBlitz.
 
 ## Embedded Mode
 
 Embedded Mode will embed the devtools as a regular component in your application. You can style it however you'd like after that!
 
-```js
+<!-- ::start:framework -->
+
+# React
+
+```tsx
 import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools'
 
 function App() {
   return (
     <>
-      <Router router={router} />
+      <RouterProvider router={router} />
       <TanStackRouterDevtoolsPanel
         router={router}
         style={styles}
@@ -172,14 +269,50 @@ function App() {
 }
 ```
 
+# Solid
+
+```tsx
+import { TanStackRouterDevtoolsPanel } from '@tanstack/solid-router-devtools'
+
+function App() {
+  return (
+    <>
+      <RouterProvider router={router} />
+      <TanStackRouterDevtoolsPanel
+        router={router}
+        style={styles}
+        class={className}
+      />
+    </>
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 ### DevtoolsPanel Options
 
 - `router: Router`
   - The router instance to connect to.
-- `style: StyleObject`
+
+<!-- ::start:framework -->
+
+# React
+
+- `style?: StyleObject`
   - The standard React style object used to style a component with inline styles.
-- `className: string`
+- `className?: string`
   - The standard React className property used to style a component with classes.
+
+# Solid
+
+- `style?: StyleObject`
+  - The standard Solid style object used to style a component with inline styles.
+- `class?: string`
+  - The standard Solid class property used to style a component with classes.
+
+<!-- ::end:framework -->
+
 - `isOpen?: boolean`
   - A boolean variable indicating whether the panel is open or closed.
 - `setIsOpen?: (isOpen: boolean) => void`
diff --git a/docs/router/eslint/create-route-property-order.md b/docs/router/eslint/create-route-property-order.md
index c3fe8aa0b8..d568666186 100644
--- a/docs/router/eslint/create-route-property-order.md
+++ b/docs/router/eslint/create-route-property-order.md
@@ -25,7 +25,13 @@ All other properties are insensitive to the order as they do not depend on type
 
 Examples of **incorrect** code for this rule:
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/routes/path.tsx"
 /* eslint "@tanstack/router/create-route-property-order": "warn" */
 import { createFileRoute } from '@tanstack/react-router'
 
@@ -37,9 +43,37 @@ export const Route = createFileRoute('/path')({
 })
 ```
 
+<!-- ::end:tabs -->
+
+# Solid
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/routes/path.tsx"
+/* eslint "@tanstack/router/create-route-property-order": "warn" */
+import { createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/path')({
+  loader: async ({context}) => {
+    await context.queryClient.ensureQueryData(getQueryOptions(context.hello)),
+  },
+  beforeLoad: () => ({hello: 'world'})
+})
+```
+
+<!-- ::end:tabs -->
+
+<!-- ::end:framework -->
+
 Examples of **correct** code for this rule:
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/routes/path.tsx"
 /* eslint "@tanstack/router/create-route-property-order": "warn" */
 import { createFileRoute } from '@tanstack/react-router'
 
@@ -51,6 +85,28 @@ export const Route = createFileRoute('/path')({
 })
 ```
 
+<!-- ::end:tabs -->
+
+# Solid
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/routes/path.tsx"
+/* eslint "@tanstack/router/create-route-property-order": "warn" */
+import { createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/path')({
+  beforeLoad: () => ({hello: 'world'}),
+  loader: async ({context}) => {
+    await context.queryClient.ensureQueryData(getQueryOptions(context.hello)),
+  }
+})
+```
+
+<!-- ::end:tabs -->
+
+<!-- ::end:framework -->
+
 ## Attributes
 
 - [x] ✅ Recommended
diff --git a/docs/router/eslint/eslint-plugin-router.md b/docs/router/eslint/eslint-plugin-router.md
index 6db567a777..b355a83a25 100644
--- a/docs/router/eslint/eslint-plugin-router.md
+++ b/docs/router/eslint/eslint-plugin-router.md
@@ -9,27 +9,12 @@ TanStack Router comes with its own ESLint plugin. This plugin is used to enforce
 
 The plugin is a separate package that you need to install:
 
-```sh
-npm install -D @tanstack/eslint-plugin-router
-```
-
-or
-
-```sh
-pnpm add -D @tanstack/eslint-plugin-router
-```
-
-or
-
-```sh
-yarn add -D @tanstack/eslint-plugin-router
-```
+<!-- ::start:tabs variant="package-manager" mode="dev-install" -->
 
-or
+react: @tanstack/eslint-plugin-router
+solid: @tanstack/eslint-plugin-router
 
-```sh
-bun add -D @tanstack/eslint-plugin-router
-```
+<!-- ::end:tabs -->
 
 ## Flat Config (`eslint.config.js`)
 
@@ -40,8 +25,9 @@ The release of ESLint 9.0 introduced a new way to configure ESLint using a flat
 
 To enable all of the recommended rules for our plugin, add the following config:
 
-```js
-// eslint.config.js
+<!-- ::start:tabs variant="files" -->
+
+```js title="eslint.config.js"
 import pluginRouter from '@tanstack/eslint-plugin-router'
 
 export default [
@@ -50,12 +36,15 @@ export default [
 ]
 ```
 
+<!-- ::end:tabs -->
+
 ### Custom Flat Config setup
 
 Alternatively, you can load the plugin and configure only the rules you want to use:
 
-```js
-// eslint.config.js
+<!-- ::start:tabs variant="files" -->
+
+```js title="eslint.config.js"
 import pluginRouter from '@tanstack/eslint-plugin-router'
 
 export default [
@@ -71,6 +60,8 @@ export default [
 ]
 ```
 
+<!-- ::end:tabs -->
+
 ## Legacy Config (`.eslintrc`)
 
 Prior to the ESLint 9.0 release, the most common way of configuring EsLint was using a `.eslintrc` file. The TanStack Router ESLint Plugin still supports this configuration method.
diff --git a/docs/router/framework/react/faq.md b/docs/router/faq.md
similarity index 86%
rename from docs/router/framework/react/faq.md
rename to docs/router/faq.md
index a7c0887298..3d51140a0a 100644
--- a/docs/router/framework/react/faq.md
+++ b/docs/router/faq.md
@@ -27,7 +27,6 @@ You should commit this file into git so that other developers can use it to buil
 ## Can I conditionally render the Root Route component?
 
 No, the root route is always rendered as it is the entry point of your application.
-
 If you need to conditionally render a route's component, this usually means that the page content needs to be different based on some condition (e.g. user authentication). For this use case, you should use a [Layout Route](./routing/routing-concepts.md#layout-routes) or a [Pathless Layout Route](./routing/routing-concepts.md#pathless-layout-routes) to conditionally render the content.
 
 You can restrict access to these routes using a conditional check in the `beforeLoad` function of the route.
@@ -35,6 +34,10 @@ You can restrict access to these routes using a conditional check in the `before
 <details>
 <summary>What does this look like?</summary>
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 // src/routes/_pathless-layout.tsx
 import { createFileRoute, Outlet } from '@tanstack/react-router'
@@ -63,4 +66,36 @@ function PathlessLayoutRouteComponent() {
 }
 ```
 
+# Solid
+
+```tsx
+// src/routes/_pathless-layout.tsx
+import { createFileRoute, Outlet } from '@tanstack/solid-router'
+import { isAuthenticated } from '../utils/auth'
+
+export const Route = createFileRoute('/_pathless-layout', {
+  beforeLoad: async () => {
+    // Check if the user is authenticated
+    const authed = await isAuthenticated()
+    if (!authed) {
+      // Redirect the user to the login page
+      return '/login'
+    }
+  },
+  component: PathlessLayoutRouteComponent,
+  // ...
+})
+
+function PathlessLayoutRouteComponent() {
+  return (
+    <div>
+      <h1>You are authed</h1>
+      <Outlet />
+    </div>
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 </details>
diff --git a/docs/router/framework/react/installation/migrate-from-react-location.md b/docs/router/framework/react/installation/migrate-from-react-location.md
index dada1bf9d6..788b6c71a7 100644
--- a/docs/router/framework/react/installation/migrate-from-react-location.md
+++ b/docs/router/framework/react/installation/migrate-from-react-location.md
@@ -2,27 +2,27 @@
 title: Migration from React Location
 ---
 
-Before you begin your journey in migrating from React Location, it's important that you have a good understanding of the [Routing Concepts](../routing/routing-concepts.md) and [Design Decisions](../decisions-on-dx.md) used by TanStack Router.
+Before you begin your journey in migrating from React Location, it's important that you have a good understanding of the [Routing Concepts](../../../routing/routing-concepts.md) and [Design Decisions](../../../decisions-on-dx.md) used by TanStack Router.
 
 ## Differences between React Location and TanStack Router
 
 React Location and TanStack Router share much of same design decisions concepts, but there are some key differences that you should be aware of.
 
 - React Location uses _generics_ to infer types for routes, while TanStack Router uses _module declaration merging_ to infer types.
-- Route configuration in React Location is done using a single array of route definitions, while in TanStack Router, route configuration is done using a tree of route definitions starting with the [root route](../routing/routing-concepts.md#the-root-route).
-- [File-based routing](../routing/file-based-routing.md) is the recommended way to define routes in TanStack Router, while React Location only allows you to define routes in a single file using a code-based approach.
-  - TanStack Router does support a [code-based approach](../routing/code-based-routing.md) to defining routes, but it is not recommended for most use cases. You can read more about why, over here: [why is file-based routing the preferred way to define routes?](../decisions-on-dx.md#why-is-file-based-routing-the-preferred-way-to-define-routes)
+- Route configuration in React Location is done using a single array of route definitions, while in TanStack Router, route configuration is done using a tree of route definitions starting with the [root route](../../../routing/routing-concepts.md#the-root-route).
+- [File-based routing](../../../routing/file-based-routing.md) is the recommended way to define routes in TanStack Router, while React Location only allows you to define routes in a single file using a code-based approach.
+  - TanStack Router does support a [code-based approach](../../../routing/code-based-routing.md) to defining routes, but it is not recommended for most use cases. You can read more about why, over here: [why is file-based routing the preferred way to define routes?](../../../decisions-on-dx.md#why-is-file-based-routing-the-preferred-way-to-define-routes)
 
 ## Migration guide
 
 In this guide we'll go over the process of migrating the [React Location Basic example](https://github.com/TanStack/router/tree/react-location/examples/basic) over to TanStack Router using file-based routing, with the end goal of having the same functionality as the original example (styling and other non-routing related code will be omitted).
 
 > [!TIP]
-> To use a code-based approach for defining your routes, you can read the [code-based Routing](../routing/code-based-routing.md) guide.
+> To use a code-based approach for defining your routes, you can read the [code-based Routing](../../../routing/code-based-routing.md) guide.
 
 ### Step 1: Swap over to TanStack Router's dependencies
 
-First, we need to install the dependencies for TanStack Router. For detailed installation instructions, see our [How to Install TanStack Router](../how-to/install.md) guide.
+First, we need to install the dependencies for TanStack Router. For detailed installation instructions, see our [How to Install TanStack Router](../../../how-to/install.md) guide.
 
 ```sh
 npm install @tanstack/react-router @tanstack/router-devtools
@@ -57,7 +57,7 @@ export default defineConfig({
 })
 ```
 
-However, if your application does not use Vite, you use one of our other [supported bundlers](../routing/file-based-routing.md#getting-started-with-file-based-routing), or you can use the `@tanstack/router-cli` package to watch for changes in your routes files and automatically update the routes configuration.
+However, if your application does not use Vite, you use one of our other [supported bundlers](../../../routing/file-based-routing.md#getting-started-with-file-based-routing), or you can use the `@tanstack/router-cli` package to watch for changes in your routes files and automatically update the routes configuration.
 
 ### Step 3: Add the file-based configuration file to your project
 
@@ -70,7 +70,7 @@ Create a `tsr.config.json` file in the root of your project with the following c
 }
 ```
 
-You can find the full list of options for the `tsr.config.json` file [here](../routing/file-based-routing.md).
+You can find the full list of options for the `tsr.config.json` file [here](../../../routing/file-based-routing.md).
 
 ### Step 4: Create the routes directory
 
@@ -249,19 +249,19 @@ You should now have successfully migrated your application from React Location t
 
 React Location also has a few more features that you might be using in your application. Here are some guides to help you migrate those features:
 
-- [Search params](../guide/search-params.md)
-- [Data loading](../guide/data-loading.md)
-- [History types](../guide/history-types.md)
-- [Wildcard / Splat / Catch-all routes](../routing/routing-concepts.md#splat--catch-all-routes)
-- [Authenticated routes](../guide/authenticated-routes.md)
+- [Search params](../../../guide/search-params.md)
+- [Data loading](../../../guide/data-loading.md)
+- [History types](../../../guide/history-types.md)
+- [Wildcard / Splat / Catch-all routes](../../../routing/routing-concepts.md#splat--catch-all-routes)
+- [Authenticated routes](../../../guide/authenticated-routes.md)
 
 TanStack Router also has a few more features that you might want to explore:
 
-- [Router Context](../guide/router-context.md)
-- [Preloading](../guide/preloading.md)
-- [Pathless Layout Routes](../routing/routing-concepts.md#pathless-layout-routes)
-- [Route masking](../guide/route-masking.md)
-- [SSR](../guide/ssr.md)
+- [Router Context](../../../guide/router-context.md)
+- [Preloading](../../../guide/preloading.md)
+- [Pathless Layout Routes](../../../routing/routing-concepts.md#pathless-layout-routes)
+- [Route masking](../../../guide/route-masking.md)
+- [SSR](../../../guide/ssr.md)
 - ... and more!
 
 If you are facing any issues or have any questions, feel free to ask for help in the TanStack Discord.
diff --git a/docs/router/framework/react/installation/migrate-from-react-router.md b/docs/router/framework/react/installation/migrate-from-react-router.md
index 6903673bf7..9e6cb618ae 100644
--- a/docs/router/framework/react/installation/migrate-from-react-router.md
+++ b/docs/router/framework/react/installation/migrate-from-react-router.md
@@ -7,7 +7,7 @@ toc: false
 
 Here is the [example repo](https://github.com/Benanna2019/SickFitsForEveryone/tree/migrate-to-tanstack/router/React-Router)
 
-- [ ] Install Router - `npm i @tanstack/react-router` (see [detailed installation guide](../how-to/install.md))
+- [ ] Install Router - `npm i @tanstack/react-router` (see [detailed installation guide](../../../how-to/install.md))
 - [ ] **Optional:** Uninstall React Router to get TypeScript errors on imports.
   - At this point I don’t know if you can do a gradual migration, but it seems likely you could have multiple router providers, not desirable.
   - The api’s between React Router and TanStack Router are very similar and could most likely be handled in a sprint cycle or two if that is your companies way of doing things.
diff --git a/docs/router/framework/react/installation/with-esbuild.md b/docs/router/framework/react/installation/with-esbuild.md
deleted file mode 100644
index 63219f73a2..0000000000
--- a/docs/router/framework/react/installation/with-esbuild.md
+++ /dev/null
@@ -1,82 +0,0 @@
----
-title: Installation with Esbuild
----
-
-[//]: # 'BundlerConfiguration'
-
-To use file-based routing with **Esbuild**, you'll need to install the `@tanstack/router-plugin` package.
-
-```sh
-npm install -D @tanstack/router-plugin
-```
-
-Once installed, you'll need to add the plugin to your configuration.
-
-```tsx
-// esbuild.config.js
-import { tanstackRouter } from '@tanstack/router-plugin/esbuild'
-
-export default {
-  // ...
-  plugins: [
-    tanstackRouter({
-      target: 'react',
-      autoCodeSplitting: true,
-    }),
-  ],
-}
-```
-
-Or, you can clone our [Quickstart Esbuild example](https://github.com/TanStack/router/tree/main/examples/react/quickstart-esbuild-file-based) and get started.
-
-Now that you've added the plugin to your Esbuild configuration, you're all set to start using file-based routing with TanStack Router.
-
-[//]: # 'BundlerConfiguration'
-
-## Ignoring the generated route tree file
-
-If your project is configured to use a linter and/or formatter, you may want to ignore the generated route tree file. This file is managed by TanStack Router and therefore shouldn't be changed by your linter or formatter.
-
-Here are some resources to help you ignore the generated route tree file:
-
-- Prettier - [https://prettier.io/docs/en/ignore.html#ignoring-files-prettierignore](https://prettier.io/docs/en/ignore.html#ignoring-files-prettierignore)
-- ESLint - [https://eslint.org/docs/latest/use/configure/ignore#ignoring-files](https://eslint.org/docs/latest/use/configure/ignore#ignoring-files)
-- Biome - [https://biomejs.dev/reference/configuration/#filesignore](https://biomejs.dev/reference/configuration/#filesignore)
-
-> [!WARNING]
-> If you are using VSCode, you may experience the route tree file unexpectedly open (with errors) after renaming a route.
-
-You can prevent that from the VSCode settings by marking the file as readonly. Our recommendation is to also exclude it from search results and file watcher with the following settings:
-
-```json
-{
-  "files.readonlyInclude": {
-    "**/routeTree.gen.ts": true
-  },
-  "files.watcherExclude": {
-    "**/routeTree.gen.ts": true
-  },
-  "search.exclude": {
-    "**/routeTree.gen.ts": true
-  }
-}
-```
-
-You can use those settings either at a user level or only for a single workspace by creating the file `.vscode/settings.json` at the root of your project.
-
-## Configuration
-
-When using the TanStack Router Plugin with Esbuild for File-based routing, it comes with some sane defaults that should work for most projects:
-
-```json
-{
-  "routesDirectory": "./src/routes",
-  "generatedRouteTree": "./src/routeTree.gen.ts",
-  "routeFileIgnorePrefix": "-",
-  "quoteStyle": "single"
-}
-```
-
-If these defaults work for your project, you don't need to configure anything at all! However, if you need to customize the configuration, you can do so by editing the configuration object passed into the `tanstackRouter` function.
-
-You can find all the available configuration options in the [File-based Routing API Reference](../../../api/file-based-routing.md).
diff --git a/docs/router/framework/react/installation/with-rspack.md b/docs/router/framework/react/installation/with-rspack.md
deleted file mode 100644
index 1a0b0afcd7..0000000000
--- a/docs/router/framework/react/installation/with-rspack.md
+++ /dev/null
@@ -1,88 +0,0 @@
----
-title: Installation with Rspack
----
-
-[//]: # 'BundlerConfiguration'
-
-To use file-based routing with **Rspack** or **Rsbuild**, you'll need to install the `@tanstack/router-plugin` package.
-
-```sh
-npm install -D @tanstack/router-plugin
-```
-
-Once installed, you'll need to add the plugin to your configuration.
-
-```tsx
-// rsbuild.config.ts
-import { defineConfig } from '@rsbuild/core'
-import { pluginReact } from '@rsbuild/plugin-react'
-import { tanstackRouter } from '@tanstack/router-plugin/rspack'
-
-export default defineConfig({
-  plugins: [pluginReact()],
-  tools: {
-    rspack: {
-      plugins: [
-        tanstackRouter({
-          target: 'react',
-          autoCodeSplitting: true,
-        }),
-      ],
-    },
-  },
-})
-```
-
-Or, you can clone our [Quickstart Rspack/Rsbuild example](https://github.com/TanStack/router/tree/main/examples/react/quickstart-rspack-file-based) and get started.
-
-Now that you've added the plugin to your Rspack/Rsbuild configuration, you're all set to start using file-based routing with TanStack Router.
-
-[//]: # 'BundlerConfiguration'
-
-## Ignoring the generated route tree file
-
-If your project is configured to use a linter and/or formatter, you may want to ignore the generated route tree file. This file is managed by TanStack Router and therefore shouldn't be changed by your linter or formatter.
-
-Here are some resources to help you ignore the generated route tree file:
-
-- Prettier - [https://prettier.io/docs/en/ignore.html#ignoring-files-prettierignore](https://prettier.io/docs/en/ignore.html#ignoring-files-prettierignore)
-- ESLint - [https://eslint.org/docs/latest/use/configure/ignore#ignoring-files](https://eslint.org/docs/latest/use/configure/ignore#ignoring-files)
-- Biome - [https://biomejs.dev/reference/configuration/#filesignore](https://biomejs.dev/reference/configuration/#filesignore)
-
-> [!WARNING]
-> If you are using VSCode, you may experience the route tree file unexpectedly open (with errors) after renaming a route.
-
-You can prevent that from the VSCode settings by marking the file as readonly. Our recommendation is to also exclude it from search results and file watcher with the following settings:
-
-```json
-{
-  "files.readonlyInclude": {
-    "**/routeTree.gen.ts": true
-  },
-  "files.watcherExclude": {
-    "**/routeTree.gen.ts": true
-  },
-  "search.exclude": {
-    "**/routeTree.gen.ts": true
-  }
-}
-```
-
-You can use those settings either at a user level or only for a single workspace by creating the file `.vscode/settings.json` at the root of your project.
-
-## Configuration
-
-When using the TanStack Router Plugin with Rspack (or Rsbuild) for File-based routing, it comes with some sane defaults that should work for most projects:
-
-```json
-{
-  "routesDirectory": "./src/routes",
-  "generatedRouteTree": "./src/routeTree.gen.ts",
-  "routeFileIgnorePrefix": "-",
-  "quoteStyle": "single"
-}
-```
-
-If these defaults work for your project, you don't need to configure anything at all! However, if you need to customize the configuration, you can do so by editing the configuration object passed into the `tanstackRouter` function.
-
-You can find all the available configuration options in the [File-based Routing API Reference](../../../api/file-based-routing.md).
diff --git a/docs/router/framework/react/installation/with-webpack.md b/docs/router/framework/react/installation/with-webpack.md
deleted file mode 100644
index 5ec487e439..0000000000
--- a/docs/router/framework/react/installation/with-webpack.md
+++ /dev/null
@@ -1,81 +0,0 @@
----
-title: Installation with Webpack
----
-
-[//]: # 'BundlerConfiguration'
-
-To use file-based routing with **Webpack**, you'll need to install the `@tanstack/router-plugin` package.
-
-```sh
-npm install -D @tanstack/router-plugin
-```
-
-Once installed, you'll need to add the plugin to your configuration.
-
-```tsx
-// webpack.config.ts
-import { tanstackRouter } from '@tanstack/router-plugin/webpack'
-
-export default {
-  plugins: [
-    tanstackRouter({
-      target: 'react',
-      autoCodeSplitting: true,
-    }),
-  ],
-}
-```
-
-Or, you can clone our [Quickstart Webpack example](https://github.com/TanStack/router/tree/main/examples/react/quickstart-webpack-file-based) and get started.
-
-Now that you've added the plugin to your Webpack configuration, you're all set to start using file-based routing with TanStack Router.
-
-[//]: # 'BundlerConfiguration'
-
-## Ignoring the generated route tree file
-
-If your project is configured to use a linter and/or formatter, you may want to ignore the generated route tree file. This file is managed by TanStack Router and therefore shouldn't be changed by your linter or formatter.
-
-Here are some resources to help you ignore the generated route tree file:
-
-- Prettier - [https://prettier.io/docs/en/ignore.html#ignoring-files-prettierignore](https://prettier.io/docs/en/ignore.html#ignoring-files-prettierignore)
-- ESLint - [https://eslint.org/docs/latest/use/configure/ignore#ignoring-files](https://eslint.org/docs/latest/use/configure/ignore#ignoring-files)
-- Biome - [https://biomejs.dev/reference/configuration/#filesignore](https://biomejs.dev/reference/configuration/#filesignore)
-
-> [!WARNING]
-> If you are using VSCode, you may experience the route tree file unexpectedly open (with errors) after renaming a route.
-
-You can prevent that from the VSCode settings by marking the file as readonly. Our recommendation is to also exclude it from search results and file watcher with the following settings:
-
-```json
-{
-  "files.readonlyInclude": {
-    "**/routeTree.gen.ts": true
-  },
-  "files.watcherExclude": {
-    "**/routeTree.gen.ts": true
-  },
-  "search.exclude": {
-    "**/routeTree.gen.ts": true
-  }
-}
-```
-
-You can use those settings either at a user level or only for a single workspace by creating the file `.vscode/settings.json` at the root of your project.
-
-## Configuration
-
-When using the TanStack Router Plugin with Webpack for File-based routing, it comes with some sane defaults that should work for most projects:
-
-```json
-{
-  "routesDirectory": "./src/routes",
-  "generatedRouteTree": "./src/routeTree.gen.ts",
-  "routeFileIgnorePrefix": "-",
-  "quoteStyle": "single"
-}
-```
-
-If these defaults work for your project, you don't need to configure anything at all! However, if you need to customize the configuration, you can do so by editing the configuration object passed into the `tanstackRouter` function.
-
-You can find all the available configuration options in the [File-based Routing API Reference](../../../api/file-based-routing.md).
diff --git a/docs/router/framework/solid/decisions-on-dx.md b/docs/router/framework/solid/decisions-on-dx.md
deleted file mode 100644
index ab5f466f1f..0000000000
--- a/docs/router/framework/solid/decisions-on-dx.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/decisions-on-dx.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/devtools.md b/docs/router/framework/solid/devtools.md
deleted file mode 100644
index e0414970ec..0000000000
--- a/docs/router/framework/solid/devtools.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-title: Devtools
-ref: docs/router/framework/react/devtools.md
-replace:
-  {
-    'react-router-devtools': 'solid-router-devtools',
-    'React': 'Solid',
-    'className': 'class',
-    'react/examples/basic-devtools-panel': 'solid/examples/basic-devtools-panel',
-  }
----
diff --git a/docs/router/framework/solid/faq.md b/docs/router/framework/solid/faq.md
deleted file mode 100644
index 38784ec02f..0000000000
--- a/docs/router/framework/solid/faq.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/faq.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/guide/authenticated-routes.md b/docs/router/framework/solid/guide/authenticated-routes.md
deleted file mode 100644
index 9f97e14882..0000000000
--- a/docs/router/framework/solid/guide/authenticated-routes.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-ref: docs/router/framework/react/guide/authenticated-routes.md
-replace:
-  {
-    'react-router': 'solid-router',
-    'auth.isAuthenticated': 'auth.isAuthenticated()',
-    'react': 'solid',
-  }
----
diff --git a/docs/router/framework/solid/guide/automatic-code-splitting.md b/docs/router/framework/solid/guide/automatic-code-splitting.md
deleted file mode 100644
index cd4802869b..0000000000
--- a/docs/router/framework/solid/guide/automatic-code-splitting.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/guide/automatic-code-splitting.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/guide/code-splitting.md b/docs/router/framework/solid/guide/code-splitting.md
deleted file mode 100644
index 2581c14240..0000000000
--- a/docs/router/framework/solid/guide/code-splitting.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/guide/code-splitting.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/guide/creating-a-router.md b/docs/router/framework/solid/guide/creating-a-router.md
deleted file mode 100644
index b4b826b739..0000000000
--- a/docs/router/framework/solid/guide/creating-a-router.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/guide/creating-a-router.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/guide/custom-link.md b/docs/router/framework/solid/guide/custom-link.md
deleted file mode 100644
index a859e2a6ad..0000000000
--- a/docs/router/framework/solid/guide/custom-link.md
+++ /dev/null
@@ -1,46 +0,0 @@
----
-ref: docs/router/framework/react/guide/custom-link.md
-replace: { 'react-router': 'solid-router' }
----
-
-[//]: # 'BasicExampleImplementation'
-
-```tsx
-import * as Solid from 'solid-js'
-import { createLink, LinkComponent } from '@tanstack/solid-router'
-
-export const Route = createRootRoute({
-  component: RootComponent,
-})
-
-type BasicLinkProps = Solid.JSX.IntrinsicElements['a'] & {
-  // Add any additional props you want to pass to the anchor element
-}
-
-const BasicLinkComponent: Solid.Component<BasicLinkProps> = (props) => (
-  <a {...props} class="block px-3 py-2 text-red-700">
-    {props.children}
-  </a>
-)
-
-const CreatedLinkComponent = createLink(BasicLinkComponent)
-
-export const CustomLink: LinkComponent<typeof BasicLinkComponent> = (props) => {
-  return <CreatedLinkComponent preload={'intent'} {...props} />
-}
-```
-
-[//]: # 'BasicExampleImplementation'
-[//]: # 'ExamplesUsingThirdPartyLibs'
-
-## `createLink` with third party libraries
-
-Here are some examples of how you can use `createLink` with third-party libraries.
-
-### Some Library example
-
-```tsx
-// TODO: Add this example.
-```
-
-[//]: # 'ExamplesUsingThirdPartyLibs'
diff --git a/docs/router/framework/solid/guide/custom-search-param-serialization.md b/docs/router/framework/solid/guide/custom-search-param-serialization.md
deleted file mode 100644
index c8f5bcd762..0000000000
--- a/docs/router/framework/solid/guide/custom-search-param-serialization.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/guide/custom-search-param-serialization.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/guide/data-loading.md b/docs/router/framework/solid/guide/data-loading.md
deleted file mode 100644
index b10e5d0953..0000000000
--- a/docs/router/framework/solid/guide/data-loading.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/guide/data-loading.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/guide/data-mutations.md b/docs/router/framework/solid/guide/data-mutations.md
deleted file mode 100644
index 7070f8a214..0000000000
--- a/docs/router/framework/solid/guide/data-mutations.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/guide/data-mutations.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/guide/deferred-data-loading.md b/docs/router/framework/solid/guide/deferred-data-loading.md
deleted file mode 100644
index 3d25b32324..0000000000
--- a/docs/router/framework/solid/guide/deferred-data-loading.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-ref: docs/router/framework/react/guide/deferred-data-loading.md
-replace: { 'react-router': 'solid-router', 'react-query': 'solid-query' }
----
-
-[//]: # 'DeferredWithAwaitFinalTip'
-[//]: # 'DeferredWithAwaitFinalTip'
-[//]: # 'SSRContent'
-[//]: # 'SSRContent'
diff --git a/docs/router/framework/solid/guide/document-head-management.md b/docs/router/framework/solid/guide/document-head-management.md
deleted file mode 100644
index 1f5f7f40d7..0000000000
--- a/docs/router/framework/solid/guide/document-head-management.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/guide/document-head-management.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/guide/external-data-loading.md b/docs/router/framework/solid/guide/external-data-loading.md
deleted file mode 100644
index 8913149651..0000000000
--- a/docs/router/framework/solid/guide/external-data-loading.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/guide/external-data-loading.md
-replace: { 'react-router': 'solid-router', 'react-query': 'solid-query' }
----
diff --git a/docs/router/framework/solid/guide/history-types.md b/docs/router/framework/solid/guide/history-types.md
deleted file mode 100644
index 6dbfe4f6ac..0000000000
--- a/docs/router/framework/solid/guide/history-types.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/guide/history-types.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/guide/link-options.md b/docs/router/framework/solid/guide/link-options.md
deleted file mode 100644
index 83270f5075..0000000000
--- a/docs/router/framework/solid/guide/link-options.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/guide/link-options.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/guide/navigation-blocking.md b/docs/router/framework/solid/guide/navigation-blocking.md
deleted file mode 100644
index e3491cf362..0000000000
--- a/docs/router/framework/solid/guide/navigation-blocking.md
+++ /dev/null
@@ -1,157 +0,0 @@
----
-ref: docs/router/framework/react/guide/navigation-blocking.md
-replace: { 'react-router': 'solid-router' }
----
-
-[//]: # 'HookBasedBlockingExample'
-
-```tsx
-import { useBlocker } from '@tanstack/solid-router'
-
-function MyComponent() {
-  const [formIsDirty, setFormIsDirty] = createSignal(false)
-
-  useBlocker({
-    shouldBlockFn: () => {
-      if (!formIsDirty()) return false
-
-      const shouldLeave = confirm('Are you sure you want to leave?')
-      return !shouldLeave
-    },
-  })
-
-  // ...
-}
-```
-
-[//]: # 'HookBasedBlockingExample'
-[//]: # 'ComponentBasedBlockingExample'
-
-```tsx
-import { Block } from '@tanstack/solid-router'
-
-function MyComponent() {
-  const [formIsDirty, setFormIsDirty] = createSignal(false)
-
-  return (
-    <Block
-      shouldBlockFn={() => {
-        if (!formIsDirty()) return false
-
-        const shouldLeave = confirm('Are you sure you want to leave?')
-        return !shouldLeave
-      }}
-    />
-  )
-
-  // OR
-
-  return (
-    <Block shouldBlockFn={() => !formIsDirty} withResolver>
-      {({ status, proceed, reset }) => <>{/* ... */}</>}
-    </Block>
-  )
-}
-```
-
-[//]: # 'ComponentBasedBlockingExample'
-[//]: # 'HookBasedCustomUIBlockingWithResolverExample'
-
-```tsx
-import { useBlocker } from '@tanstack/solid-router'
-
-function MyComponent() {
-  const [formIsDirty, setFormIsDirty] = createSignal(false)
-
-  const { proceed, reset, status } = useBlocker({
-    shouldBlockFn: () => formIsDirty(),
-    withResolver: true,
-  })
-
-  // ...
-
-  return (
-    <>
-      {/* ... */}
-      {status === 'blocked' && (
-        <div>
-          <p>Are you sure you want to leave?</p>
-          <button onClick={proceed}>Yes</button>
-          <button onClick={reset}>No</button>
-        </div>
-      )}
-    </>
-}
-```
-
-[//]: # 'HookBasedCustomUIBlockingWithResolverExample'
-[//]: # 'HookBasedCustomUIBlockingWithoutResolverExample'
-
-```tsx
-import { useBlocker } from '@tanstack/solid-router'
-
-function MyComponent() {
-  const [formIsDirty, setFormIsDirty] = createSignal(false)
-
-  useBlocker({
-    shouldBlockFn: () => {
-      if (!formIsDirty()) {
-        return false
-      }
-
-      const shouldBlock = new Promise<boolean>((resolve) => {
-        // Using a modal manager of your choice
-        modals.open({
-          title: 'Are you sure you want to leave?',
-          children: (
-            <SaveBlocker
-              confirm={() => {
-                modals.closeAll()
-                resolve(false)
-              }}
-              reject={() => {
-                modals.closeAll()
-                resolve(true)
-              }}
-            />
-          ),
-          onClose: () => resolve(true),
-        })
-      })
-      return shouldBlock
-    },
-  })
-
-  // ...
-}
-```
-
-[//]: # 'HookBasedCustomUIBlockingWithoutResolverExample'
-[//]: # 'ComponentBasedCustomUIBlockingExample'
-
-```tsx
-import { Block } from '@tanstack/solid-router'
-
-function MyComponent() {
-  const [formIsDirty, setFormIsDirty] = createSignal(false)
-
-  return (
-    <Block shouldBlockFn={() => formIsDirty()} withResolver>
-      {({ status, proceed, reset }) => (
-        <>
-          {/* ... */}
-          {status === 'blocked' && (
-            <div>
-              <p>Are you sure you want to leave?</p>
-              <button onClick={proceed}>Yes</button>
-              <button onClick={reset}>No</button>
-            </div>
-          )}
-        </>
-      )}
-    </Block>
-  )
-}
-```
-
-[//]: # 'ComponentBasedCustomUIBlockingExample'
diff --git a/docs/router/framework/solid/guide/navigation.md b/docs/router/framework/solid/guide/navigation.md
deleted file mode 100644
index 12f132a02f..0000000000
--- a/docs/router/framework/solid/guide/navigation.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/guide/navigation.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/guide/not-found-errors.md b/docs/router/framework/solid/guide/not-found-errors.md
deleted file mode 100644
index 0ab152da2a..0000000000
--- a/docs/router/framework/solid/guide/not-found-errors.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/guide/not-found-errors.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/guide/outlets.md b/docs/router/framework/solid/guide/outlets.md
deleted file mode 100644
index e340e6bdfe..0000000000
--- a/docs/router/framework/solid/guide/outlets.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/guide/outlets.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/guide/path-params.md b/docs/router/framework/solid/guide/path-params.md
deleted file mode 100644
index 7851e94bd8..0000000000
--- a/docs/router/framework/solid/guide/path-params.md
+++ /dev/null
@@ -1,769 +0,0 @@
----
-title: Path Params
----
-
-Path params are used to match a single segment (the text until the next `/`) and provide its value back to you as a **named** variable. They are defined by using the `$` character prefix in the path, followed by the key variable to assign it to. The following are valid path param paths:
-
-- `$postId`
-- `$name`
-- `$teamId`
-- `about/$name`
-- `team/$teamId`
-- `blog/$postId`
-
-Because path param routes only match to the next `/`, child routes can be created to continue expressing hierarchy:
-
-Let's create a post route file that uses a path param to match the post ID:
-
-- `posts.$postId.tsx`
-
-```tsx
-import { createFileRoute } from '@tanstack/solid-router'
-
-export const Route = createFileRoute('/posts/$postId')({
-  loader: async ({ params }) => {
-    return fetchPost(params.postId)
-  },
-})
-```
-
-## Path Params can be used by child routes
-
-Once a path param has been parsed, it is available to all child routes. This means that if we define a child route to our `postRoute`, we can use the `postId` variable from the URL in the child route's path!
-
-## Path Params in Loaders
-
-Path params are passed to the loader as a `params` object. The keys of this object are the names of the path params, and the values are the values that were parsed out of the actual URL path. For example, if we were to visit the `/blog/123` URL, the `params` object would be `{ postId: '123' }`:
-
-```tsx
-export const Route = createFileRoute('/posts/$postId')({
-  loader: async ({ params }) => {
-    return fetchPost(params.postId)
-  },
-})
-```
-
-The `params` object is also passed to the `beforeLoad` option:
-
-```tsx
-export const Route = createFileRoute('/posts/$postId')({
-  beforeLoad: async ({ params }) => {
-    // do something with params.postId
-  },
-})
-```
-
-## Path Params in Components
-
-If we add a component to our `postRoute`, we can access the `postId` variable from the URL by using the route's `useParams` hook:
-
-```tsx
-export const Route = createFileRoute('/posts/$postId')({
-  component: PostComponent,
-})
-
-function PostComponent() {
-  const params = Route.useParams()
-  return <div>Post {params().postId}</div>
-}
-```
-
-> 🧠 Quick tip: If your component is code-split, you can use the [getRouteApi function](./code-splitting.md#manually-accessing-route-apis-in-other-files-with-the-getrouteapi-helper) to avoid having to import the `Route` configuration to get access to the typed `useParams()` hook.
-
-## Path Params outside of Routes
-
-You can also use the globally exported `useParams` hook to access any parsed path params from any component in your app. You'll need to pass the `strict: false` option to `useParams`, denoting that you want to access the params from an ambiguous location:
-
-```tsx
-function PostComponent() {
-  const params = useParams({ strict: false })
-  return <div>Post {params().postId}</div>
-}
-```
-
-## Navigating with Path Params
-
-When navigating to a route with path params, TypeScript will require you to pass the params either as an object or as a function that returns an object of params.
-
-Let's see what an object style looks like:
-
-```tsx
-function Component() {
-  return (
-    <Link to="/blog/$postId" params={{ postId: '123' }}>
-      Post 123
-    </Link>
-  )
-}
-```
-
-And here's what a function style looks like:
-
-```tsx
-function Component() {
-  return (
-    <Link to="/blog/$postId" params={(prev) => ({ ...prev, postId: '123' })}>
-      Post 123
-    </Link>
-  )
-}
-```
-
-Notice that the function style is useful when you need to persist params that are already in the URL for other routes. This is because the function style will receive the current params as an argument, allowing you to modify them as needed and return the final params object.
-
-## Prefixes and Suffixes for Path Params
-
-You can also use **prefixes** and **suffixes** with path params to create more complex routing patterns. This allows you to match specific URL structures while still capturing the dynamic segments.
-
-When using either prefixes or suffixes, you can define them by wrapping the path param in curly braces `{}` and placing the prefix or suffix before or after the variable name.
-
-### Defining Prefixes
-
-Prefixes are defined by placing the prefix text outside the curly braces before the variable name. For example, if you want to match a URL that starts with `post-` followed by a post ID, you can define it like this:
-
-```tsx
-// src/routes/posts/post-{$postId}.tsx
-export const Route = createFileRoute('/posts/post-{$postId}')({
-  component: PostComponent,
-})
-
-function PostComponent() {
-  const params = Route.useParams()
-  // postId will be the value after 'post-'
-  return <div>Post ID: {params().postId}</div>
-}
-```
-
-You can even combines prefixes with wildcard routes to create more complex patterns:
-
-```tsx
-// src/routes/on-disk/storage-{$}
-export const Route = createFileRoute('/on-disk/storage-{$postId}/$')({
-  component: StorageComponent,
-})
-
-function StorageComponent() {
-  const params = Route.useParams()
-  // _splat, will be value after 'storage-'
-  // i.e. my-drive/documents/foo.txt
-  return <div>Storage Location: /{params()._splat}</div>
-}
-```
-
-### Defining Suffixes
-
-Suffixes are defined by placing the suffix text outside the curly braces after the variable name. For example, if you want to match a URL a filename that ends with `txt`, you can define it like this:
-
-```tsx
-// src/routes/files/{$fileName}txt
-export const Route = createFileRoute('/files/{$fileName}.txt')({
-  component: FileComponent,
-})
-
-function FileComponent() {
-  const params = Route.useParams()
-  // fileName will be the value before 'txt'
-  return <div>File Name: {params().fileName}</div>
-}
-```
-
-You can also combine suffixes with wildcards for more complex routing patterns:
-
-```tsx
-// src/routes/files/{$}[.]txt
-export const Route = createFileRoute('/files/{$fileName}[.]txt')({
-  component: FileComponent,
-})
-
-function FileComponent() {
-  const params = Route.useParams()
-  // _splat will be the value before '.txt'
-  return <div>File Splat: {params()._splat}</div>
-}
-```
-
-### Combining Prefixes and Suffixes
-
-You can combine both prefixes and suffixes to create very specific routing patterns. For example, if you want to match a URL that starts with `user-` and ends with `.json`, you can define it like this:
-
-```tsx
-// src/routes/users/user-{$userId}.json
-export const Route = createFileRoute('/users/user-{$userId}.json')({
-  component: UserComponent,
-})
-
-function UserComponent() {
-  const params = Route.useParams()
-  // userId will be the value between 'user-' and '.json'
-  return <div>User ID: {params().userId}</div>
-}
-```
-
-Similar to the previous examples, you can also use wildcards with prefixes and suffixes. Go wild!
-
-## Optional Path Parameters
-
-Optional path parameters allow you to define route segments that may or may not be present in the URL. They use the `{-$paramName}` syntax and provide flexible routing patterns where certain parameters are optional.
-
-### Defining Optional Parameters
-
-Optional path parameters are defined using curly braces with a dash prefix: `{-$paramName}`
-
-```tsx
-// Single optional parameter
-// src/routes/posts/{-$category}.tsx
-export const Route = createFileRoute('/posts/{-$category}')({
-  component: PostsComponent,
-})
-
-// Multiple optional parameters
-// src/routes/posts/{-$category}/{-$slug}.tsx
-export const Route = createFileRoute('/posts/{-$category}/{-$slug}')({
-  component: PostComponent,
-})
-
-// Mixed required and optional parameters
-// src/routes/users/$id/{-$tab}.tsx
-export const Route = createFileRoute('/users/$id/{-$tab}')({
-  component: UserComponent,
-})
-```
-
-### How Optional Parameters Work
-
-Optional parameters create flexible URL patterns:
-
-- `/posts/{-$category}` matches both `/posts` and `/posts/tech`
-- `/posts/{-$category}/{-$slug}` matches `/posts`, `/posts/tech`, and `/posts/tech/hello-world`
-- `/users/$id/{-$tab}` matches `/users/123` and `/users/123/settings`
-
-When an optional parameter is not present in the URL, its value will be `undefined` in your route handlers and components.
-
-### Accessing Optional Parameters
-
-Optional parameters work exactly like regular parameters in your components, but their values may be `undefined`:
-
-```tsx
-function PostsComponent() {
-  const params = Route.useParams()
-
-  return (
-    <div>
-      {params().category ? `Posts in ${params().category}` : 'All Posts'}
-    </div>
-  )
-}
-```
-
-### Optional Parameters in Loaders
-
-Optional parameters are available in loaders and may be `undefined`:
-
-```tsx
-export const Route = createFileRoute('/posts/{-$category}')({
-  loader: async ({ params }) => {
-    // params.category might be undefined
-    return fetchPosts({ category: params.category })
-  },
-})
-```
-
-### Optional Parameters in beforeLoad
-
-Optional parameters work in `beforeLoad` handlers as well:
-
-```tsx
-export const Route = createFileRoute('/posts/{-$category}')({
-  beforeLoad: async ({ params }) => {
-    if (params.category) {
-      // Validate category exists
-      await validateCategory(params.category)
-    }
-  },
-})
-```
-
-### Advanced Optional Parameter Patterns
-
-#### With Prefix and Suffix
-
-Optional parameters support prefix and suffix patterns:
-
-```tsx
-// File route: /files/prefix{-$name}.txt
-// Matches: /files/prefix.txt and /files/prefixdocument.txt
-export const Route = createFileRoute('/files/prefix{-$name}.txt')({
-  component: FileComponent,
-})
-
-function FileComponent() {
-  const params = Route.useParams()
-  return <div>File: {params().name || 'default'}</div>
-}
-```
-
-#### All Optional Parameters
-
-You can create routes where all parameters are optional:
-
-```tsx
-// Route: /{-$year}/{-$month}/{-$day}
-// Matches: /, /2023, /2023/12, /2023/12/25
-export const Route = createFileRoute('/{-$year}/{-$month}/{-$day}')({
-  component: DateComponent,
-})
-
-function DateComponent() {
-  const params = Route.useParams()
-
-  if (!params().year) return <div>Select a year</div>
-  if (!params().month) return <div>Year: {params().year}</div>
-  if (!params().day)
-    return (
-      <div>
-        Month: {params().year}/{params().month}
-      </div>
-    )
-
-  return (
-    <div>
-      Date: {params().year}/{params().month}/{params().day}
-    </div>
-  )
-}
-```
-
-#### Optional Parameters with Wildcards
-
-Optional parameters can be combined with wildcards for complex routing patterns:
-
-```tsx
-// Route: /docs/{-$version}/$
-// Matches: /docs/extra/path, /docs/v2/extra/path
-export const Route = createFileRoute('/docs/{-$version}/$')({
-  component: DocsComponent,
-})
-
-function DocsComponent() {
-  const params = Route.useParams()
-
-  return (
-    <div>
-      Version: {params().version || 'latest'}
-      Path: {params()._splat}
-    </div>
-  )
-}
-```
-
-### Navigating with Optional Parameters
-
-When navigating to routes with optional parameters, you have fine-grained control over which parameters to include:
-
-```tsx
-function Navigation() {
-  return (
-    <div>
-      {/* Navigate with optional parameter */}
-      <Link to="/posts/{-$category}" params={{ category: 'tech' }}>
-        Tech Posts
-      </Link>
-
-      {/* Navigate without optional parameter */}
-      <Link to="/posts/{-$category}" params={{ category: undefined }}>
-        All Posts
-      </Link>
-
-      {/* Navigate with multiple optional parameters */}
-      <Link
-        to="/posts/{-$category}/{-$slug}"
-        params={{ category: 'tech', slug: 'solid-tips' }}
-      >
-        Specific Post
-      </Link>
-    </div>
-  )
-}
-```
-
-### Type Safety with Optional Parameters
-
-TypeScript provides full type safety for optional parameters:
-
-```tsx
-function PostsComponent() {
-	// TypeScript knows category might be undefined
-	const params = Route.useParams() // category: string | undefined
-
-	// Safe navigation
-	const categoryUpper = params().category?.toUpperCase()
-
-	return <div>{categoryUpper || 'All Categories'}</div>
-}
-
-// Navigation is type-safe and flexible
-<Link
-	to="/posts/{-$category}"
-	params={{ category: 'tech' }} // ✅ Valid - string
->
-	Tech Posts
-</Link>
-
-<Link
-	to="/posts/{-$category}"
-	params={{ category: 123 }} // ✅ Valid - number (auto-stringified)
->
-	Category 123
-</Link>
-```
-
-## Internationalization (i18n) with Optional Path Parameters
-
-Optional path parameters are excellent for implementing internationalization (i18n) routing patterns. You can use prefix patterns to handle multiple languages while maintaining clean, SEO-friendly URLs.
-
-### Prefix-based i18n
-
-Use optional language prefixes to support URLs like `/en/about`, `/fr/about`, or just `/about` (default language):
-
-```tsx
-// Route: /{-$locale}/about
-export const Route = createFileRoute('/{-$locale}/about')({
-  component: AboutComponent,
-})
-
-function AboutComponent() {
-  const params = Route.useParams()
-  const currentLocale = params().locale || 'en' // Default to English
-
-  const content = {
-    en: { title: 'About Us', description: 'Learn more about our company.' },
-    fr: {
-      title: 'À Propos',
-      description: 'En savoir plus sur notre entreprise.',
-    },
-    es: {
-      title: 'Acerca de',
-      description: 'Conoce más sobre nuestra empresa.',
-    },
-  }
-
-  return (
-    <div>
-      <h1>{content[currentLocale]?.title}</h1>
-      <p>{content[currentLocale]?.description}</p>
-    </div>
-  )
-}
-```
-
-This pattern matches:
-
-- `/about` (default locale)
-- `/en/about` (explicit English)
-- `/fr/about` (French)
-- `/es/about` (Spanish)
-
-### Complex i18n Patterns
-
-Combine optional parameters for more sophisticated i18n routing:
-
-```tsx
-// Route: /{-$locale}/blog/{-$category}/$slug
-export const Route = createFileRoute('/{-$locale}/blog/{-$category}/$slug')({
-  beforeLoad: async ({ params }) => {
-    const locale = params.locale || 'en'
-    const category = params.category
-
-    // Validate locale and category
-    const validLocales = ['en', 'fr', 'es', 'de']
-    if (locale && !validLocales.includes(locale)) {
-      throw new Error('Invalid locale')
-    }
-
-    return { locale, category }
-  },
-  loader: async ({ params, context }) => {
-    const { locale } = context
-    const { slug, category } = params
-
-    return fetchBlogPost({ slug, category, locale })
-  },
-  component: BlogPostComponent,
-})
-
-function BlogPostComponent() {
-  const params = Route.useParams()
-  const data = Route.useLoaderData()
-
-  return (
-    <article>
-      <h1>{data.title}</h1>
-      <p>
-        Category: {params().category || 'All'} | Language:{' '}
-        {params().locale || 'en'}
-      </p>
-      <div>{data.content}</div>
-    </article>
-  )
-}
-```
-
-This supports URLs like:
-
-- `/blog/tech/my-post` (default locale, tech category)
-- `/fr/blog/my-post` (French, no category)
-- `/en/blog/tech/my-post` (explicit English, tech category)
-- `/es/blog/tecnologia/mi-post` (Spanish, Spanish category)
-
-### Language Navigation
-
-Create language switchers using optional i18n parameters with function-style params:
-
-```tsx
-function LanguageSwitcher() {
-  const currentParams = useParams({ strict: false })
-
-  const languages = [
-    { code: 'en', name: 'English' },
-    { code: 'fr', name: 'Français' },
-    { code: 'es', name: 'Español' },
-  ]
-
-  return (
-    <div className="language-switcher">
-      {languages.map(({ code, name }) => (
-        <Link
-          key={code}
-          to="/{-$locale}/blog/{-$category}/$slug"
-          params={(prev) => ({
-            ...prev,
-            locale: code === 'en' ? undefined : code, // Remove 'en' for clean URLs
-          })}
-          className={currentParams().locale === code ? 'active' : ''}
-        >
-          {name}
-        </Link>
-      ))}
-    </div>
-  )
-}
-```
-
-You can also create more sophisticated language switching logic:
-
-```tsx
-function AdvancedLanguageSwitcher() {
-  const currentParams = useParams({ strict: false })
-
-  const handleLanguageChange = (newLocale: string) => {
-    return (prev: any) => {
-      // Preserve all existing params but update locale
-      const updatedParams = { ...prev }
-
-      if (newLocale === 'en') {
-        // Remove locale for clean English URLs
-        delete updatedParams.locale
-      } else {
-        updatedParams.locale = newLocale
-      }
-
-      return updatedParams
-    }
-  }
-
-  return (
-    <div className="language-switcher">
-      <Link
-        to="/{-$locale}/blog/{-$category}/$slug"
-        params={handleLanguageChange('fr')}
-      >
-        Français
-      </Link>
-
-      <Link
-        to="/{-$locale}/blog/{-$category}/$slug"
-        params={handleLanguageChange('es')}
-      >
-        Español
-      </Link>
-
-      <Link
-        to="/{-$locale}/blog/{-$category}/$slug"
-        params={handleLanguageChange('en')}
-      >
-        English
-      </Link>
-    </div>
-  )
-}
-```
-
-### Advanced i18n with Optional Parameters
-
-Organize i18n routes using optional parameters for flexible locale handling:
-
-```tsx
-// Route structure:
-// routes/
-//   {-$locale}/
-//     index.tsx        // /, /en, /fr
-//     about.tsx        // /about, /en/about, /fr/about
-//     blog/
-//       index.tsx      // /blog, /en/blog, /fr/blog
-//       $slug.tsx      // /blog/post, /en/blog/post, /fr/blog/post
-
-// routes/{-$locale}/index.tsx
-export const Route = createFileRoute('/{-$locale}/')({
-  component: HomeComponent,
-})
-
-function HomeComponent() {
-  const params = Route.useParams()
-  const isRTL = ['ar', 'he', 'fa'].includes(locale || '')
-
-  return (
-    <div dir={isRTL ? 'rtl' : 'ltr'}>
-      <h1>Welcome ({params().locale || 'en'})</h1>
-      {/* Localized content */}
-    </div>
-  )
-}
-```
-
-```tsx
-// routes/{-$locale}/about.tsx
-export const Route = createFileRoute('/{-$locale}/about')({
-  component: AboutComponent,
-})
-```
-
-### SEO and Canonical URLs
-
-Handle SEO for i18n routes properly:
-
-```tsx
-export const Route = createFileRoute('/{-$locale}/products/$id')({
-  component: ProductComponent,
-  head: ({ params, loaderData }) => {
-    const locale = params.locale || 'en'
-    const product = loaderData
-
-    return {
-      title: product.title[locale] || product.title.en,
-      meta: [
-        {
-          name: 'description',
-          content: product.description[locale] || product.description.en,
-        },
-        {
-          property: 'og:locale',
-          content: locale,
-        },
-      ],
-      links: [
-        // Canonical URL (always use default locale format)
-        {
-          rel: 'canonical',
-          href: `https://example.com/products/${params.id}`,
-        },
-        // Alternate language versions
-        {
-          rel: 'alternate',
-          hreflang: 'en',
-          href: `https://example.com/products/${params.id}`,
-        },
-        {
-          rel: 'alternate',
-          hreflang: 'fr',
-          href: `https://example.com/fr/products/${params.id}`,
-        },
-        {
-          rel: 'alternate',
-          hreflang: 'es',
-          href: `https://example.com/es/products/${params.id}`,
-        },
-      ],
-    }
-  },
-})
-```
-
-### Type Safety for i18n
-
-Ensure type safety for your i18n implementations:
-
-```tsx
-// Define supported locales
-type Locale = 'en' | 'fr' | 'es' | 'de'
-
-// Type-safe locale validation
-function validateLocale(locale: string | undefined): locale is Locale {
-	return ['en', 'fr', 'es', 'de'].includes(locale as Locale)
-}
-
-export const Route = createFileRoute('/{-$locale}/shop/{-$category}')({
-	beforeLoad: async ({ params }) => {
-		const { locale } = params
-
-		// Type-safe locale validation
-		if (locale && !validateLocale(locale)) {
-			throw redirect({
-				to: '/shop/{-$category}',
-				params: { category: params.category },
-			})
-		}
-
-		return {
-			locale: (locale as Locale) || 'en',
-			isDefaultLocale: !locale || locale === 'en',
-		}
-	},
-	component: ShopComponent,
-})
-
-function ShopComponent() {
-	const params = Route.useParams()
-	const routeContext = Route.useRouteContext()
-
-	// TypeScript knows locale is Locale | undefined
-	// and we have validated it in beforeLoad
-
-	return (
-		<div>
-			<h1>Shop {params().category ? `- ${params().category}` : ''}</h1>
-			<p>Language: {params().locale || 'en'}</p>
-			{!routeContext().isDefaultLocale && (
-				<Link to="/shop/{-$category}" params={{ params().category }}>
-					View in English
-				</Link>
-			)}
-		</div>
-	)
-}
-```
-
-Optional path parameters provide a powerful and flexible foundation for implementing internationalization in your TanStack Router applications. Whether you prefer prefix-based or combined approaches, you can create clean, SEO-friendly URLs while maintaining excellent developer experience and type safety.
-
-## Allowed Characters
-
-By default, path params are escaped with `encodeURIComponent`. If you want to allow other valid URI characters (e.g. `@` or `+`), you can specify that in your [RouterOptions](../api/router/RouterOptionsType.md#pathparamsallowedcharacters-property).
-
-Example usage:
-
-```tsx
-const router = createRouter({
-  // ...
-  pathParamsAllowedCharacters: ['@'],
-})
-```
-
-The following is the list of accepted allowed characters:
-
-- `;`
-- `:`
-- `@`
-- `&`
-- `=`
-- `+`
-- `$`
-- `,`
diff --git a/docs/router/framework/solid/guide/preloading.md b/docs/router/framework/solid/guide/preloading.md
deleted file mode 100644
index 17ce2de1bb..0000000000
--- a/docs/router/framework/solid/guide/preloading.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/guide/preloading.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/guide/route-masking.md b/docs/router/framework/solid/guide/route-masking.md
deleted file mode 100644
index e72dc199f0..0000000000
--- a/docs/router/framework/solid/guide/route-masking.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/guide/route-masking.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/guide/router-context.md b/docs/router/framework/solid/guide/router-context.md
deleted file mode 100644
index 824a615815..0000000000
--- a/docs/router/framework/solid/guide/router-context.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/guide/router-context.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/guide/scroll-restoration.md b/docs/router/framework/solid/guide/scroll-restoration.md
deleted file mode 100644
index 2326d33fc6..0000000000
--- a/docs/router/framework/solid/guide/scroll-restoration.md
+++ /dev/null
@@ -1,45 +0,0 @@
----
-ref: docs/router/framework/react/guide/scroll-restoration.md
-replace: { 'react-router': 'solid-router' }
----
-
-[//]: # 'ManualRestorationExample'
-
-```tsx
-function Component() {
-  // We need a unique ID for manual scroll restoration on a specific element
-  // It should be as unique as possible for this element across your app
-  const scrollRestorationId = 'myVirtualizedContent'
-
-  // We use that ID to get the scroll entry for this element
-  const scrollEntry = useElementScrollRestoration({
-    id: scrollRestorationId,
-  })
-
-  // Let's use TanStack Virtual to virtualize some content!
-  let virtualizerParentRef: any
-  const virtualizer = createVirtualizer({
-    count: 10000,
-    getScrollElement: () => virtualizerParentRef,
-    estimateSize: () => 100,
-    // We pass the scrollY from the scroll restoration entry to the virtualizer
-    // as the initial offset
-    initialOffset: scrollEntry?.scrollY,
-  })
-
-  return (
-    <div
-      ref={virtualizerParentRef}
-      // We pass the scroll restoration ID to the element
-      // as a custom attribute that will get picked up by the
-      // scroll restoration watcher
-      data-scroll-restoration-id={scrollRestorationId}
-      class="flex-1 border rounded-lg overflow-auto relative"
-    >
-      ...
-    </div>
-  )
-}
-```
-
-[//]: # 'ManualRestorationExample'
diff --git a/docs/router/framework/solid/guide/search-params.md b/docs/router/framework/solid/guide/search-params.md
deleted file mode 100644
index fa3e155483..0000000000
--- a/docs/router/framework/solid/guide/search-params.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/guide/search-params.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/guide/ssr.md b/docs/router/framework/solid/guide/ssr.md
deleted file mode 100644
index 46444ae87c..0000000000
--- a/docs/router/framework/solid/guide/ssr.md
+++ /dev/null
@@ -1,19 +0,0 @@
----
-ref: docs/router/framework/react/guide/ssr.md
-replace: { 'react-router': 'solid-router' }
----
-
-[//]: # 'ClientEntryFileExample'
-
-```tsx
-// src/entry-client.tsx
-import { hydrate } from 'solid-js/web'
-import { RouterClient } from '@tanstack/solid-router/ssr/client'
-import { createRouter } from './router'
-
-const router = createRouter()
-
-hydrate(() => <RouterClient router={router} />, document.body)
-```
-
-[//]: # 'ClientEntryFileExample'
diff --git a/docs/router/framework/solid/guide/static-route-data.md b/docs/router/framework/solid/guide/static-route-data.md
deleted file mode 100644
index e27b65770f..0000000000
--- a/docs/router/framework/solid/guide/static-route-data.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/guide/static-route-data.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/guide/type-safety.md b/docs/router/framework/solid/guide/type-safety.md
deleted file mode 100644
index 4aa41008be..0000000000
--- a/docs/router/framework/solid/guide/type-safety.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/guide/type-safety.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/guide/type-utilities.md b/docs/router/framework/solid/guide/type-utilities.md
deleted file mode 100644
index 525f884a2e..0000000000
--- a/docs/router/framework/solid/guide/type-utilities.md
+++ /dev/null
@@ -1,39 +0,0 @@
----
-ref: docs/router/framework/react/guide/type-utilities.md
-replace:
-  { 'react-router': 'solid-router', 'React.ReactNode': 'Solid.JSX.Element' }
----
-
-[//]: # 'TypeCheckingNavigateOptionsWithValidateNavigateOptionsImpl'
-
-```tsx
-export interface UseConditionalNavigateResult {
-  enable: () => void
-  disable: () => void
-  navigate: () => void
-}
-
-export function useConditionalNavigate<
-  TRouter extends RegisteredRouter,
-  TOptions,
->(
-  navigateOptions: ValidateNavigateOptions<TRouter, TOptions>,
-): UseConditionalNavigateResult
-export function useConditionalNavigate(
-  navigateOptions: ValidateNavigateOptions,
-): UseConditionalNavigateResult {
-  const [enabled, setEnabled] = createSignal(false)
-  const navigate = useNavigate()
-  return {
-    enable: () => setEnabled(true),
-    disable: () => setEnabled(false),
-    navigate: () => {
-      if (enabled) {
-        navigate(navigateOptions)
-      }
-    },
-  }
-}
-```
-
-[//]: # 'TypeCheckingNavigateOptionsWithValidateNavigateOptionsImpl'
diff --git a/docs/router/framework/solid/installation/manual.md b/docs/router/framework/solid/installation/manual.md
deleted file mode 100644
index 0624eac8f3..0000000000
--- a/docs/router/framework/solid/installation/manual.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-title: Manual Setup
-ref: docs/router/framework/react/installation/manual.md
-replace: { 'react-router': 'solid-router' }
----
-
-[//]: # 'Requirements'
-
-- `solid-js`v1.x.x
-
-[//]: # 'Requirements'
diff --git a/docs/router/framework/solid/installation/with-router-cli.md b/docs/router/framework/solid/installation/with-router-cli.md
deleted file mode 100644
index 571ec4678f..0000000000
--- a/docs/router/framework/solid/installation/with-router-cli.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-ref: docs/router/framework/react/installation/with-router-cli.md
----
-
-[//]: # 'AfterScripts'
-
-If you are using TypeScript, you should also add the following options to your `tsconfig.json`:
-
-```json
-{
-  "compilerOptions": {
-    "jsx": "preserve",
-    "jsxImportSource": "solid-js"
-  }
-}
-```
-
-With that, you're all set to start using file-based routing with TanStack Router.
-
-[//]: # 'AfterScripts'
-[//]: # 'TargetConfiguration'
-
-Since you are using Solid, you should add the following to your `tsr.config.json` file:
-
-```json
-{
-  "target": "solid"
-}
-```
-
-[//]: # 'TargetConfiguration'
diff --git a/docs/router/framework/solid/installation/with-vite.md b/docs/router/framework/solid/installation/with-vite.md
deleted file mode 100644
index 6e7085fc43..0000000000
--- a/docs/router/framework/solid/installation/with-vite.md
+++ /dev/null
@@ -1,49 +0,0 @@
----
-ref: docs/router/framework/react/installation/with-vite.md
----
-
-[//]: # 'BundlerConfiguration'
-
-To use file-based routing with **Vite**, you'll need to install the `@tanstack/router-plugin` package.
-
-```sh
-npm install -D @tanstack/router-plugin
-```
-
-Once installed, you'll need to add the plugin to your Vite configuration.
-
-```ts
-// vite.config.ts
-import { defineConfig } from 'vite'
-import solid from 'vite-plugin-solid'
-import { tanstackRouter } from '@tanstack/router-plugin/vite'
-
-// https://vitejs.dev/config/
-export default defineConfig({
-  plugins: [
-    tanstackRouter({
-      target: 'solid',
-      autoCodeSplitting: true,
-    }),
-    solid(),
-    // ...
-  ],
-})
-```
-
-If you are using TypeScript, you should also add the following options to your `tsconfig.json`:
-
-```json
-{
-  "compilerOptions": {
-    "jsx": "preserve",
-    "jsxImportSource": "solid-js"
-  }
-}
-```
-
-Or, you can clone our [Quickstart Vite example](https://github.com/TanStack/router/tree/main/examples/solid/quickstart-file-based) and get started.
-
-Now that you've added the plugin to your Vite configuration, you're all set to start using file-based routing with TanStack Router.
-
-[//]: # 'BundlerConfiguration'
diff --git a/docs/router/framework/solid/llm-support.md b/docs/router/framework/solid/llm-support.md
deleted file mode 100644
index 7e92494073..0000000000
--- a/docs/router/framework/solid/llm-support.md
+++ /dev/null
@@ -1,3 +0,0 @@
----
-ref: docs/router/framework/react/llm-support.md
----
diff --git a/docs/router/framework/solid/overview.md b/docs/router/framework/solid/overview.md
deleted file mode 100644
index 15434efbdc..0000000000
--- a/docs/router/framework/solid/overview.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: Overview
-ref: docs/router/framework/react/overview.md
----
diff --git a/docs/router/framework/solid/quick-start.md b/docs/router/framework/solid/quick-start.md
deleted file mode 100644
index 6a89405e5a..0000000000
--- a/docs/router/framework/solid/quick-start.md
+++ /dev/null
@@ -1,65 +0,0 @@
----
-ref: docs/router/framework/react/quick-start.md
-replace: { 'React': 'Solid', 'react': 'solid' }
----
-
-[//]: # 'createAppCommand'
-
-```sh
-npx create-tsrouter-app@latest --framework solid
-```
-
-[//]: # 'createAppCommand'
-[//]: # 'CLIPrompts'
-
-- File-based or code-based route configuration
-- TypeScript support
-- Toolchain setup
-- Git initialization
-
-[//]: # 'CLIPrompts'
-[//]: # 'createAppCommandFileBased'
-
-```sh
-npx create-tsrouter-app@latest my-app --framework solid --template file-router
-```
-
-[//]: # 'createAppCommandFileBased'
-[//]: # 'createAppCommandCodeBased'
-
-```sh
-npx create-tsrouter-app@latest my-app --framework solid
-```
-
-[//]: # 'createAppCommandCodeBased'
-[//]: # 'Requirements'
-
-- `solid-js` v1.x.x
-
-[//]: # 'Requirements'
-[//]: # 'installCommand'
-
-```sh
-npm install @tanstack/solid-router
-# or
-pnpm add @tanstack/solid-router
-#or
-yarn add @tanstack/solid-router
-# or
-bun add @tanstack/solid-router
-# or
-deno add npm:@tanstack/solid-router
-```
-
-[//]: # 'installCommand'
-[//]: # 'packageJson'
-
-```json
-{
-  "dependencies": {
-    "@tanstack/solid-router": "^x.x.x"
-  }
-}
-```
-
-[//]: # 'packageJson'
diff --git a/docs/router/framework/solid/routing/code-based-routing.md b/docs/router/framework/solid/routing/code-based-routing.md
deleted file mode 100644
index d85d52ad47..0000000000
--- a/docs/router/framework/solid/routing/code-based-routing.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/routing/code-based-routing.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/routing/file-based-routing.md b/docs/router/framework/solid/routing/file-based-routing.md
deleted file mode 100644
index e759ac98bf..0000000000
--- a/docs/router/framework/solid/routing/file-based-routing.md
+++ /dev/null
@@ -1,54 +0,0 @@
----
-ref: docs/router/framework/react/routing/file-based-routing.md
-replace: { 'react-router': 'solid-router' }
----
-
-[//]: # 'SupportedBundlersList'
-
-- [Configuration with Vite](#configuration-with-vite)
-
-[//]: # 'SupportedBundlersList'
-[//]: # 'ConfigurationBundlerVite'
-
-### Configuration with Vite
-
-To use file-based routing with **Vite**, you'll need to install the `@tanstack/router-plugin` package.
-
-```sh
-npm install -D @tanstack/router-plugin
-```
-
-Once installed, you'll need to add the plugin to your Vite configuration.
-
-```ts
-// vite.config.ts
-import { defineConfig } from 'vite'
-import solid from 'vite-plugin-solid'
-import { tanstackRouter } from '@tanstack/router-plugin/vite'
-
-// https://vitejs.dev/config/
-export default defineConfig({
-  plugins: [
-    tanstackRouter({
-      target: 'solid',
-      autoCodeSplitting: true,
-    }),
-    solid(),
-    // ...
-  ],
-})
-```
-
-Or, you can clone our [Quickstart Vite example](https://github.com/TanStack/router/tree/main/examples/react/quickstart-file-based) and get started.
-
-Now that you've added the plugin to your Vite configuration, you're all set to start using file-based routing with TanStack Router.
-
-You shouldn't forget to _ignore_ the generated route tree file. Head over to the [Ignoring the generated route tree file](#ignoring-the-generated-route-tree-file) section to learn more.
-
-[//]: # 'ConfigurationBundlerVite'
-[//]: # 'ConfigurationBundlerRspack'
-[//]: # 'ConfigurationBundlerRspack'
-[//]: # 'ConfigurationBundlerWebpack'
-[//]: # 'ConfigurationBundlerWebpack'
-[//]: # 'ConfigurationBundlerEsbuild'
-[//]: # 'ConfigurationBundlerEsbuild'
diff --git a/docs/router/framework/solid/routing/file-naming-conventions.md b/docs/router/framework/solid/routing/file-naming-conventions.md
deleted file mode 100644
index 6598516d4a..0000000000
--- a/docs/router/framework/solid/routing/file-naming-conventions.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/routing/file-naming-conventions.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/routing/route-matching.md b/docs/router/framework/solid/routing/route-matching.md
deleted file mode 100644
index 6b389cee5b..0000000000
--- a/docs/router/framework/solid/routing/route-matching.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/routing/route-matching.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/routing/route-trees.md b/docs/router/framework/solid/routing/route-trees.md
deleted file mode 100644
index d58bd8f19c..0000000000
--- a/docs/router/framework/solid/routing/route-trees.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/routing/route-trees.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/routing/routing-concepts.md b/docs/router/framework/solid/routing/routing-concepts.md
deleted file mode 100644
index 30e7bbb999..0000000000
--- a/docs/router/framework/solid/routing/routing-concepts.md
+++ /dev/null
@@ -1,4 +0,0 @@
----
-ref: docs/router/framework/react/routing/routing-concepts.md
-replace: { 'react-router': 'solid-router' }
----
diff --git a/docs/router/framework/solid/routing/virtual-file-routes.md b/docs/router/framework/solid/routing/virtual-file-routes.md
deleted file mode 100644
index 9cc7be3b4e..0000000000
--- a/docs/router/framework/solid/routing/virtual-file-routes.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-ref: docs/router/framework/react/routing/virtual-file-routes.md
-replace:
-  { 'react-router': 'solid-router', "target: 'react'": "target: 'solid'" }
----
diff --git a/docs/router/framework/react/guide/authenticated-routes.md b/docs/router/guide/authenticated-routes.md
similarity index 74%
rename from docs/router/framework/react/guide/authenticated-routes.md
rename to docs/router/guide/authenticated-routes.md
index 4de520bbfe..706e89955c 100644
--- a/docs/router/framework/react/guide/authenticated-routes.md
+++ b/docs/router/guide/authenticated-routes.md
@@ -55,6 +55,10 @@ export const Route = createFileRoute('/_authenticated')({
 
 If your authentication check can throw errors (network failures, token validation, etc.), wrap it in try/catch:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { createFileRoute, redirect, isRedirect } from '@tanstack/react-router'
 
@@ -84,6 +88,39 @@ export const Route = createFileRoute('/_authenticated')({
 })
 ```
 
+# Solid
+
+```tsx
+import { createFileRoute, redirect, isRedirect } from '@tanstack/solid-router'
+
+// src/routes/_authenticated.tsx
+export const Route = createFileRoute('/_authenticated')({
+  beforeLoad: async ({ location }) => {
+    try {
+      const user = await verifySession() // might throw on network error
+      if (!user) {
+        throw redirect({
+          to: '/login',
+          search: { redirect: location.href },
+        })
+      }
+      return { user }
+    } catch (error) {
+      // Re-throw redirects (they're intentional, not errors)
+      if (isRedirect(error)) throw error
+
+      // Auth check failed (network error, etc.) - redirect to login
+      throw redirect({
+        to: '/login',
+        search: { redirect: location.href },
+      })
+    }
+  },
+})
+```
+
+<!-- ::end:framework -->
+
 The [`isRedirect()`](../api/router/isRedirectFunction.md) helper distinguishes between actual errors and intentional redirects.
 
 Once you have authenticated a user, it's also common practice to redirect them back to the page they were trying to access. To do this, you can utilize the `redirect` search param that we added in our original redirect. Since we'll be replacing the entire URL with what it was, `router.history.push` is better suited for this than `router.navigate`:
@@ -122,9 +159,13 @@ We'll cover the `router.context` options in-detail in the [Router Context](./rou
 
 Here's an example that uses React context and hooks for protecting authenticated routes in TanStack Router. See the entire working setup in the [Authenticated Routes example](https://github.com/TanStack/router/tree/main/examples/react/authenticated-routes).
 
-- `src/routes/__root.tsx`
+<!-- ::start:framework -->
 
-```tsx
+# React
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/routes/__root.tsx"
 import { createRootRouteWithContext } from '@tanstack/react-router'
 
 interface MyRouterContext {
@@ -137,9 +178,7 @@ export const Route = createRootRouteWithContext<MyRouterContext>()({
 })
 ```
 
-- `src/router.tsx`
-
-```tsx
+```tsx title="src/router.tsx"
 import { createRouter } from '@tanstack/react-router'
 
 import { routeTree } from './routeTree.gen'
@@ -154,9 +193,7 @@ export const router = createRouter({
 })
 ```
 
-- `src/App.tsx`
-
-```tsx
+```tsx title="src/App.tsx"
 import { RouterProvider } from '@tanstack/react-router'
 
 import { AuthProvider, useAuth } from './auth'
@@ -177,11 +214,72 @@ function App() {
 }
 ```
 
+<!-- ::end:tabs -->
+
+# Solid
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/routes/__root.tsx"
+import { createRootRouteWithContext } from '@tanstack/solid-router'
+
+interface MyRouterContext {
+  // The ReturnType of your useAuth hook or the value of your AuthContext
+  auth: AuthState
+}
+
+export const Route = createRootRouteWithContext<MyRouterContext>()({
+  component: () => <Outlet />,
+})
+```
+
+```tsx title="src/router.tsx"
+import { createRouter } from '@tanstack/solid-router'
+
+import { routeTree } from './routeTree.gen'
+
+export const router = createRouter({
+  routeTree,
+  context: {
+    // auth will initially be undefined
+    // We'll be passing down the auth state from within a React component
+    auth: undefined!,
+  },
+})
+```
+
+```tsx title="src/App.tsx"
+import { RouterProvider } from '@tanstack/solid-router'
+
+import { AuthProvider, useAuth } from './auth'
+
+import { router } from './router'
+
+function InnerApp() {
+  const auth = useAuth()
+  return <RouterProvider router={router} context={{ auth }} />
+}
+
+function App() {
+  return (
+    <AuthProvider>
+      <InnerApp />
+    </AuthProvider>
+  )
+}
+```
+
+<!-- ::end:tabs -->
+
+<!-- ::end:framework -->
+
 Then in the authenticated route, you can check the auth state using the `beforeLoad` function, and **throw a `redirect()`** to your **Login route** if the user is not signed-in.
 
-- `src/routes/dashboard.route.tsx`
+<!-- ::start:framework -->
 
-```tsx
+# React
+
+```tsx title="src/routes/dashboard.route.tsx"
 import { createFileRoute, redirect } from '@tanstack/react-router'
 
 export const Route = createFileRoute('/dashboard')({
@@ -198,6 +296,27 @@ export const Route = createFileRoute('/dashboard')({
 })
 ```
 
+# Solid
+
+```tsx title="src/routes/dashboard.route.tsx"
+import { createFileRoute, redirect } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/dashboard')({
+  beforeLoad: ({ context, location }) => {
+    if (!context.auth.isAuthenticated()) {
+      throw redirect({
+        to: '/login',
+        search: {
+          redirect: location.href,
+        },
+      })
+    }
+  },
+})
+```
+
+<!-- ::end:framework -->
+
 You can _optionally_, also use the [Non-Redirected Authentication](#non-redirected-authentication) approach to show a login form instead of calling a **redirect**.
 
 This approach can also be used in conjunction with Pathless or Layout Route to protect all routes under their parent route.
diff --git a/docs/router/framework/react/guide/automatic-code-splitting.md b/docs/router/guide/automatic-code-splitting.md
similarity index 98%
rename from docs/router/framework/react/guide/automatic-code-splitting.md
rename to docs/router/guide/automatic-code-splitting.md
index 8c980d7d82..4612c298c6 100644
--- a/docs/router/framework/react/guide/automatic-code-splitting.md
+++ b/docs/router/guide/automatic-code-splitting.md
@@ -83,8 +83,6 @@ For automatic code splitting to work, there are some rules in-place to make sure
 Route properties like `component`, `loader`, etc., should not be exported from the route file. Exporting these properties results in them being bundled into the main application bundle, which means that they will not be code-split.
 
 ```tsx
-import { createRoute } from '@tanstack/react-router'
-
 export const Route = createRoute('/posts')({
   // ...
   notFoundComponent: PostsNotFoundComponent,
@@ -116,8 +114,7 @@ You can change how TanStack Router splits your routes by changing the `defaultBe
 
 For example, to bundle all UI-related components into a single chunk, you could configure it like this:
 
-```ts
-// vite.config.ts
+```ts title="vite.config.ts"
 import { defineConfig } from 'vite'
 import { tanstackRouter } from '@tanstack/router-plugin/vite'
 
@@ -144,8 +141,7 @@ export default defineConfig({
 
 For complex rulesets, you can use the `splitBehavior` function in your vite config to programmatically define how routes should be split into chunks based on their `routeId`. This function allows you to implement custom logic for grouping properties together, giving you fine-grained control over the code splitting behavior.
 
-```ts
-// vite.config.ts
+```ts title="vite.config.ts"
 import { defineConfig } from 'vite'
 import { tanstackRouter } from '@tanstack/router-plugin/vite'
 
@@ -171,9 +167,7 @@ export default defineConfig({
 
 For ultimate control, you can override the global configuration directly inside a route file by adding a `codeSplitGroupings` property. This is useful for routes that have unique optimization needs.
 
-```tsx
-// src/routes/posts.route.tsx
-import { createFileRoute } from '@tanstack/react-router'
+```tsx title="src/routes/posts.route.tsx"
 import { loadPostsData } from './-heavy-posts-utils'
 
 export const Route = createFileRoute('/posts')({
diff --git a/docs/router/framework/react/guide/code-splitting.md b/docs/router/guide/code-splitting.md
similarity index 76%
rename from docs/router/framework/react/guide/code-splitting.md
rename to docs/router/guide/code-splitting.md
index e422562725..698bf262b5 100644
--- a/docs/router/framework/react/guide/code-splitting.md
+++ b/docs/router/guide/code-splitting.md
@@ -119,8 +119,11 @@ When you are using `.lazy.tsx` you can split your route into two files to enable
 
 **Before (Single File)**
 
-```tsx
-// src/routes/posts.tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/posts.tsx"
 import { createFileRoute } from '@tanstack/react-router'
 import { fetchPosts } from './api'
 
@@ -134,13 +137,33 @@ function Posts() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/posts.tsx"
+import { createFileRoute } from '@tanstack/solid-router'
+import { fetchPosts } from './api'
+
+export const Route = createFileRoute('/posts')({
+  loader: fetchPosts,
+  component: Posts,
+})
+
+function Posts() {
+  // ...
+}
+```
+
+<!-- ::end:framework -->
+
 **After (Split into two files)**
 
 This file would contain the critical route configuration:
 
-```tsx
-// src/routes/posts.tsx
+<!-- ::start:framework -->
+
+# React
 
+```tsx title="src/routes/posts.tsx"
 import { createFileRoute } from '@tanstack/react-router'
 import { fetchPosts } from './api'
 
@@ -149,10 +172,26 @@ export const Route = createFileRoute('/posts')({
 })
 ```
 
+# Solid
+
+```tsx title="src/routes/posts.tsx"
+import { createFileRoute } from '@tanstack/solid-router'
+import { fetchPosts } from './api'
+
+export const Route = createFileRoute('/posts')({
+  loader: fetchPosts,
+})
+```
+
+<!-- ::end:framework -->
+
 With the non-critical route configuration going into the file with the `.lazy.tsx` suffix:
 
-```tsx
-// src/routes/posts.lazy.tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/posts.lazy.tsx"
 import { createLazyFileRoute } from '@tanstack/react-router'
 
 export const Route = createLazyFileRoute('/posts')({
@@ -164,14 +203,35 @@ function Posts() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/posts.lazy.tsx"
+import { createLazyFileRoute } from '@tanstack/solid-router'
+
+export const Route = createLazyFileRoute('/posts')({
+  component: Posts,
+})
+
+function Posts() {
+  // ...
+}
+```
+
+<!-- ::end:framework -->
+
 ## Using Virtual Routes
 
 You might run into a situation where you end up splitting out everything from a route file, leaving it empty! In this case, simply **delete the route file entirely**! A virtual route will automatically be generated for you to serve as an anchor for your code split files. This virtual route will live directly in the generated route tree file.
 
 **Before (Virtual Routes)**
 
-```tsx
-// src/routes/posts.tsx
+<!-- ::start:framework -->
+
+# React
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/routes/posts.tsx"
 import { createFileRoute } from '@tanstack/react-router'
 
 export const Route = createFileRoute('/posts')({
@@ -179,8 +239,7 @@ export const Route = createFileRoute('/posts')({
 })
 ```
 
-```tsx
-// src/routes/posts.lazy.tsx
+```tsx title="src/routes/posts.lazy.tsx"
 import { createLazyFileRoute } from '@tanstack/react-router'
 
 export const Route = createLazyFileRoute('/posts')({
@@ -192,10 +251,43 @@ function Posts() {
 }
 ```
 
+<!-- ::end:tabs -->
+
+# Solid
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/routes/posts.tsx"
+import { createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/posts')({
+  // Hello?
+})
+```
+
+```tsx title="src/routes/posts.lazy.tsx"
+import { createLazyFileRoute } from '@tanstack/solid-router'
+
+export const Route = createLazyFileRoute('/posts')({
+  component: Posts,
+})
+
+function Posts() {
+  // ...
+}
+```
+
+<!-- ::end:tabs -->
+
+<!-- ::end:framework -->
+
 **After (Virtual Routes)**
 
-```tsx
-// src/routes/posts.lazy.tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/posts.lazy.tsx"
 import { createLazyFileRoute } from '@tanstack/react-router'
 
 export const Route = createLazyFileRoute('/posts')({
@@ -207,6 +299,22 @@ function Posts() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/posts.lazy.tsx"
+import { createLazyFileRoute } from '@tanstack/solid-router'
+
+export const Route = createLazyFileRoute('/posts')({
+  component: Posts,
+})
+
+function Posts() {
+  // ...
+}
+```
+
+<!-- ::end:framework -->
+
 Tada! 🎉
 
 ## Code-Based Splitting
@@ -215,8 +323,7 @@ If you are using code-based routing, you can still code-split your routes using
 
 Create a lazy route using the `createLazyRoute` function.
 
-```tsx
-// src/posts.lazy.tsx
+```tsx title="src/posts.lazy.tsx"
 export const Route = createLazyRoute('/posts')({
   component: MyComponent,
 })
@@ -228,8 +335,7 @@ function MyComponent() {
 
 Then, call the `.lazy` method on the route definition in your `app.tsx` to import the lazy/code-split route with the non-critical route configuration.
 
-```tsx
-// src/app.tsx
+```tsx title="src/app.tsx"
 const postsRoute = createRoute({
   getParentRoute: () => rootRoute,
   path: '/posts',
@@ -244,6 +350,10 @@ It can be a powerful tool to reduce bundle size, but it comes with a cost as men
 
 You can code split your data loading logic using the Route's `loader` option. While this process makes it difficult to maintain type-safety with the parameters passed to your loader, you can always use the generic `LoaderContext` type to get you most of the way there:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { lazyFn } from '@tanstack/react-router'
 
@@ -259,15 +369,38 @@ export const loader = async (context: LoaderContext) => {
 }
 ```
 
+# Solid
+
+```tsx
+import { lazyFn } from '@tanstack/solid-router'
+
+const route = createRoute({
+  path: '/my-route',
+  component: MyComponent,
+  loader: lazyFn(() => import('./loader'), 'loader'),
+})
+
+// In another file...a
+export const loader = async (context: LoaderContext) => {
+  /// ...
+}
+```
+
+<!-- ::end:framework -->
+
 If you are using file-based routing, you'll only be able to split your `loader` if you are using [Automatic Code Splitting](#using-automatic-code-splitting) with customized bundling options.
 
 ## Manually accessing Route APIs in other files with the `getRouteApi` helper
 
 As you might have guessed, placing your component code in a separate file than your route can make it difficult to consume the route itself. To help with this, TanStack Router exports a handy `getRouteApi` function that you can use to access a route's type-safe APIs in a file without importing the route itself.
 
-- `my-route.tsx`
+<!-- ::start:framework -->
 
-```tsx
+# React
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/my-route.tsx"
 import { createRoute } from '@tanstack/react-router'
 import { MyComponent } from './MyComponent'
 
@@ -280,9 +413,7 @@ const route = createRoute({
 })
 ```
 
-- `MyComponent.tsx`
-
-```tsx
+```tsx title="src/MyComponent.tsx"
 import { getRouteApi } from '@tanstack/react-router'
 
 const route = getRouteApi('/my-route')
@@ -295,6 +426,42 @@ export function MyComponent() {
 }
 ```
 
+<!-- ::end:tabs -->
+
+# Solid
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/my-route.tsx"
+import { createRoute } from '@tanstack/solid-router'
+import { MyComponent } from './MyComponent'
+
+const route = createRoute({
+  path: '/my-route',
+  loader: () => ({
+    foo: 'bar',
+  }),
+  component: MyComponent,
+})
+```
+
+```tsx title="src/MyComponent.tsx"
+import { getRouteApi } from '@tanstack/solid-router'
+
+const route = getRouteApi('/my-route')
+
+export function MyComponent() {
+  const loaderData = route.useLoaderData()
+  //    ^? { foo: string }
+
+  return <div>...</div>
+}
+```
+
+<!-- ::end:tabs -->
+
+<!-- ::end:framework -->
+
 The `getRouteApi` function is useful for accessing other type-safe APIs:
 
 - `useLoaderData`
diff --git a/docs/router/framework/react/guide/creating-a-router.md b/docs/router/guide/creating-a-router.md
similarity index 83%
rename from docs/router/framework/react/guide/creating-a-router.md
rename to docs/router/guide/creating-a-router.md
index d84815bd7c..f8919d6b51 100644
--- a/docs/router/framework/react/guide/creating-a-router.md
+++ b/docs/router/guide/creating-a-router.md
@@ -2,11 +2,15 @@
 title: Creating a Router
 ---
 
-## The `Router` Class
+## The `createRouter` function
 
 When you're ready to start using your router, you'll need to create a new `Router` instance. The router instance is the core brains of TanStack Router and is responsible for managing the route tree, matching routes, and coordinating navigations and route transitions. It also serves as a place to configure router-wide settings.
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/router.tsx"
 import { createRouter } from '@tanstack/react-router'
 
 const router = createRouter({
@@ -14,6 +18,18 @@ const router = createRouter({
 })
 ```
 
+# Solid
+
+```tsx title="src/router.tsx"
+import { createRouter } from '@tanstack/solid-router'
+
+const router = createRouter({
+  // ...
+})
+```
+
+<!-- ::end:framework -->
+
 ## Route Tree
 
 You'll probably notice quickly that the `Router` constructor requires a `routeTree` option. This is the route tree that the router will use to match routes and render components.
@@ -45,7 +61,11 @@ const routeTree = rootRoute.addChildren([
 
 TanStack Router provides amazing support for TypeScript, even for things you wouldn't expect like bare imports straight from the library! To make this possible, you must register your router's types using TypeScripts' [Declaration Merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) feature. This is done by extending the `Register` interface on `@tanstack/react-router` with a `router` property that has the type of your `router` instance:
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/router.tsx"
 declare module '@tanstack/react-router' {
   interface Register {
     // This infers the type of our router and registers it across your entire project
@@ -54,6 +74,19 @@ declare module '@tanstack/react-router' {
 }
 ```
 
+# Solid
+
+```tsx title="src/router.tsx"
+declare module '@tanstack/solid-router' {
+  interface Register {
+    // This infers the type of our router and registers it across your entire project
+    router: typeof router
+  }
+}
+```
+
+<!-- ::end:framework -->
+
 With your router registered, you'll now get type-safety across your entire project for anything related to routing.
 
 ## 404 Not Found Route
diff --git a/docs/router/framework/react/guide/custom-link.md b/docs/router/guide/custom-link.md
similarity index 77%
rename from docs/router/framework/react/guide/custom-link.md
rename to docs/router/guide/custom-link.md
index 1ffb55fce8..dd7038cecd 100644
--- a/docs/router/framework/react/guide/custom-link.md
+++ b/docs/router/guide/custom-link.md
@@ -12,7 +12,9 @@ While repeating yourself can be acceptable in many situations, you might find th
 
 If you want to create a basic custom link component, you can do so with the following:
 
-[//]: # 'BasicExampleImplementation'
+<!-- ::start:framework -->
+
+# React
 
 ```tsx
 import * as React from 'react'
@@ -37,7 +39,34 @@ export const CustomLink: LinkComponent<typeof BasicLinkComponent> = (props) => {
 }
 ```
 
-[//]: # 'BasicExampleImplementation'
+# Solid
+
+```tsx
+import * as Solid from 'solid-js'
+import { createLink, LinkComponent } from '@tanstack/solid-router'
+
+export const Route = createRootRoute({
+  component: RootComponent,
+})
+
+type BasicLinkProps = Solid.JSX.IntrinsicElements['a'] & {
+  // Add any additional props you want to pass to the anchor element
+}
+
+const BasicLinkComponent: Solid.Component<BasicLinkProps> = (props) => (
+  <a {...props} class="block px-3 py-2 text-red-700">
+    {props.children}
+  </a>
+)
+
+const CreatedLinkComponent = createLink(BasicLinkComponent)
+
+export const CustomLink: LinkComponent<typeof BasicLinkComponent> = (props) => {
+  return <CreatedLinkComponent preload={'intent'} {...props} />
+}
+```
+
+<!-- ::end:framework -->
 
 You can then use your newly created `Link` component as any other `Link`
 
@@ -45,17 +74,21 @@ You can then use your newly created `Link` component as any other `Link`
 <CustomLink to={'/dashboard/invoices/$invoiceId'} params={{ invoiceId: 0 }} />
 ```
 
-[//]: # 'ExamplesUsingThirdPartyLibs'
-
 ## `createLink` with third party libraries
 
 Here are some examples of how you can use `createLink` with third-party libraries.
 
+<!-- ::start:framework -->
+
+# React
+
 ### React Aria Components example
 
 React Aria Components v1.11.0 and later works with TanStack Router's `preload (intent)` prop. Use `createLink` to wrap each React Aria component that you use as a link.
 
-```tsx
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="RACLink.tsx"
 import { createLink } from '@tanstack/react-router'
 import { Link as RACLink, MenuItem } from 'react-aria-components'
 
@@ -63,9 +96,7 @@ export const Link = createLink(RACLink)
 export const MenuItemLink = createLink(MenuItem)
 ```
 
-To use React Aria's render props, including the `className`, `style`, and `children` functions, create a wrapper component and pass that to `createLink`.
-
-```tsx
+```tsx title="CustomRACLink.tsx"
 import { createLink } from '@tanstack/react-router'
 import { Link as RACLink, type LinkProps } from 'react-aria-components'
 
@@ -87,9 +118,19 @@ function MyLink(props: MyLinkProps) {
 export const Link = createLink(MyLink)
 ```
 
+<!-- ::end:tabs -->
+
+To use React Aria's render props, including the `className`, `style`, and `children` functions, create a wrapper component and pass that to `createLink`.
+
+<!-- ::end:framework -->
+
+<!-- ::start:framework -->
+
+# React
+
 ### Chakra UI example
 
-```tsx
+```tsx title="ChakraLinkComponent.tsx"
 import * as React from 'react'
 import { createLink, LinkComponent } from '@tanstack/react-router'
 import { Link } from '@chakra-ui/react'
@@ -125,6 +166,12 @@ export const CustomLink: LinkComponent<typeof ChakraLinkComponent> = (
 }
 ```
 
+<!-- ::end:framework -->
+
+<!-- ::start:framework -->
+
+# React
+
 ### MUI example
 
 There is an [example](https://github.com/TanStack/router/tree/main/examples/react/start-material-ui) available which uses these patterns.
@@ -133,16 +180,22 @@ There is an [example](https://github.com/TanStack/router/tree/main/examples/reac
 
 If the MUI `Link` should simply behave like the router `Link`, it can be just wrapped with `createLink`:
 
-```tsx
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="CustomLink.tsx"
 import { createLink } from '@tanstack/react-router'
 import { Link } from '@mui/material'
 
 export const CustomLink = createLink(Link)
 ```
 
+<!-- ::end:tabs -->
+
 If the `Link` should be customized this approach can be used:
 
-```tsx
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="CustomLink.tsx"
 import React from 'react'
 import { createLink } from '@tanstack/react-router'
 import { Link } from '@mui/material'
@@ -166,11 +219,15 @@ export const CustomLink: LinkComponent<typeof MUILinkComponent> = (props) => {
 // Can also be styled
 ```
 
+<!-- ::end:tabs -->
+
 #### `Button`
 
 If a `Button` should be used as a router `Link`, the `component` should be set as `a`:
 
-```tsx
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="CustomButtonLink.tsx"
 import React from 'react'
 import { createLink } from '@tanstack/react-router'
 import { Button } from '@mui/material'
@@ -195,11 +252,15 @@ export const CustomButtonLink: LinkComponent<typeof MUIButtonLinkComponent> = (
 }
 ```
 
+<!-- ::end:tabs -->
+
 #### Usage with `styled`
 
 Any of these MUI approaches can then be used with `styled`:
 
-```tsx
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="StyledCustomLink.tsx"
 import { css, styled } from '@mui/material'
 import { CustomLink } from './CustomLink'
 
@@ -210,9 +271,19 @@ const StyledCustomLink = styled(CustomLink)(
 )
 ```
 
+<!-- ::end:tabs -->
+
+<!-- ::end:framework -->
+
+<!-- ::start:framework -->
+
+# React
+
 ### Mantine example
 
-```tsx
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="CustomLink.tsx"
 import * as React from 'react'
 import { createLink, LinkComponent } from '@tanstack/react-router'
 import { Anchor, AnchorProps } from '@mantine/core'
@@ -237,4 +308,22 @@ export const CustomLink: LinkComponent<typeof MantineLinkComponent> = (
 }
 ```
 
-[//]: # 'ExamplesUsingThirdPartyLibs'
+<!-- ::end:tabs -->
+
+<!-- ::end:framework -->
+
+<!-- ::start:framework -->
+
+# Solid
+
+### Some Library example
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="UntitledLink.tsx"
+// TODO: Add this example.
+```
+
+<!-- ::end:tabs -->
+
+<!-- ::end:framework -->
diff --git a/docs/router/framework/react/guide/custom-search-param-serialization.md b/docs/router/guide/custom-search-param-serialization.md
similarity index 73%
rename from docs/router/framework/react/guide/custom-search-param-serialization.md
rename to docs/router/guide/custom-search-param-serialization.md
index 33124513e8..7e87191a5a 100644
--- a/docs/router/framework/react/guide/custom-search-param-serialization.md
+++ b/docs/router/guide/custom-search-param-serialization.md
@@ -22,6 +22,10 @@ It would be serialized and escaped into the following search string:
 
 We can implement the default behavior with the following code:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import {
   createRouter,
@@ -36,6 +40,24 @@ const router = createRouter({
 })
 ```
 
+# Solid
+
+```tsx
+import {
+  createRouter,
+  parseSearchWith,
+  stringifySearchWith,
+} from '@tanstack/solid-router'
+
+const router = createRouter({
+  // ...
+  parseSearch: parseSearchWith(JSON.parse),
+  stringifySearch: stringifySearchWith(JSON.stringify),
+})
+```
+
+<!-- ::end:framework -->
+
 However, this default behavior may not be suitable for all use cases. For example, you may want to use a different serialization format, such as base64 encoding, or you may want to use a purpose-built serialization/deserialization library, like [query-string](https://github.com/sindresorhus/query-string), [JSURL2](https://github.com/wmertens/jsurl2), or [Zipson](https://jgranstrom.github.io/zipson/).
 
 This can be achieved by providing your own serialization and deserialization functions to the `parseSearch` and `stringifySearch` options in the [`Router`](../api/router/RouterOptionsType.md#stringifysearch-method) configuration. When doing this, you can utilize TanStack Router's built-in helper functions, `parseSearchWith` and `stringifySearchWith`, to simplify the process.
@@ -51,6 +73,10 @@ Here are some examples of how you can customize the search param serialization i
 
 It's common to base64 encode your search params to achieve maximum compatibility across browsers and URL unfurlers, etc. This can be done with the following code:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import {
   Router,
@@ -84,6 +110,43 @@ function encodeToBinary(str: string): string {
 }
 ```
 
+# Solid
+
+```tsx
+import {
+  Router,
+  parseSearchWith,
+  stringifySearchWith,
+} from '@tanstack/solid-router'
+
+const router = createRouter({
+  parseSearch: parseSearchWith((value) => JSON.parse(decodeFromBinary(value))),
+  stringifySearch: stringifySearchWith((value) =>
+    encodeToBinary(JSON.stringify(value)),
+  ),
+})
+
+function decodeFromBinary(str: string): string {
+  return decodeURIComponent(
+    Array.prototype.map
+      .call(atob(str), function (c) {
+        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
+      })
+      .join(''),
+  )
+}
+
+function encodeToBinary(str: string): string {
+  return btoa(
+    encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
+      return String.fromCharCode(parseInt(p1, 16))
+    }),
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 > [⚠️ Why does this snippet not use atob/btoa?](#safe-binary-encodingdecoding)
 
 So, if we were to turn the previous object into a search string using this configuration, it would look like this:
@@ -99,6 +162,10 @@ So, if we were to turn the previous object into a search string using this confi
 
 The [query-string](https://github.com/sindresorhus/query-string) library is a popular for being able to reliably parse and stringify query strings. You can use it to customize the serialization format of your search params. This can be done with the following code:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { createRouter } from '@tanstack/react-router'
 import qs from 'query-string'
@@ -118,6 +185,29 @@ const router = createRouter({
 })
 ```
 
+# Solid
+
+```tsx
+import { createRouter } from '@tanstack/solid-router'
+import qs from 'query-string'
+
+const router = createRouter({
+  // ...
+  stringifySearch: stringifySearchWith((value) =>
+    qs.stringify(value, {
+      // ...options
+    }),
+  ),
+  parseSearch: parseSearchWith((value) =>
+    qs.parse(value, {
+      // ...options
+    }),
+  ),
+})
+```
+
+<!-- ::end:framework -->
+
 So, if we were to turn the previous object into a search string using this configuration, it would look like this:
 
 ```txt
@@ -128,6 +218,10 @@ So, if we were to turn the previous object into a search string using this confi
 
 [JSURL2](https://github.com/wmertens/jsurl2) is a non-standard library that can compress URLs while still maintaining readability. This can be done with the following code:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import {
   Router,
@@ -143,6 +237,25 @@ const router = createRouter({
 })
 ```
 
+# Solid
+
+```tsx
+import {
+  Router,
+  parseSearchWith,
+  stringifySearchWith,
+} from '@tanstack/solid-router'
+import { parse, stringify } from 'jsurl2'
+
+const router = createRouter({
+  // ...
+  parseSearch: parseSearchWith(parse),
+  stringifySearch: stringifySearchWith(stringify),
+})
+```
+
+<!-- ::end:framework -->
+
 So, if we were to turn the previous object into a search string using this configuration, it would look like this:
 
 ```txt
@@ -153,6 +266,10 @@ So, if we were to turn the previous object into a search string using this confi
 
 [Zipson](https://jgranstrom.github.io/zipson/) is a very user-friendly and performant JSON compression library (both in runtime performance and the resulting compression performance). To compress your search params with it (which requires escaping/unescaping and base64 encoding/decoding them as well), you can use the following code:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import {
   Router,
@@ -187,6 +304,44 @@ function encodeToBinary(str: string): string {
 }
 ```
 
+# Solid
+
+```tsx
+import {
+  Router,
+  parseSearchWith,
+  stringifySearchWith,
+} from '@tanstack/solid-router'
+import { stringify, parse } from 'zipson'
+
+const router = createRouter({
+  parseSearch: parseSearchWith((value) => parse(decodeFromBinary(value))),
+  stringifySearch: stringifySearchWith((value) =>
+    encodeToBinary(stringify(value)),
+  ),
+})
+
+function decodeFromBinary(str: string): string {
+  return decodeURIComponent(
+    Array.prototype.map
+      .call(atob(str), function (c) {
+        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
+      })
+      .join(''),
+  )
+}
+
+function encodeToBinary(str: string): string {
+  return btoa(
+    encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
+      return String.fromCharCode(parseInt(p1, 16))
+    }),
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 > [⚠️ Why does this snippet not use atob/btoa?](#safe-binary-encodingdecoding)
 
 So, if we were to turn the previous object into a search string using this configuration, it would look like this:
@@ -197,13 +352,13 @@ So, if we were to turn the previous object into a search string using this confi
 
 <hr>
 
-### Safe Binary Encoding/Decoding
+## Safe Binary Encoding/Decoding
 
 In the browser, the `atob` and `btoa` functions are not guaranteed to work properly with non-UTF8 characters. We recommend using these encoding/decoding utilities instead:
 
 To encode from a string to a binary string:
 
-```typescript
+```ts
 export function encodeToBinary(str: string): string {
   return btoa(
     encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
@@ -215,7 +370,7 @@ export function encodeToBinary(str: string): string {
 
 To decode from a binary string to a string:
 
-```typescript
+```ts
 export function decodeFromBinary(str: string): string {
   return decodeURIComponent(
     Array.prototype.map
diff --git a/docs/router/framework/react/guide/data-loading.md b/docs/router/guide/data-loading.md
similarity index 96%
rename from docs/router/framework/react/guide/data-loading.md
rename to docs/router/guide/data-loading.md
index c9cc4bd424..80e85c1366 100644
--- a/docs/router/framework/react/guide/data-loading.md
+++ b/docs/router/guide/data-loading.md
@@ -60,7 +60,7 @@ The router cache is built-in and is as easy as returning data from any route's `
 Route `loader` functions are called when a route match is loaded. They are called with a single parameter which is an object containing many helpful properties. We'll go over those in a bit, but first, let's look at an example of a route `loader` function:
 
 ```tsx
-// routes/posts.tsx
+// src/routes/posts.tsx
 export const Route = createFileRoute('/posts')({
   loader: () => fetchPosts(),
 })
@@ -97,6 +97,10 @@ const posts = Route.useLoaderData()
 
 If you don't have ready access to your route object (i.e. you're deep in the component tree for the current route), you can use `getRouteApi` to access the same hook (as well as the other hooks on the Route object). This should be preferred over importing the Route object, which is likely to create circular dependencies.
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { getRouteApi } from '@tanstack/react-router'
 
@@ -106,6 +110,19 @@ const routeApi = getRouteApi('/posts')
 const data = routeApi.useLoaderData()
 ```
 
+# Solid
+
+```tsx
+import { getRouteApi } from '@tanstack/solid-router'
+
+// in your component
+
+const routeApi = getRouteApi('/posts')
+const data = routeApi.useLoaderData()
+```
+
+<!-- ::end:framework -->
+
 ## Dependency-based Stale-While-Revalidate Caching
 
 TanStack Router provides a built-in Stale-While-Revalidate caching layer for route loaders that is keyed on the dependencies of a route:
@@ -280,6 +297,10 @@ export const fetchPosts = async () => {
 
 - `/routes/__root.tsx`
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { createRootRouteWithContext } from '@tanstack/react-router'
 
@@ -289,11 +310,22 @@ export const Route = createRootRouteWithContext<{
 }>()() // NOTE: the double call is on purpose, since createRootRouteWithContext is a factory ;)
 ```
 
-- `/routes/posts.tsx`
+# Solid
 
 ```tsx
-import { createFileRoute } from '@tanstack/react-router'
+import { createRootRouteWithContext } from '@tanstack/solid-router'
+
+// Create a root route using the createRootRouteWithContext<{...}>() function and pass it whatever types you would like to be available in your router context.
+export const Route = createRootRouteWithContext<{
+  fetchPosts: typeof fetchPosts
+}>()() // NOTE: the double call is on purpose, since createRootRouteWithContext is a factory ;)
+```
 
+<!-- ::end:framework -->
+
+- `/routes/posts.tsx`
+
+```tsx
 // Notice how our postsRoute references context to get our fetchPosts function
 // This can be a powerful tool for dependency injection across your router
 // and routes.
@@ -323,7 +355,7 @@ const router = createRouter({
 To use path params in your `loader` function, access them via the `params` property on the function's parameters. Here's an example:
 
 ```tsx
-// routes/posts.$postId.tsx
+// src/routes/posts.$postId.tsx
 export const Route = createFileRoute('/posts/$postId')({
   loader: ({ params: { postId } }) => fetchPostById(postId),
 })
@@ -334,9 +366,7 @@ export const Route = createFileRoute('/posts/$postId')({
 Passing down global context to your router is great, but what if you want to provide context that is specific to a route? This is where the `beforeLoad` option comes in. The `beforeLoad` option is a function that runs right before attempting to load a route and receives the same parameters as `loader`. Beyond its ability to redirect potential matches, block loader requests, etc, it can also return an object that will be merged into the route's context. Let's take a look at an example where we inject some data into our route context via the `beforeLoad` option:
 
 ```tsx
-// /routes/posts.tsx
-import { createFileRoute } from '@tanstack/react-router'
-
+// src/routes/posts.tsx
 export const Route = createFileRoute('/posts')({
   // Pass the fetchPosts function to the route context
   beforeLoad: () => ({
@@ -398,7 +428,7 @@ export const Route = createFileRoute('/posts')({
 The `abortController` property of the `loader` function is an [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController). Its signal is cancelled when the route is unloaded or when the `loader` call becomes outdated. This is useful for cancelling network requests when the route is unloaded or when the route's params change. Here is an example using it with a fetch call:
 
 ```tsx
-// routes/posts.tsx
+// src/routes/posts.tsx
 export const Route = createFileRoute('/posts')({
   loader: ({ abortController }) =>
     fetchPosts({
@@ -413,7 +443,7 @@ export const Route = createFileRoute('/posts')({
 The `preload` property of the `loader` function is a boolean which is `true` when the route is being preloaded instead of loaded. Some data loading libraries may handle preloading differently than a standard fetch, so you may want to pass `preload` to your data loading library, or use it to execute the appropriate data loading logic:
 
 ```tsx
-// routes/posts.tsx
+// src/routes/posts.tsx
 export const Route = createFileRoute('/posts')({
   loader: async ({ preload }) =>
     fetchPosts({
@@ -454,7 +484,7 @@ TanStack Router provides a few ways to handle errors that occur during the route
 The `routeOptions.onError` option is a function that is called when an error occurs during the route loading.
 
 ```tsx
-// routes/posts.tsx
+// src/routes/posts.tsx
 export const Route = createFileRoute('/posts')({
   loader: () => fetchPosts(),
   onError: ({ error }) => {
@@ -469,7 +499,7 @@ export const Route = createFileRoute('/posts')({
 The `routeOptions.onCatch` option is a function that is called whenever an error was caught by the router's CatchBoundary.
 
 ```tsx
-// routes/posts.tsx
+// src/routes/posts.tsx
 export const Route = createFileRoute('/posts')({
   onCatch: ({ error, errorInfo }) => {
     // Log the error
@@ -486,7 +516,7 @@ The `routeOptions.errorComponent` option is a component that is rendered when an
 - `reset` - A function to reset the internal `CatchBoundary`
 
 ```tsx
-// routes/posts.tsx
+// src/routes/posts.tsx
 export const Route = createFileRoute('/posts')({
   loader: () => fetchPosts(),
   errorComponent: ({ error }) => {
@@ -499,7 +529,7 @@ export const Route = createFileRoute('/posts')({
 The `reset` function can be used to allow the user to retry rendering the error boundaries normal children:
 
 ```tsx
-// routes/posts.tsx
+// src/routes/posts.tsx
 export const Route = createFileRoute('/posts')({
   loader: () => fetchPosts(),
   errorComponent: ({ error, reset }) => {
@@ -523,7 +553,7 @@ export const Route = createFileRoute('/posts')({
 If the error was the result of a route load, you should instead call `router.invalidate()`, which will coordinate both a router reload and an error boundary reset:
 
 ```tsx
-// routes/posts.tsx
+// src/routes/posts.tsx
 export const Route = createFileRoute('/posts')({
   loader: () => fetchPosts(),
   errorComponent: ({ error, reset }) => {
@@ -551,9 +581,7 @@ export const Route = createFileRoute('/posts')({
 TanStack Router provides a default `ErrorComponent` that is rendered when an error occurs during the route loading or rendering lifecycle. If you choose to override your routes' error components, it's still wise to always fall back to rendering any uncaught errors with the default `ErrorComponent`:
 
 ```tsx
-// routes/posts.tsx
-import { createFileRoute, ErrorComponent } from '@tanstack/react-router'
-
+// src/routes/posts.tsx
 export const Route = createFileRoute('/posts')({
   loader: () => fetchPosts(),
   errorComponent: ({ error }) => {
diff --git a/docs/router/framework/react/guide/data-mutations.md b/docs/router/guide/data-mutations.md
similarity index 100%
rename from docs/router/framework/react/guide/data-mutations.md
rename to docs/router/guide/data-mutations.md
diff --git a/docs/router/framework/react/guide/deferred-data-loading.md b/docs/router/guide/deferred-data-loading.md
similarity index 81%
rename from docs/router/framework/react/guide/deferred-data-loading.md
rename to docs/router/guide/deferred-data-loading.md
index 8ba29da9e3..9956542ebd 100644
--- a/docs/router/framework/react/guide/deferred-data-loading.md
+++ b/docs/router/guide/deferred-data-loading.md
@@ -68,12 +68,14 @@ The `Await` component resolves the promise by triggering the nearest suspense bo
 
 If the promise is rejected, the `Await` component will throw the serialized error, which can be caught by the nearest error boundary.
 
-[//]: # 'DeferredWithAwaitFinalTip'
+<!-- ::start:framework -->
+
+# React
 
 > [!TIP]
 > In React 19, you can use the `use()` hook instead of `Await`
 
-[//]: # 'DeferredWithAwaitFinalTip'
+<!-- ::end:framework -->
 
 ## Deferred Data Loading with External libraries
 
@@ -81,6 +83,10 @@ When your strategy for fetching information for the route relies on [External Da
 
 So, instead of using `defer` and `Await`, you'll instead want to use the Route's `loader` to kick off the data fetching and then use the library's hooks to access the data in your components.
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 // src/routes/posts.$postId.tsx
 import { createFileRoute } from '@tanstack/react-router'
@@ -97,8 +103,32 @@ export const Route = createFileRoute('/posts/$postId')({
 })
 ```
 
+# Solid
+
+```tsx
+// src/routes/posts.$postId.tsx
+import { createFileRoute } from '@tanstack/solid-router'
+import { slowDataOptions, fastDataOptions } from '~/api/query-options'
+
+export const Route = createFileRoute('/posts/$postId')({
+  loader: async ({ context: { queryClient } }) => {
+    // Kick off the fetching of some slower data, but do not await it
+    queryClient.prefetchQuery(slowDataOptions())
+
+    // Fetch and await some data that resolves quickly
+    await queryClient.ensureQueryData(fastDataOptions())
+  },
+})
+```
+
+<!-- ::end:framework -->
+
 Then in your component, you can use the library's hooks to access the data:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 // src/routes/posts.$postId.tsx
 import { createFileRoute } from '@tanstack/react-router'
@@ -129,11 +159,47 @@ function SlowDataComponent() {
 }
 ```
 
+# Solid
+
+```tsx
+// src/routes/posts.$postId.tsx
+import { createFileRoute } from '@tanstack/solid-router'
+import { useSuspenseQuery } from '@tanstack/solid-query'
+import { slowDataOptions, fastDataOptions } from '~/api/query-options'
+
+export const Route = createFileRoute('/posts/$postId')({
+  // ...
+  component: PostIdComponent,
+})
+
+function PostIdComponent() {
+  const fastData = useSuspenseQuery(fastDataOptions())
+
+  // do something with fastData
+
+  return (
+    <Suspense fallback={<div>Loading...</div>}>
+      <SlowDataComponent />
+    </Suspense>
+  )
+}
+
+function SlowDataComponent() {
+  const data = useSuspenseQuery(slowDataOptions())
+
+  return <div>{data()}</div>
+}
+```
+
+<!-- ::end:framework -->
+
 ## Caching and Invalidation
 
 Streamed promises follow the same lifecycle as the loader data they are associated with. They can even be preloaded!
 
-[//]: # 'SSRContent'
+<!-- ::start:framework -->
+
+# React
 
 ## SSR & Streaming Deferred Data
 
@@ -159,4 +225,4 @@ The following is a high-level overview of how deferred data streaming works with
 - Client
   - The suspended placeholder promises within `<Await>` are resolved with the streamed data/error responses and either render the result or throw the error to the nearest error boundary
 
-[//]: # 'SSRContent'
+<!-- ::end:framework -->
diff --git a/docs/router/framework/react/guide/document-head-management.md b/docs/router/guide/document-head-management.md
similarity index 77%
rename from docs/router/framework/react/guide/document-head-management.md
rename to docs/router/guide/document-head-management.md
index fdf63656fd..cf66544a4a 100644
--- a/docs/router/framework/react/guide/document-head-management.md
+++ b/docs/router/guide/document-head-management.md
@@ -2,13 +2,13 @@
 title: Document Head Management
 ---
 
-Document head management is the process of managing the head, title, meta, link, and script tags of a document and TanStack Router provides a robust way to manage the document head for full-stack applications that use Start and for single-page applications that use `@tanstack/react-router`. It provides:
+Document head management is the process of managing the head, title, meta, link, and script tags of a document and TanStack Router provides a robust way to manage the document head for full-stack applications that use Start and for single-page applications that use TanStack Router. It provides:
 
 - Automatic deduping of `title` and `meta` tags
 - Automatic loading/unloading of tags based on route visibility
 - A composable way to merge `title` and `meta` tags from nested routes
 
-For full-stack applications that use Start, and even for single-page applications that use `@tanstack/react-router`, managing the document head is a crucial part of any application for the following reasons:
+For full-stack applications that use Start, and even for single-page applications that use TanStack Router, managing the document head is a crucial part of any application for the following reasons:
 
 - SEO
 - Social media sharing
@@ -70,6 +70,10 @@ It should be **rendered either in the `<head>` tag of your root layout or as hig
 
 ### Start/Full-Stack Applications
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { HeadContent } from '@tanstack/react-router'
 
@@ -87,10 +91,35 @@ export const Route = createRootRoute({
 })
 ```
 
+# Solid
+
+```tsx
+import { HeadContent } from '@tanstack/solid-router'
+
+export const Route = createRootRoute({
+  component: () => (
+    <html>
+      <head>
+        <HeadContent />
+      </head>
+      <body>
+        <Outlet />
+      </body>
+    </html>
+  ),
+})
+```
+
+<!-- ::end:framework -->
+
 ### Single-Page Applications
 
 First, remove the `<title>` tag from the index.html if you have set any.
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { HeadContent } from '@tanstack/react-router'
 
@@ -104,6 +133,23 @@ const rootRoute = createRootRoute({
 })
 ```
 
+# Solid
+
+```tsx
+import { HeadContent } from '@tanstack/solid-router'
+
+const rootRoute = createRootRoute({
+  component: () => (
+    <>
+      <HeadContent />
+      <Outlet />
+    </>
+  ),
+})
+```
+
+<!-- ::end:framework -->
+
 ## Managing Body Scripts
 
 In addition to scripts that can be rendered in the `<head>` tag, you can also render scripts in the `<body>` tag using the `routeOptions.scripts` property. This is useful for loading scripts (even inline scripts) that require the DOM to be loaded, but before the main entry point of your application (which includes hydration if you're using Start or a full-stack implementation of TanStack Router).
@@ -129,9 +175,13 @@ The `<Scripts />` component is **required** to render the body scripts of a docu
 
 ### Example
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
-import { createFileRoute, Scripts } from '@tanstack/react-router'
-export const Router = createFileRoute('/')({
+import { createRootRoute, Scripts } from '@tanstack/react-router'
+export const Route = createFileRoute('/')({
   component: () => (
     <html>
       <head />
@@ -144,23 +194,33 @@ export const Router = createFileRoute('/')({
 })
 ```
 
-```tsx
-import { Scripts, createRootRoute } from '@tanstack/react-router'
+# Solid
 
-export const Route = createRootRoute({
+```tsx
+import { createFileRoute, Scripts } from '@tanstack/solid-router'
+export const Route = createRootRoute('/')({
   component: () => (
-    <>
-      <Outlet />
-      <Scripts />
-    </>
+    <html>
+      <head />
+      <body>
+        <Outlet />
+        <Scripts />
+      </body>
+    </html>
   ),
 })
 ```
 
+<!-- ::end:framework -->
+
 ## Inline Scripts with ScriptOnce
 
 For scripts that must run before React hydrates (like theme detection), use `ScriptOnce`. This is particularly useful for avoiding flash of unstyled content (FOUC) or theme flicker.
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { ScriptOnce } from '@tanstack/react-router'
 
@@ -184,6 +244,33 @@ function ThemeProvider({ children }) {
 }
 ```
 
+# Solid
+
+```tsx
+import { ScriptOnce } from '@tanstack/solid-router'
+
+const themeScript = `(function() {
+  try {
+    const theme = localStorage.getItem('theme') || 'auto';
+    const resolved = theme === 'auto'
+      ? (matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
+      : theme;
+    document.documentElement.classList.add(resolved);
+  } catch (e) {}
+})();`
+
+function ThemeProvider({ children }) {
+  return (
+    <>
+      <ScriptOnce children={themeScript} />
+      {children}
+    </>
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 ### How ScriptOnce Works
 
 1. During SSR, renders a `<script>` tag with the provided code
@@ -191,6 +278,10 @@ function ThemeProvider({ children }) {
 3. After execution, the script removes itself from the DOM
 4. On client-side navigation, nothing is rendered (prevents duplicate execution)
 
+<!-- ::start:framework -->
+
+# React
+
 ### Preventing Hydration Warnings
 
 If your script modifies the DOM before hydration (like adding a class to `<html>`), use `suppressHydrationWarning` to prevent React warnings:
@@ -213,6 +304,8 @@ export const Route = createRootRoute({
 })
 ```
 
+<!-- ::end:framework -->
+
 ### Common Use Cases
 
 - **Theme/dark mode detection** - Apply theme class before hydration to prevent flash
diff --git a/docs/router/framework/react/guide/external-data-loading.md b/docs/router/guide/external-data-loading.md
similarity index 100%
rename from docs/router/framework/react/guide/external-data-loading.md
rename to docs/router/guide/external-data-loading.md
diff --git a/docs/router/framework/react/guide/history-types.md b/docs/router/guide/history-types.md
similarity index 65%
rename from docs/router/framework/react/guide/history-types.md
rename to docs/router/guide/history-types.md
index c65afccd27..9e20736854 100644
--- a/docs/router/framework/react/guide/history-types.md
+++ b/docs/router/guide/history-types.md
@@ -12,6 +12,10 @@ If you don't create a history instance, a browser-oriented instance of this API
 
 Once you have a history instance, you can pass it to the `Router` constructor:
 
+<!-- ::start:framework -->
+
+# React
+
 ```ts
 import { createMemoryHistory, createRouter } from '@tanstack/react-router'
 
@@ -22,6 +26,20 @@ const memoryHistory = createMemoryHistory({
 const router = createRouter({ routeTree, history: memoryHistory })
 ```
 
+# Solid
+
+```ts
+import { createMemoryHistory, createRouter } from '@tanstack/solid-router'
+
+const memoryHistory = createMemoryHistory({
+  initialEntries: ['/'], // Pass your initial url
+})
+
+const router = createRouter({ routeTree, history: memoryHistory })
+```
+
+<!-- ::end:framework -->
+
 ## Browser Routing
 
 The `createBrowserHistory` is the default history type. It uses the browser's history API to manage the browser history.
@@ -30,6 +48,10 @@ The `createBrowserHistory` is the default history type. It uses the browser's hi
 
 Hash routing can be helpful if your server doesn't support rewrites to index.html for HTTP requests (among other environments that don't have a server).
 
+<!-- ::start:framework -->
+
+# React
+
 ```ts
 import { createHashHistory, createRouter } from '@tanstack/react-router'
 
@@ -38,10 +60,26 @@ const hashHistory = createHashHistory()
 const router = createRouter({ routeTree, history: hashHistory })
 ```
 
+# Solid
+
+```ts
+import { createHashHistory, createRouter } from '@tanstack/solid-router'
+
+const hashHistory = createHashHistory()
+
+const router = createRouter({ routeTree, history: hashHistory })
+```
+
+<!-- ::end:framework -->
+
 ## Memory Routing
 
 Memory routing is useful in environments that are not a browser or when you do not want components to interact with the URL.
 
+<!-- ::start:framework -->
+
+# React
+
 ```ts
 import { createMemoryHistory, createRouter } from '@tanstack/react-router'
 
@@ -52,4 +90,18 @@ const memoryHistory = createMemoryHistory({
 const router = createRouter({ routeTree, history: memoryHistory })
 ```
 
-Refer to the [SSR Guide](./ssr.md#server-history) for usage on the server for server-side rendering.
+# Solid
+
+```ts
+import { createMemoryHistory, createRouter } from '@tanstack/solid-router'
+
+const memoryHistory = createMemoryHistory({
+  initialEntries: ['/'], // Pass your initial url
+})
+
+const router = createRouter({ routeTree, history: memoryHistory })
+```
+
+<!-- ::end:framework -->
+
+Refer to the [SSR Guide](./ssr.md#automatic-server-history) for usage on the server for server-side rendering.
diff --git a/docs/router/framework/react/guide/internationalization-i18n.md b/docs/router/guide/internationalization-i18n.md
similarity index 100%
rename from docs/router/framework/react/guide/internationalization-i18n.md
rename to docs/router/guide/internationalization-i18n.md
diff --git a/docs/router/framework/react/guide/link-options.md b/docs/router/guide/link-options.md
similarity index 100%
rename from docs/router/framework/react/guide/link-options.md
rename to docs/router/guide/link-options.md
diff --git a/docs/router/framework/react/guide/navigation-blocking.md b/docs/router/guide/navigation-blocking.md
similarity index 63%
rename from docs/router/framework/react/guide/navigation-blocking.md
rename to docs/router/guide/navigation-blocking.md
index 5fa852301e..aa0dd72d0e 100644
--- a/docs/router/framework/react/guide/navigation-blocking.md
+++ b/docs/router/guide/navigation-blocking.md
@@ -33,7 +33,9 @@ There are 2 ways to use navigation blocking:
 
 Let's imagine we want to prevent navigation if a form is dirty. We can do this by using the `useBlocker` hook:
 
-[//]: # 'HookBasedBlockingExample'
+<!-- ::start:framework -->
+
+# React
 
 ```tsx
 import { useBlocker } from '@tanstack/react-router'
@@ -54,10 +56,35 @@ function MyComponent() {
 }
 ```
 
-[//]: # 'HookBasedBlockingExample'
+# Solid
+
+```tsx
+import { useBlocker } from '@tanstack/solid-router'
+
+function MyComponent() {
+  const [formIsDirty, setFormIsDirty] = createSignal(false)
+
+  useBlocker({
+    shouldBlockFn: () => {
+      if (!formIsDirty()) return false
+
+      const shouldLeave = confirm('Are you sure you want to leave?')
+      return !shouldLeave
+    },
+  })
+
+  // ...
+}
+```
+
+<!-- ::end:framework -->
 
 `shouldBlockFn` gives you type safe access to the `current` and `next` location:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { useBlocker } from '@tanstack/react-router'
 
@@ -79,9 +106,36 @@ function MyComponent() {
 }
 ```
 
+# Solid
+
+```tsx
+import { useBlocker } from '@tanstack/solid-router'
+
+function MyComponent() {
+  // always block going from /foo to /bar/123?hello=world
+  const { proceed, reset, status } = useBlocker({
+    shouldBlockFn: ({ current, next }) => {
+      return (
+        current.routeId === '/foo' &&
+        next.fullPath === '/bar/$id' &&
+        next.params.id === 123 &&
+        next.search.hello === 'world'
+      )
+    },
+    withResolver: true,
+  })
+
+  // ...
+}
+```
+
+<!-- ::end:framework -->
+
 Note that even if `shouldBlockFn` returns `false`, the browser's `beforeunload` event may still be triggered on page reloads or tab closing. To gain control over this, you can use the `enableBeforeUnload` option to conditionally register the `beforeunload` handler:
 
-[//]: # 'HookBasedBlockingExample'
+<!-- ::start:framework -->
+
+# React
 
 ```tsx
 import { useBlocker } from '@tanstack/react-router'
@@ -98,16 +152,37 @@ function MyComponent() {
 }
 ```
 
+# Solid
+
+```tsx
+import { useBlocker } from '@tanstack/solid-router'
+
+function MyComponent() {
+  const [formIsDirty, setFormIsDirty] = useState(false)
+
+  useBlocker({
+    {/* ... */}
+    enableBeforeUnload: formIsDirty(),
+  })
+
+  // ...
+}
+```
+
+<!-- ::end:framework -->
+
 You can find more information about the `useBlocker` hook in the [API reference](../api/router/useBlockerHook.md).
 
 ## Component-based blocking
 
 In addition to logical/hook based blocking, you can use the `Block` component to achieve similar results:
 
-[//]: # 'ComponentBasedBlockingExample'
+<!-- ::start:framework -->
+
+# React
 
 ```tsx
-import { Block } from '@tanstack/react-router'
+import { Block } from '@tanstack/solid-router'
 
 function MyComponent() {
   const [formIsDirty, setFormIsDirty] = useState(false)
@@ -138,7 +213,36 @@ function MyComponent() {
 }
 ```
 
-[//]: # 'ComponentBasedBlockingExample'
+# Solid
+
+```tsx
+import { Block } from '@tanstack/solid-router'
+
+function MyComponent() {
+  const [formIsDirty, setFormIsDirty] = createSignal(false)
+
+  return (
+    <Block
+      shouldBlockFn={() => {
+        if (!formIsDirty()) return false
+
+        const shouldLeave = confirm('Are you sure you want to leave?')
+        return !shouldLeave
+      }}
+    />
+  )
+
+  // OR
+
+  return (
+    <Block shouldBlockFn={() => !formIsDirty} withResolver>
+      {({ status, proceed, reset }) => <>{/* ... */}</>}
+    </Block>
+  )
+}
+```
+
+<!-- ::end:framework -->
 
 ## How can I show a custom UI?
 
@@ -150,7 +254,9 @@ However, in some situations, you might want to show a custom UI that is intentio
 
 ### Hook/logical-based custom UI with resolver
 
-[//]: # 'HookBasedCustomUIBlockingWithResolverExample'
+<!-- ::start:framework -->
+
+# React
 
 ```tsx
 import { useBlocker } from '@tanstack/react-router'
@@ -179,11 +285,42 @@ function MyComponent() {
 }
 ```
 
-[//]: # 'HookBasedCustomUIBlockingWithResolverExample'
+# Solid
+
+```tsx
+import { useBlocker } from '@tanstack/solid-router'
+
+function MyComponent() {
+  const [formIsDirty, setFormIsDirty] = createSignal(false)
+
+  const { proceed, reset, status } = useBlocker({
+    shouldBlockFn: () => formIsDirty(),
+    withResolver: true,
+  })
+
+  // ...
+
+  return (
+    <>
+      {/* ... */}
+      {status === 'blocked' && (
+        <div>
+          <p>Are you sure you want to leave?</p>
+          <button onClick={proceed}>Yes</button>
+          <button onClick={reset}>No</button>
+        </div>
+      )}
+    </>
+}
+```
+
+<!-- ::end:framework -->
 
 ### Hook/logical-based custom UI without resolver
 
-[//]: # 'HookBasedCustomUIBlockingWithoutResolverExample'
+<!-- ::start:framework -->
+
+# React
 
 ```tsx
 import { useBlocker } from '@tanstack/react-router'
@@ -224,13 +361,56 @@ function MyComponent() {
 }
 ```
 
-[//]: # 'HookBasedCustomUIBlockingWithoutResolverExample'
+# Solid
+
+```tsx
+import { useBlocker } from '@tanstack/solid-router'
+
+function MyComponent() {
+  const [formIsDirty, setFormIsDirty] = createSignal(false)
+
+  useBlocker({
+    shouldBlockFn: () => {
+      if (!formIsDirty()) {
+        return false
+      }
+
+      const shouldBlock = new Promise<boolean>((resolve) => {
+        // Using a modal manager of your choice
+        modals.open({
+          title: 'Are you sure you want to leave?',
+          children: (
+            <SaveBlocker
+              confirm={() => {
+                modals.closeAll()
+                resolve(false)
+              }}
+              reject={() => {
+                modals.closeAll()
+                resolve(true)
+              }}
+            />
+          ),
+          onClose: () => resolve(true),
+        })
+      })
+      return shouldBlock
+    },
+  })
+
+  // ...
+}
+```
+
+<!-- ::end:framework -->
 
 ### Component-based custom UI
 
 Similarly to the hook, the `Block` component returns the same state and functions as render props:
 
-[//]: # 'ComponentBasedCustomUIBlockingExample'
+<!-- ::start:framework -->
+
+# React
 
 ```tsx
 import { Block } from '@tanstack/react-router'
@@ -257,4 +437,31 @@ function MyComponent() {
 }
 ```
 
-[//]: # 'ComponentBasedCustomUIBlockingExample'
+# Solid
+
+```tsx
+import { Block } from '@tanstack/solid-router'
+
+function MyComponent() {
+  const [formIsDirty, setFormIsDirty] = createSignal(false)
+
+  return (
+    <Block shouldBlockFn={() => formIsDirty()} withResolver>
+      {({ status, proceed, reset }) => (
+        <>
+          {/* ... */}
+          {status === 'blocked' && (
+            <div>
+              <p>Are you sure you want to leave?</p>
+              <button onClick={proceed}>Yes</button>
+              <button onClick={reset}>No</button>
+            </div>
+          )}
+        </>
+      )}
+    </Block>
+  )
+}
+```
+
+<!-- ::end:framework -->
diff --git a/docs/router/framework/react/guide/navigation.md b/docs/router/guide/navigation.md
similarity index 99%
rename from docs/router/framework/react/guide/navigation.md
rename to docs/router/guide/navigation.md
index d40829ada7..5e7d1d332a 100644
--- a/docs/router/framework/react/guide/navigation.md
+++ b/docs/router/guide/navigation.md
@@ -154,12 +154,26 @@ export type LinkProps<
 
 Let's make a simple static link!
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { Link } from '@tanstack/react-router'
 
 const link = <Link to="/about">About</Link>
 ```
 
+# Solid
+
+```tsx
+import { Link } from '@tanstack/solid-router'
+
+const link = <Link to="/about">About</Link>
+```
+
+<!-- ::end:framework -->
+
 ### Dynamic Links
 
 Dynamic links are links that have dynamic segments in them. For example, a link to a blog post might look like this:
diff --git a/docs/router/framework/react/guide/not-found-errors.md b/docs/router/guide/not-found-errors.md
similarity index 99%
rename from docs/router/framework/react/guide/not-found-errors.md
rename to docs/router/guide/not-found-errors.md
index ed156cb99d..b4c6bc59a6 100644
--- a/docs/router/framework/react/guide/not-found-errors.md
+++ b/docs/router/guide/not-found-errors.md
@@ -208,8 +208,6 @@ export const Route = createFileRoute('/_pathless/route-a')({
 You can also target the root route by passing the exported `rootRouteId` variable to the `notFound` function's `route` property:
 
 ```tsx
-import { rootRouteId } from '@tanstack/react-router'
-
 export const Route = createFileRoute('/posts/$postId')({
   loader: async ({ params: { postId } }) => {
     const post = await getPost(postId)
@@ -274,8 +272,7 @@ The main differences are:
 
 To migrate from `NotFoundRoute` to `notFoundComponent`, you'll just need to make a few changes:
 
-```tsx
-// router.tsx
+```tsx title='src/router.tsx'
 import { createRouter } from '@tanstack/react-router'
 import { routeTree } from './routeTree.gen.'
 - import { notFoundRoute } from './notFoundRoute'  // [!code --]
diff --git a/docs/router/framework/react/guide/outlets.md b/docs/router/guide/outlets.md
similarity index 73%
rename from docs/router/framework/react/guide/outlets.md
rename to docs/router/guide/outlets.md
index 4d92476bff..56122b5e7f 100644
--- a/docs/router/framework/react/guide/outlets.md
+++ b/docs/router/guide/outlets.md
@@ -13,6 +13,10 @@ The `Outlet` component is used to render the next potentially matching child rou
 
 A great example is configuring the root route of your application. Let's give our root route a component that renders a title, then an `<Outlet />` for our top-level routes to render.
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { createRootRoute, Outlet } from '@tanstack/react-router'
 
@@ -29,3 +33,24 @@ function RootComponent() {
   )
 }
 ```
+
+# Solid
+
+```tsx
+import { createRootRoute, Outlet } from '@tanstack/solid-router'
+
+export const Route = createRootRoute({
+  component: RootComponent,
+})
+
+function RootComponent() {
+  return (
+    <div>
+      <h1>My App</h1>
+      <Outlet /> {/* This is where child routes will render */}
+    </div>
+  )
+}
+```
+
+<!-- ::end:framework -->
diff --git a/docs/router/framework/react/guide/parallel-routes.md b/docs/router/guide/parallel-routes.md
similarity index 100%
rename from docs/router/framework/react/guide/parallel-routes.md
rename to docs/router/guide/parallel-routes.md
diff --git a/docs/router/framework/react/guide/path-params.md b/docs/router/guide/path-params.md
similarity index 59%
rename from docs/router/framework/react/guide/path-params.md
rename to docs/router/guide/path-params.md
index 4ebd477ace..7755047b13 100644
--- a/docs/router/framework/react/guide/path-params.md
+++ b/docs/router/guide/path-params.md
@@ -15,9 +15,11 @@ Because path param routes only match to the next `/`, child routes can be create
 
 Let's create a post route file that uses a path param to match the post ID:
 
-- `posts.$postId.tsx`
+<!-- ::start:framework -->
 
-```tsx
+# React
+
+```tsx title="src/routes/posts.$postId.tsx"
 import { createFileRoute } from '@tanstack/react-router'
 
 export const Route = createFileRoute('/posts/$postId')({
@@ -27,6 +29,20 @@ export const Route = createFileRoute('/posts/$postId')({
 })
 ```
 
+# Solid
+
+```tsx title="src/routes/posts.$postId.tsx"
+import { createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/posts/$postId')({
+  loader: async ({ params }) => {
+    return fetchPost(params.postId)
+  },
+})
+```
+
+<!-- ::end:framework -->
+
 ## Path Params can be used by child routes
 
 Once a path param has been parsed, it is available to all child routes. This means that if we define a child route to our `postRoute`, we can use the `postId` variable from the URL in the child route's path!
@@ -35,7 +51,7 @@ Once a path param has been parsed, it is available to all child routes. This mea
 
 Path params are passed to the loader as a `params` object. The keys of this object are the names of the path params, and the values are the values that were parsed out of the actual URL path. For example, if we were to visit the `/blog/123` URL, the `params` object would be `{ postId: '123' }`:
 
-```tsx
+```tsx title="src/routes/posts.$postId.tsx"
 export const Route = createFileRoute('/posts/$postId')({
   loader: async ({ params }) => {
     return fetchPost(params.postId)
@@ -45,7 +61,7 @@ export const Route = createFileRoute('/posts/$postId')({
 
 The `params` object is also passed to the `beforeLoad` option:
 
-```tsx
+```tsx title="src/routes/posts.$postId.tsx"
 export const Route = createFileRoute('/posts/$postId')({
   beforeLoad: async ({ params }) => {
     // do something with params.postId
@@ -57,7 +73,11 @@ export const Route = createFileRoute('/posts/$postId')({
 
 If we add a component to our `postRoute`, we can access the `postId` variable from the URL by using the route's `useParams` hook:
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/posts.$postId.tsx"
 export const Route = createFileRoute('/posts/$postId')({
   component: PostComponent,
 })
@@ -68,19 +88,49 @@ function PostComponent() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/posts.$postId.tsx"
+export const Route = createFileRoute('/posts/$postId')({
+  component: PostComponent,
+})
+
+function PostComponent() {
+  const params = Route.useParams()
+  return <div>Post {params().postId}</div>
+}
+```
+
+<!-- ::end:framework -->
+
 > 🧠 Quick tip: If your component is code-split, you can use the [getRouteApi function](./code-splitting.md#manually-accessing-route-apis-in-other-files-with-the-getrouteapi-helper) to avoid having to import the `Route` configuration to get access to the typed `useParams()` hook.
 
 ## Path Params outside of Routes
 
 You can also use the globally exported `useParams` hook to access any parsed path params from any component in your app. You'll need to pass the `strict: false` option to `useParams`, denoting that you want to access the params from an ambiguous location:
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/components/PostComponent.tsx"
 function PostComponent() {
   const { postId } = useParams({ strict: false })
   return <div>Post {postId}</div>
 }
 ```
 
+# Solid
+
+```tsx title="src/components/PostComponent.tsx"
+function PostComponent() {
+  const params = useParams({ strict: false })
+  return <div>Post {params().postId}</div>
+}
+```
+
+<!-- ::end:framework -->
+
 ## Navigating with Path Params
 
 When navigating to a route with path params, TypeScript will require you to pass the params either as an object or as a function that returns an object of params.
@@ -121,8 +171,11 @@ When using either prefixes or suffixes, you can define them by wrapping the path
 
 Prefixes are defined by placing the prefix text outside the curly braces before the variable name. For example, if you want to match a URL that starts with `post-` followed by a post ID, you can define it like this:
 
-```tsx
-// src/routes/posts/post-{$postId}.tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/posts/post-{$postId}.tsx"
 export const Route = createFileRoute('/posts/post-{$postId}')({
   component: PostComponent,
 })
@@ -134,10 +187,29 @@ function PostComponent() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/posts/post-{$postId}.tsx"
+export const Route = createFileRoute('/posts/post-{$postId}')({
+  component: PostComponent,
+})
+
+function PostComponent() {
+  const params = Route.useParams()
+  // postId will be the value after 'post-'
+  return <div>Post ID: {params().postId}</div>
+}
+```
+
+<!-- ::end:framework -->
+
 You can even combines prefixes with wildcard routes to create more complex patterns:
 
-```tsx
-// src/routes/on-disk/storage-{$}
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/on-disk/storage-{$postId}/$.tsx"
 export const Route = createFileRoute('/on-disk/storage-{$postId}/$')({
   component: StorageComponent,
 })
@@ -150,12 +222,32 @@ function StorageComponent() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/on-disk/storage-{$postId}/$.tsx"
+export const Route = createFileRoute('/on-disk/storage-{$postId}/$')({
+  component: StorageComponent,
+})
+
+function StorageComponent() {
+  const params = Route.useParams()
+  // _splat, will be value after 'storage-'
+  // i.e. my-drive/documents/foo.txt
+  return <div>Storage Location: /{params()._splat}</div>
+}
+```
+
+<!-- ::end:framework -->
+
 ### Defining Suffixes
 
 Suffixes are defined by placing the suffix text outside the curly braces after the variable name. For example, if you want to match a URL a filename that ends with `txt`, you can define it like this:
 
-```tsx
-// src/routes/files/{$fileName}txt
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/files/{$fileName}.txt"
 export const Route = createFileRoute('/files/{$fileName}.txt')({
   component: FileComponent,
 })
@@ -167,10 +259,29 @@ function FileComponent() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/files/{$fileName}.txt"
+export const Route = createFileRoute('/files/{$fileName}.txt')({
+  component: FileComponent,
+})
+
+function FileComponent() {
+  const params = Route.useParams()
+  // fileName will be the value before 'txt'
+  return <div>File Name: {params().fileName}</div>
+}
+```
+
+<!-- ::end:framework -->
+
 You can also combine suffixes with wildcards for more complex routing patterns:
 
-```tsx
-// src/routes/files/{$}[.]txt
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/files/{$}[.]txt"
 export const Route = createFileRoute('/files/{$fileName}[.]txt')({
   component: FileComponent,
 })
@@ -182,12 +293,31 @@ function FileComponent() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/files/{$}[.]txt"
+export const Route = createFileRoute('/files/{$fileName}[.]txt')({
+  component: FileComponent,
+})
+
+function FileComponent() {
+  const params = Route.useParams()
+  // _splat will be the value before '.txt'
+  return <div>File Splat: {params()._splat}</div>
+}
+```
+
+<!-- ::end:framework -->
+
 ### Combining Prefixes and Suffixes
 
 You can combine both prefixes and suffixes to create very specific routing patterns. For example, if you want to match a URL that starts with `user-` and ends with `.json`, you can define it like this:
 
-```tsx
-// src/routes/users/user-{$userId}.json
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/users/user-{$userId}.json"
 export const Route = createFileRoute('/users/user-{$userId}.json')({
   component: UserComponent,
 })
@@ -199,6 +329,22 @@ function UserComponent() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/users/user-{$userId}.json"
+export const Route = createFileRoute('/users/user-{$userId}.json')({
+  component: UserComponent,
+})
+
+function UserComponent() {
+  const params = Route.useParams()
+  // userId will be the value between 'user-' and '.json'
+  return <div>User ID: {params().userId}</div>
+}
+```
+
+<!-- ::end:framework -->
+
 Similar to the previous examples, you can also use wildcards with prefixes and suffixes. Go wild!
 
 ## Optional Path Parameters
@@ -243,7 +389,11 @@ When an optional parameter is not present in the URL, its value will be `undefin
 
 Optional parameters work exactly like regular parameters in your components, but their values may be `undefined`:
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/posts/{-$category}.tsx"
 function PostsComponent() {
   const { category } = Route.useParams()
 
@@ -251,6 +401,22 @@ function PostsComponent() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/posts/{-$category}.tsx"
+function PostsComponent() {
+  const params = Route.useParams()
+
+  return (
+    <div>
+      {params().category ? `Posts in ${params().category}` : 'All Posts'}
+    </div>
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 ### Optional Parameters in Loaders
 
 Optional parameters are available in loaders and may be `undefined`:
@@ -285,8 +451,12 @@ export const Route = createFileRoute('/posts/{-$category}')({
 
 Optional parameters support prefix and suffix patterns:
 
-```tsx
-// File route: /files/prefix{-$name}.txt
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/files/prefix{-$name}.txt"
+// Route: /files/prefix{-$name}.txt
 // Matches: /files/prefix.txt and /files/prefixdocument.txt
 export const Route = createFileRoute('/files/prefix{-$name}.txt')({
   component: FileComponent,
@@ -298,11 +468,32 @@ function FileComponent() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/files/prefix{-$name}.txt"
+// Route: /files/prefix{-$name}.txt
+// Matches: /files/prefix.txt and /files/prefixdocument.txt
+export const Route = createFileRoute('/files/prefix{-$name}.txt')({
+  component: FileComponent,
+})
+
+function FileComponent() {
+  const params = Route.useParams()
+  return <div>File: {params().name || 'default'}</div>
+}
+```
+
+<!-- ::end:framework -->
+
 #### All Optional Parameters
 
 You can create routes where all parameters are optional:
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/{-$year}/{-$month}/{-$day}.tsx"
 // Route: /{-$year}/{-$month}/{-$day}
 // Matches: /, /2023, /2023/12, /2023/12/25
 export const Route = createFileRoute('/{-$year}/{-$month}/{-$day}')({
@@ -329,11 +520,46 @@ function DateComponent() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/{-$year}/{-$month}/{-$day}.tsx"
+// Route: /{-$year}/{-$month}/{-$day}
+// Matches: /, /2023, /2023/12, /2023/12/25
+export const Route = createFileRoute('/{-$year}/{-$month}/{-$day}')({
+  component: DateComponent,
+})
+
+function DateComponent() {
+  const params = Route.useParams()
+
+  if (!params().year) return <div>Select a year</div>
+  if (!params().month) return <div>Year: {params().year}</div>
+  if (!params().day)
+    return (
+      <div>
+        Month: {params().year}/{params().month}
+      </div>
+    )
+
+  return (
+    <div>
+      Date: {params().year}/{params().month}/{params().day}
+    </div>
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 #### Optional Parameters with Wildcards
 
 Optional parameters can be combined with wildcards for complex routing patterns:
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/docs/{-$version}/$.tsx"
 // Route: /docs/{-$version}/$
 // Matches: /docs/extra/path, /docs/v2/extra/path
 export const Route = createFileRoute('/docs/{-$version}/$')({
@@ -353,6 +579,29 @@ function DocsComponent() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/docs/{-$version}/$.tsx"
+// Route: /docs/{-$version}/$
+// Matches: /docs/extra/path, /docs/v2/extra/path
+export const Route = createFileRoute('/docs/{-$version}/$')({
+  component: DocsComponent,
+})
+
+function DocsComponent() {
+  const params = Route.useParams()
+
+  return (
+    <div>
+      Version: {params().version || 'latest'}
+      Path: {params()._splat}
+    </div>
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 ### Navigating with Optional Parameters
 
 When navigating to routes with optional parameters, you have fine-grained control over which parameters to include:
@@ -387,7 +636,11 @@ function Navigation() {
 
 TypeScript provides full type safety for optional parameters:
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/posts/{-$category}.tsx"
 function PostsComponent() {
   // TypeScript knows category might be undefined
   const { category } = Route.useParams() // category: string | undefined
@@ -414,6 +667,37 @@ function PostsComponent() {
 </Link>
 ```
 
+# Solid
+
+```tsx title="src/routes/posts/{-$category}.tsx"
+function PostsComponent() {
+  // TypeScript knows category might be undefined
+  const params = Route.useParams() // category: string | undefined
+
+  // Safe navigation
+  const categoryUpper = params().category?.toUpperCase()
+
+  return <div>{categoryUpper || 'All Categories'}</div>
+}
+
+// Navigation is type-safe and flexible
+<Link
+  to="/posts/{-$category}"
+  params={{ category: 'tech' }} // ✅ Valid - string
+>
+  Tech Posts
+</Link>
+
+<Link
+  to="/posts/{-$category}"
+  params={{ category: 123 }} // ✅ Valid - number (auto-stringified)
+>
+  Category 123
+</Link>
+```
+
+<!-- ::end:framework -->
+
 ## Internationalization (i18n) with Optional Path Parameters
 
 Optional path parameters are excellent for implementing internationalization (i18n) routing patterns. You can use prefix patterns to handle multiple languages while maintaining clean, SEO-friendly URLs.
@@ -422,7 +706,11 @@ Optional path parameters are excellent for implementing internationalization (i1
 
 Use optional language prefixes to support URLs like `/en/about`, `/fr/about`, or just `/about` (default language):
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/{-$locale}/about.tsx"
 // Route: /{-$locale}/about
 export const Route = createFileRoute('/{-$locale}/about')({
   component: AboutComponent,
@@ -453,6 +741,41 @@ function AboutComponent() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/{-$locale}/about.tsx"
+// Route: /{-$locale}/about
+export const Route = createFileRoute('/{-$locale}/about')({
+  component: AboutComponent,
+})
+
+function AboutComponent() {
+  const params = Route.useParams()
+  const currentLocale = params().locale || 'en' // Default to English
+
+  const content = {
+    en: { title: 'About Us', description: 'Learn more about our company.' },
+    fr: {
+      title: 'À Propos',
+      description: 'En savoir plus sur notre entreprise.',
+    },
+    es: {
+      title: 'Acerca de',
+      description: 'Conoce más sobre nuestra empresa.',
+    },
+  }
+
+  return (
+    <div>
+      <h1>{content[currentLocale]?.title}</h1>
+      <p>{content[currentLocale]?.description}</p>
+    </div>
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 This pattern matches:
 
 - `/about` (default locale)
@@ -464,7 +787,11 @@ This pattern matches:
 
 Combine optional parameters for more sophisticated i18n routing:
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/{-$locale}/blog/{-$category}/$slug.tsx"
 // Route: /{-$locale}/blog/{-$category}/$slug
 export const Route = createFileRoute('/{-$locale}/blog/{-$category}/$slug')({
   beforeLoad: async ({ params }) => {
@@ -504,6 +831,51 @@ function BlogPostComponent() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/{-$locale}/blog/{-$category}/$slug.tsx"
+// Route: /{-$locale}/blog/{-$category}/$slug
+export const Route = createFileRoute('/{-$locale}/blog/{-$category}/$slug')({
+  beforeLoad: async ({ params }) => {
+    const locale = params.locale || 'en'
+    const category = params.category
+
+    // Validate locale and category
+    const validLocales = ['en', 'fr', 'es', 'de']
+    if (locale && !validLocales.includes(locale)) {
+      throw new Error('Invalid locale')
+    }
+
+    return { locale, category }
+  },
+  loader: async ({ params, context }) => {
+    const { locale } = context
+    const { slug, category } = params
+
+    return fetchBlogPost({ slug, category, locale })
+  },
+  component: BlogPostComponent,
+})
+
+function BlogPostComponent() {
+  const params = Route.useParams()
+  const data = Route.useLoaderData()
+
+  return (
+    <article>
+      <h1>{data.title}</h1>
+      <p>
+        Category: {params().category || 'All'} | Language:{' '}
+        {params().locale || 'en'}
+      </p>
+      <div>{data.content}</div>
+    </article>
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 This supports URLs like:
 
 - `/blog/tech/my-post` (default locale, tech category)
@@ -515,7 +887,11 @@ This supports URLs like:
 
 Create language switchers using optional i18n parameters with function-style params:
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/components/LanguageSwitcher.tsx"
 function LanguageSwitcher() {
   const currentParams = useParams({ strict: false })
 
@@ -545,8 +921,45 @@ function LanguageSwitcher() {
 }
 ```
 
+# Solid
+
+```tsx title="src/components/LanguageSwitcher.tsx"
+function LanguageSwitcher() {
+  const currentParams = useParams({ strict: false })
+
+  const languages = [
+    { code: 'en', name: 'English' },
+    { code: 'fr', name: 'Français' },
+    { code: 'es', name: 'Español' },
+  ]
+
+  return (
+    <div class="language-switcher">
+      {languages.map(({ code, name }) => (
+        <Link
+          to="/{-$locale}/blog/{-$category}/$slug"
+          params={(prev) => ({
+            ...prev,
+            locale: code === 'en' ? undefined : code, // Remove 'en' for clean URLs
+          })}
+          class={currentParams().locale === code ? 'active' : ''}
+        >
+          {name}
+        </Link>
+      ))}
+    </div>
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 You can also create more sophisticated language switching logic:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 function AdvancedLanguageSwitcher() {
   const currentParams = useParams({ strict: false })
@@ -594,10 +1007,65 @@ function AdvancedLanguageSwitcher() {
 }
 ```
 
+# Solid
+
+```tsx
+function AdvancedLanguageSwitcher() {
+  const currentParams = useParams({ strict: false })
+
+  const handleLanguageChange = (newLocale: string) => {
+    return (prev: any) => {
+      // Preserve all existing params but update locale
+      const updatedParams = { ...prev }
+
+      if (newLocale === 'en') {
+        // Remove locale for clean English URLs
+        delete updatedParams.locale
+      } else {
+        updatedParams.locale = newLocale
+      }
+
+      return updatedParams
+    }
+  }
+
+  return (
+    <div class="language-switcher">
+      <Link
+        to="/{-$locale}/blog/{-$category}/$slug"
+        params={handleLanguageChange('fr')}
+      >
+        Français
+      </Link>
+
+      <Link
+        to="/{-$locale}/blog/{-$category}/$slug"
+        params={handleLanguageChange('es')}
+      >
+        Español
+      </Link>
+
+      <Link
+        to="/{-$locale}/blog/{-$category}/$slug"
+        params={handleLanguageChange('en')}
+      >
+        English
+      </Link>
+    </div>
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 ### Advanced i18n with Optional Parameters
 
 Organize i18n routes using optional parameters for flexible locale handling:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 // Route structure:
 // routes/
@@ -631,11 +1099,101 @@ export const Route = createFileRoute('/{-$locale}/about')({
 })
 ```
 
+# Solid
+
+```tsx
+// Route structure:
+// routes/
+//   {-$locale}/
+//     index.tsx        // /, /en, /fr
+//     about.tsx        // /about, /en/about, /fr/about
+//     blog/
+//       index.tsx      // /blog, /en/blog, /fr/blog
+//       $slug.tsx      // /blog/post, /en/blog/post, /fr/blog/post
+
+// routes/{-$locale}/index.tsx
+export const Route = createFileRoute('/{-$locale}/')({
+  component: HomeComponent,
+})
+
+function HomeComponent() {
+  const params = Route.useParams()
+  const isRTL = ['ar', 'he', 'fa'].includes(params().locale || '')
+
+  return (
+    <div dir={isRTL ? 'rtl' : 'ltr'}>
+      <h1>Welcome ({params().locale || 'en'})</h1>
+      {/* Localized content */}
+    </div>
+  )
+}
+
+// routes/{-$locale}/about.tsx
+export const Route = createFileRoute('/{-$locale}/about')({
+  component: AboutComponent,
+})
+```
+
+<!-- ::end:framework -->
+
 ### SEO and Canonical URLs
 
 Handle SEO for i18n routes properly:
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/{-$locale}/products/$id.tsx"
+export const Route = createFileRoute('/{-$locale}/products/$id')({
+  component: ProductComponent,
+  head: ({ params, loaderData }) => {
+    const locale = params.locale || 'en'
+    const product = loaderData
+
+    return {
+      title: product.title[locale] || product.title.en,
+      meta: [
+        {
+          name: 'description',
+          content: product.description[locale] || product.description.en,
+        },
+        {
+          property: 'og:locale',
+          content: locale,
+        },
+      ],
+      links: [
+        // Canonical URL (always use default locale format)
+        {
+          rel: 'canonical',
+          href: `https://example.com/products/${params.id}`,
+        },
+        // Alternate language versions
+        {
+          rel: 'alternate',
+          hreflang: 'en',
+          href: `https://example.com/products/${params.id}`,
+        },
+        {
+          rel: 'alternate',
+          hreflang: 'fr',
+          href: `https://example.com/fr/products/${params.id}`,
+        },
+        {
+          rel: 'alternate',
+          hreflang: 'es',
+          href: `https://example.com/es/products/${params.id}`,
+        },
+      ],
+    }
+  },
+})
+```
+
+# Solid
+
+```tsx title="src/routes/{-$locale}/products/$id.tsx"
 export const Route = createFileRoute('/{-$locale}/products/$id')({
   component: ProductComponent,
   head: ({ params, loaderData }) => {
@@ -682,11 +1240,17 @@ export const Route = createFileRoute('/{-$locale}/products/$id')({
 })
 ```
 
+<!-- ::end:framework -->
+
 ### Type Safety for i18n
 
 Ensure type safety for your i18n implementations:
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/{-$locale}/shop/{-$category}.tsx"
 // Define supported locales
 type Locale = 'en' | 'fr' | 'es' | 'de'
 
@@ -736,6 +1300,60 @@ function ShopComponent() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/{-$locale}/shop/{-$category}.tsx"
+// Define supported locales
+type Locale = 'en' | 'fr' | 'es' | 'de'
+
+// Type-safe locale validation
+function validateLocale(locale: string | undefined): locale is Locale {
+  return ['en', 'fr', 'es', 'de'].includes(locale as Locale)
+}
+
+export const Route = createFileRoute('/{-$locale}/shop/{-$category}')({
+  beforeLoad: async ({ params }) => {
+    const { locale } = params
+
+    // Type-safe locale validation
+    if (locale && !validateLocale(locale)) {
+      throw redirect({
+        to: '/shop/{-$category}',
+        params: { category: params.category },
+      })
+    }
+
+    return {
+      locale: (locale as Locale) || 'en',
+      isDefaultLocale: !locale || locale === 'en',
+    }
+  },
+  component: ShopComponent,
+})
+
+function ShopComponent() {
+  const params = Route.useParams()
+  const routeContext = Route.useRouteContext()
+
+  // TypeScript knows locale is Locale | undefined
+  // and we have validated it in beforeLoad
+
+  return (
+    <div>
+      <h1>Shop {params().category ? `- ${params().category}` : ''}</h1>
+      <p>Language: {params().locale || 'en'}</p>
+      {!routeContext().isDefaultLocale && (
+        <Link to="/shop/{-$category}" params={{ category: params().category }}>
+          View in English
+        </Link>
+      )}
+    </div>
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 Optional path parameters provide a powerful and flexible foundation for implementing internationalization in your TanStack Router applications. Whether you prefer prefix-based or combined approaches, you can create clean, SEO-friendly URLs while maintaining excellent developer experience and type safety.
 
 ## Allowed Characters
diff --git a/docs/router/framework/react/guide/preloading.md b/docs/router/guide/preloading.md
similarity index 76%
rename from docs/router/framework/react/guide/preloading.md
rename to docs/router/guide/preloading.md
index 5695245c75..453294ab6e 100644
--- a/docs/router/framework/react/guide/preloading.md
+++ b/docs/router/guide/preloading.md
@@ -27,6 +27,10 @@ If you need more control over preloading, caching and/or garbage collection of p
 
 The simplest way to preload routes for your application is to set the `defaultPreload` option to `intent` for your entire router:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { createRouter } from '@tanstack/react-router'
 
@@ -36,12 +40,29 @@ const router = createRouter({
 })
 ```
 
+# Solid
+
+```tsx
+import { createRouter } from '@tanstack/solid-router'
+
+const router = createRouter({
+  // ...
+  defaultPreload: 'intent',
+})
+```
+
+<!-- ::end:framework -->
+
 This will turn on `intent` preloading by default for all `<Link>` components in your application. You can also set the `preload` prop on individual `<Link>` components to override the default behavior.
 
 ## Preload Delay
 
 By default, preloading will start after **50ms** of the user hovering or touching a `<Link>` component. You can change this delay by setting the `defaultPreloadDelay` option on your router:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { createRouter } from '@tanstack/react-router'
 
@@ -51,6 +72,19 @@ const router = createRouter({
 })
 ```
 
+# Solid
+
+```tsx
+import { createRouter } from '@tanstack/solid-router'
+
+const router = createRouter({
+  // ...
+  defaultPreloadDelay: 100,
+})
+```
+
+<!-- ::end:framework -->
+
 You can also set the `preloadDelay` prop on individual `<Link>` components to override the default behavior on a per-link basis.
 
 ## Built-in Preloading & `preloadStaleTime`
@@ -59,6 +93,10 @@ If you're using the built-in loaders, you can control how long preloaded data is
 
 To change this, you can set the `defaultPreloadStaleTime` option on your router:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { createRouter } from '@tanstack/react-router'
 
@@ -68,6 +106,19 @@ const router = createRouter({
 })
 ```
 
+# Solid
+
+```tsx
+import { createRouter } from '@tanstack/solid-router'
+
+const router = createRouter({
+  // ...
+  defaultPreloadStaleTime: 10_000,
+})
+```
+
+<!-- ::end:framework -->
+
 Or, you can use the `routeOptions.preloadStaleTime` option on individual routes:
 
 ```tsx
@@ -87,6 +138,10 @@ To customize the preloading behavior in TanStack Router and fully leverage your
 
 For example:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { createRouter } from '@tanstack/react-router'
 
@@ -96,12 +151,29 @@ const router = createRouter({
 })
 ```
 
+# Solid
+
+```tsx
+import { createRouter } from '@tanstack/solid-router'
+
+const router = createRouter({
+  // ...
+  defaultPreloadStaleTime: 0,
+})
+```
+
+<!-- ::end:framework -->
+
 This would then allow you, for instance, to use an option like React Query's `staleTime` to control the freshness of your preloads.
 
 ## Preloading Manually
 
 If you need to manually preload a route, you can use the router's `preloadRoute` method. It accepts a standard TanStack `NavigateOptions` object and returns a promise that resolves when the route is preloaded.
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 function Component() {
   const router = useRouter()
@@ -125,8 +197,39 @@ function Component() {
 }
 ```
 
+# Solid
+
+```tsx
+function Component() {
+  const router = useRouter()
+
+  createEffect(() => {
+    async function preload() {
+      try {
+        const matches = await router.preloadRoute({
+          to: postRoute,
+          params: { id: 1 },
+        })
+      } catch (err) {
+        // Failed to preload route
+      }
+    }
+
+    preload()
+  })
+
+  return <div />
+}
+```
+
+<!-- ::end:framework -->
+
 If you need to preload only the JS chunk of a route, you can use the router's `loadRouteChunk` method. It accepts a route object and returns a promise that resolves when the route chunk is loaded.
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 function Component() {
   const router = useRouter()
@@ -151,3 +254,32 @@ function Component() {
   return <div />
 }
 ```
+
+# Solid
+
+```tsx
+function Component() {
+  const router = useRouter()
+
+  createEffect(() => {
+    async function preloadRouteChunks() {
+      try {
+        const postsRoute = router.routesByPath['/posts']
+        await Promise.all([
+          router.loadRouteChunk(router.routesByPath['/']),
+          router.loadRouteChunk(postsRoute),
+          router.loadRouteChunk(postsRoute.parentRoute),
+        ])
+      } catch (err) {
+        // Failed to preload route chunk
+      }
+    }
+
+    preloadRouteChunks()
+  })
+
+  return <div />
+}
+```
+
+<!-- ::end:framework -->
diff --git a/docs/router/framework/react/guide/render-optimizations.md b/docs/router/guide/render-optimizations.md
similarity index 100%
rename from docs/router/framework/react/guide/render-optimizations.md
rename to docs/router/guide/render-optimizations.md
diff --git a/docs/router/framework/react/guide/route-masking.md b/docs/router/guide/route-masking.md
similarity index 94%
rename from docs/router/framework/react/guide/route-masking.md
rename to docs/router/guide/route-masking.md
index b31647db81..a734b75e17 100644
--- a/docs/router/framework/react/guide/route-masking.md
+++ b/docs/router/guide/route-masking.md
@@ -93,7 +93,9 @@ function onOpenPhoto() {
 
 In addition to the imperative API, you can also use the Router's `routeMasks` option to declaratively mask routes. Instead of needing to pass the `mask` option to every `<Link>` or `navigate()` call, you can instead create a route mask on the Router to mask routes that match a certain pattern. Here's an example of the same route mask from above, but using the `routeMasks` option instead:
 
-// Use the following for the example below
+<!-- ::start:framework -->
+
+# React
 
 ```tsx
 import { createRouteMask } from '@tanstack/react-router'
@@ -113,6 +115,28 @@ const router = createRouter({
 })
 ```
 
+# Solid
+
+```tsx
+import { createRouteMask } from '@tanstack/solid-router'
+
+const photoModalToPhotoMask = createRouteMask({
+  routeTree,
+  from: '/photos/$photoId/modal',
+  to: '/photos/$photoId',
+  params: (prev) => ({
+    photoId: prev.photoId,
+  }),
+})
+
+const router = createRouter({
+  routeTree,
+  routeMasks: [photoModalToPhotoMask],
+})
+```
+
+<!-- ::end:framework -->
+
 When creating a route mask, you'll need to pass 1 argument with at least:
 
 - `routeTree` - The route tree that the route mask will be applied to
diff --git a/docs/router/framework/react/guide/router-context.md b/docs/router/guide/router-context.md
similarity index 72%
rename from docs/router/framework/react/guide/router-context.md
rename to docs/router/guide/router-context.md
index 9e02803de7..5fc4001010 100644
--- a/docs/router/framework/react/guide/router-context.md
+++ b/docs/router/guide/router-context.md
@@ -17,6 +17,10 @@ These are just suggested uses of the router context. You can use it for whatever
 
 Like everything else, the root router context is strictly typed. This type can be augmented via any route's `beforeLoad` option as it is merged down the route match tree. To constrain the type of the root router context, you must use the `createRootRouteWithContext<YourContextTypeHere>()(routeOptions)` function to create a new router context instead of the `createRootRoute()` function to create your root route. Here's an example:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import {
   createRootRouteWithContext,
@@ -42,6 +46,35 @@ const router = createRouter({
 })
 ```
 
+# Solid
+
+```tsx
+import {
+  createRootRouteWithContext,
+  createRouter,
+} from '@tanstack/solid-router'
+
+interface MyRouterContext {
+  user: User
+}
+
+// Use the routerContext to create your root route
+const rootRoute = createRootRouteWithContext<MyRouterContext>()({
+  component: App,
+})
+
+const routeTree = rootRoute.addChildren([
+  // ...
+])
+
+// Use the routerContext to create your router
+const router = createRouter({
+  routeTree,
+})
+```
+
+<!-- ::end:framework -->
+
 > [!TIP]
 > `MyRouterContext` only needs to contain content that will be passed directly to `createRouter` below. All other context added in `beforeLoad` will be inferred.
 
@@ -52,6 +85,10 @@ The router context is passed to the router at instantiation time. You can pass t
 > [!TIP]
 > If your context has any required properties, you will see a TypeScript error if you don't pass them in the initial router context. If all of your context properties are optional, you will not see a TypeScript error and passing the context will be optional. If you don't pass a router context, it defaults to `{}`.
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { createRouter } from '@tanstack/react-router'
 
@@ -67,10 +104,33 @@ const router = createRouter({
 })
 ```
 
+# Solid
+
+```tsx
+import { createRouter } from '@tanstack/solid-router'
+
+// Use the routerContext you created to create your router
+const router = createRouter({
+  routeTree,
+  context: {
+    user: {
+      id: '123',
+      name: 'John Doe',
+    },
+  },
+})
+```
+
+<!-- ::end:framework -->
+
 ### Invalidating the Router Context
 
 If you need to invalidate the context state you are passing into the router, you can call the `invalidate` method to tell the router to recompute the context. This is useful when you need to update the context state and have the router recompute the context for all routes.
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 function useAuth() {
   const router = useRouter()
@@ -89,6 +149,28 @@ function useAuth() {
 }
 ```
 
+# Solid
+
+```tsx
+function useAuth() {
+  const router = useRouter()
+  const [user, setUser] = createSignal<User | null>(null)
+
+  createEffect(() => {
+    const unsubscribe = auth.onAuthStateChanged((user) => {
+      setUser(user)
+      router.invalidate()
+    })
+
+    return unsubscribe
+  }, [])
+
+  return user()
+}
+```
+
+<!-- ::end:framework -->
+
 ## Using the Router Context
 
 Once you have defined the router context type, you can use it in your route definitions:
@@ -133,6 +215,10 @@ export const Route = createFileRoute('/todos')({
 
 ### How about an external data fetching library?
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import {
   createRootRouteWithContext,
@@ -157,6 +243,34 @@ const router = createRouter({
 })
 ```
 
+# Solid
+
+```tsx
+import {
+  createRootRouteWithContext,
+  createRouter,
+} from '@tanstack/solid-router'
+
+interface MyRouterContext {
+  queryClient: QueryClient
+}
+
+const rootRoute = createRootRouteWithContext<MyRouterContext>()({
+  component: App,
+})
+
+const queryClient = new QueryClient()
+
+const router = createRouter({
+  routeTree: rootRoute,
+  context: {
+    queryClient,
+  },
+})
+```
+
+<!-- ::end:framework -->
+
 Then, in your route:
 
 ```tsx
@@ -172,6 +286,10 @@ export const Route = createFileRoute('/todos')({
 })
 ```
 
+<!-- ::start:framework -->
+
+# React
+
 ## How about using React Context/Hooks?
 
 When trying to use React Context or Hooks in your route's `beforeLoad` or `loader` functions, it's important to remember React's [Rules of Hooks](https://react.dev/reference/rules/rules-of-hooks). You can't use hooks in a non-React function, so you can't use hooks in your `beforeLoad` or `loader` functions.
@@ -180,9 +298,9 @@ So, how do we use React Context or Hooks in our route's `beforeLoad` or `loader`
 
 Let's look at the setup for an example, where we pass down a `useNetworkStrength` hook to our route's `loader` function:
 
-- `src/routes/__root.tsx`
+<!-- ::start:tabs variant="files" -->
 
-```tsx
+```tsx title="src/routes/__root.tsx"
 // First, make sure the context for the root route is typed
 import { createRootRouteWithContext } from '@tanstack/react-router'
 import { useNetworkStrength } from '@/hooks/useNetworkStrength'
@@ -196,11 +314,13 @@ export const Route = createRootRouteWithContext<MyRouterContext>()({
 })
 ```
 
+<!-- ::end:tabs -->
+
 In this example, we'd instantiate the hook before rendering the router using the `<RouterProvider />`. This way, the hook would be called in React-land, therefore adhering to the Rules of Hooks.
 
-- `src/router.tsx`
+<!-- ::start:tabs variant="files" -->
 
-```tsx
+```tsx title="src/router.tsx"
 import { createRouter } from '@tanstack/react-router'
 
 import { routeTree } from './routeTree.gen'
@@ -213,9 +333,13 @@ export const router = createRouter({
 })
 ```
 
-- `src/main.tsx`
+<!-- ::end:tabs -->
 
-```tsx
+Then, we can call the `useNetworkStrength` hook in our `App` component and pass the returned value into the router context via the `<RouterProvider />`:
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/main.tsx"
 import { RouterProvider } from '@tanstack/react-router'
 import { router } from './router'
 
@@ -230,11 +354,13 @@ function App() {
 // ...
 ```
 
+<!-- ::end:tabs -->
+
 So, now in our route's `loader` function, we can access the `networkStrength` hook from the router context:
 
-- `src/routes/posts.tsx`
+<!-- ::start:tabs variant="files" -->
 
-```tsx
+```tsx title="src/routes/posts.tsx"
 import { createFileRoute } from '@tanstack/react-router'
 
 export const Route = createFileRoute('/posts')({
@@ -247,13 +373,21 @@ export const Route = createFileRoute('/posts')({
 })
 ```
 
+<!-- ::end:tabs -->
+
+<!-- ::end:framework -->
+
 ## Modifying the Router Context
 
 The router context is passed down the route tree and is merged at each route. This means that you can modify the context at each route and the modifications will be available to all child routes. Here's an example:
 
-- `src/routes/__root.tsx`
+<!-- ::start:framework -->
 
-```tsx
+# React
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/routes/__root.tsx"
 import { createRootRouteWithContext } from '@tanstack/react-router'
 
 interface MyRouterContext {
@@ -265,9 +399,11 @@ export const Route = createRootRouteWithContext<MyRouterContext>()({
 })
 ```
 
-- `src/router.tsx`
+<!-- ::end:tabs -->
 
-```tsx
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/router.tsx"
 import { createRouter } from '@tanstack/react-router'
 
 import { routeTree } from './routeTree.gen'
@@ -280,9 +416,11 @@ const router = createRouter({
 })
 ```
 
-- `src/routes/todos.tsx`
+<!-- ::end:tabs -->
 
-```tsx
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/routes/todos.tsx"
 import { createFileRoute } from '@tanstack/react-router'
 
 export const Route = createFileRoute('/todos')({
@@ -299,12 +437,71 @@ export const Route = createFileRoute('/todos')({
 })
 ```
 
+<!-- ::end:tabs -->
+
+# Solid
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/routes/__root.tsx"
+import { createRootRouteWithContext } from '@tanstack/solid-router'
+
+interface MyRouterContext {
+  foo: boolean
+}
+
+export const Route = createRootRouteWithContext<MyRouterContext>()({
+  component: App,
+})
+```
+
+<!-- ::end:tabs -->
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/router.tsx"
+import { createRouter } from '@tanstack/solid-router'
+
+import { routeTree } from './routeTree.gen'
+
+const router = createRouter({
+  routeTree,
+  context: {
+    foo: true,
+  },
+})
+```
+
+<!-- ::end:tabs -->
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/routes/todos.tsx"
+import { createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/todos')({
+  component: Todos,
+  beforeLoad: () => {
+    return {
+      bar: true,
+    }
+  },
+  loader: ({ context }) => {
+    context.foo // true
+    context.bar // true
+  },
+})
+```
+
+<!-- ::end:tabs -->
+
+<!-- ::end:framework -->
+
 ## Processing Accumulated Route Context
 
 Context, especially the isolated route `context` objects, make it trivial to accumulate and process the route context objects for all matched routes. Here's an example where we use all of the matched route contexts to generate a breadcrumb trail:
 
-```tsx
-// src/routes/__root.tsx
+```tsx title="src/routes/__root.tsx"
 export const Route = createRootRoute({
   component: () => {
     const matches = useRouterState({ select: (s) => s.matches })
@@ -325,8 +522,7 @@ export const Route = createRootRoute({
 
 Using that same route context, we could also generate a title tag for our page's `<head>`:
 
-```tsx
-// src/routes/__root.tsx
+```tsx title="src/routes/__root.tsx"
 export const Route = createRootRoute({
   component: () => {
     const matches = useRouterState({ select: (s) => s.matches })
diff --git a/docs/router/framework/react/guide/scroll-restoration.md b/docs/router/guide/scroll-restoration.md
similarity index 86%
rename from docs/router/framework/react/guide/scroll-restoration.md
rename to docs/router/guide/scroll-restoration.md
index 9aa5ec7f3b..2345091510 100644
--- a/docs/router/framework/react/guide/scroll-restoration.md
+++ b/docs/router/guide/scroll-restoration.md
@@ -55,8 +55,6 @@ It does this by:
 That may sound like a lot, but for you, it's as simple as this:
 
 ```tsx
-import { createRouter } from '@tanstack/react-router'
-
 const router = createRouter({
   scrollRestoration: true,
 })
@@ -80,8 +78,6 @@ The default `getKey` is `(location) => location.state.__TSR_key!`, where `__TSR_
 You could sync scrolling to the pathname:
 
 ```tsx
-import { createRouter } from '@tanstack/react-router'
-
 const router = createRouter({
   getScrollRestorationKey: (location) => location.pathname,
 })
@@ -90,8 +86,6 @@ const router = createRouter({
 You can conditionally sync only some paths, then use the key for the rest:
 
 ```tsx
-import { createRouter } from '@tanstack/react-router'
-
 const router = createRouter({
   getScrollRestorationKey: (location) => {
     const paths = ['/', '/chat']
@@ -118,8 +112,6 @@ Most of the time, you won't need to do anything special to get scroll restoratio
 
 To manually control scroll restoration for virtualized lists within the whole browser window:
 
-[//]: # 'VirtualizedWindowScrollRestorationExample'
-
 ```tsx
 function Component() {
   const scrollEntry = useElementScrollRestoration({
@@ -145,11 +137,11 @@ function Component() {
 }
 ```
 
-[//]: # 'VirtualizedWindowScrollRestorationExample'
-
 To manually control scroll restoration for a specific element, you can use the `useElementScrollRestoration` hook and the `data-scroll-restoration-id` DOM attribute:
 
-[//]: # 'ManualRestorationExample'
+<!-- ::start:framework -->
+
+# React
 
 ```tsx
 function Component() {
@@ -188,15 +180,52 @@ function Component() {
 }
 ```
 
-[//]: # 'ManualRestorationExample'
+# Solid
+
+```tsx
+function Component() {
+  // We need a unique ID for manual scroll restoration on a specific element
+  // It should be as unique as possible for this element across your app
+  const scrollRestorationId = 'myVirtualizedContent'
+
+  // We use that ID to get the scroll entry for this element
+  const scrollEntry = useElementScrollRestoration({
+    id: scrollRestorationId,
+  })
+
+  // Let's use TanStack Virtual to virtualize some content!
+  let virtualizerParentRef: any
+  const virtualizer = createVirtualizer({
+    count: 10000,
+    getScrollElement: () => virtualizerParentRef,
+    estimateSize: () => 100,
+    // We pass the scrollY from the scroll restoration entry to the virtualizer
+    // as the initial offset
+    initialOffset: scrollEntry?.scrollY,
+  })
+
+  return (
+    <div
+      ref={virtualizerParentRef}
+      // We pass the scroll restoration ID to the element
+      // as a custom attribute that will get picked up by the
+      // scroll restoration watcher
+      data-scroll-restoration-id={scrollRestorationId}
+      class="flex-1 border rounded-lg overflow-auto relative"
+    >
+      ...
+    </div>
+  )
+}
+```
+
+<!-- ::end:framework -->
 
 ## Scroll Behavior
 
 To control the scroll behavior when navigating between pages, you can use the `scrollRestorationBehavior` option. This allows you to make the transition between pages instant instead of a smooth scroll. The global configuration of scroll restoration behavior has the same options as those supported by the browser, which are `smooth`, `instant`, and `auto` (see [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView#behavior) for more information).
 
 ```tsx
-import { createRouter } from '@tanstack/react-router'
-
 const router = createRouter({
   scrollRestorationBehavior: 'instant',
 })
diff --git a/docs/router/framework/react/guide/search-params.md b/docs/router/guide/search-params.md
similarity index 91%
rename from docs/router/framework/react/guide/search-params.md
rename to docs/router/guide/search-params.md
index ce3096cefb..53e9cd1c8a 100644
--- a/docs/router/framework/react/guide/search-params.md
+++ b/docs/router/guide/search-params.md
@@ -90,9 +90,7 @@ Despite TanStack Router being able to parse search params into reliable JSON, th
 
 TanStack Router provides convenient APIs for validating and typing search params. This all starts with the `Route`'s `validateSearch` option:
 
-```tsx
-// /routes/shop.products.tsx
-
+```tsx title="src/routes/shop/products.tsx"
 type ProductSearchSortOptions = 'newest' | 'oldest' | 'price'
 
 type ProductSearch = {
@@ -121,9 +119,7 @@ The `validateSearch` option is a function that is provided the JSON parsed (but
 
 Here's an example:
 
-```tsx
-// /routes/shop.products.tsx
-
+```tsx title="src/routes/shop/products.tsx"
 type ProductSearchSortOptions = 'newest' | 'oldest' | 'price'
 
 type ProductSearch = {
@@ -146,9 +142,7 @@ export const Route = createFileRoute('/shop/products')({
 
 Here's an example using the [Zod](https://zod.dev/) library (but feel free to use any validation library you want) to both validate and type the search params in a single step:
 
-```tsx
-// /routes/shop.products.tsx
-
+```tsx title="src/routes/shop/products.tsx"
 import { z } from 'zod'
 
 const productSearchSchema = z.object({
@@ -179,7 +173,6 @@ The underlying mechanics why this works relies on the `validateSearch` function
 When using a library like [Zod](https://zod.dev/) to validate search params you might want to `transform` search params before committing the search params to the URL. A common `zod` `transform` is `default` for example.
 
 ```tsx
-import { createFileRoute } from '@tanstack/react-router'
 import { z } from 'zod'
 
 const productSearchSchema = z.object({
@@ -206,7 +199,6 @@ For validation libraries we recommend using adapters which infer the correct `in
 An adapter is provided for [Zod](https://zod.dev/) which will pipe through the correct `input` type and `output` type
 
 ```tsx
-import { createFileRoute } from '@tanstack/react-router'
 import { zodValidator } from '@tanstack/zod-adapter'
 import { z } from 'zod'
 
@@ -230,7 +222,6 @@ The important part here is the following use of `Link` no longer requires `searc
 However the use of `catch` here overrides the types and makes `page`, `filter` and `sort` `unknown` causing type loss. We have handled this case by providing a `fallback` generic function which retains the types but provides a `fallback` value when validation fails
 
 ```tsx
-import { createFileRoute } from '@tanstack/react-router'
 import { fallback, zodValidator } from '@tanstack/zod-adapter'
 import { z } from 'zod'
 
@@ -279,7 +270,6 @@ This provides flexibility in which type you want to infer for navigation and whi
 When using [Valibot](https://valibot.dev/) an adapter is not needed to ensure the correct `input` and `output` types are used for navigation and reading search params. This is because `valibot` implements [Standard Schema](https://github.com/standard-schema/standard-schema)
 
 ```tsx
-import { createFileRoute } from '@tanstack/react-router'
 import * as v from 'valibot'
 
 const productSearchSchema = v.object({
@@ -304,7 +294,6 @@ export const Route = createFileRoute('/shop/products/')({
 When using [ArkType](https://arktype.io/) an adapter is not needed to ensure the correct `input` and `output` types are used for navigation and reading search params. This is because [ArkType](https://arktype.io/) implements [Standard Schema](https://github.com/standard-schema/standard-schema)
 
 ```tsx
-import { createFileRoute } from '@tanstack/react-router'
 import { type } from 'arktype'
 
 const productSearchSchema = type({
@@ -323,7 +312,6 @@ export const Route = createFileRoute('/shop/products/')({
 When using [Effect/Schema](https://effect.website/docs/schema/introduction/) an adapter is not needed to ensure the correct `input` and `output` types are used for navigation and reading search params. This is because [Effect/Schema](https://effect.website/docs/schema/standard-schema/) implements [Standard Schema](https://github.com/standard-schema/standard-schema)
 
 ```tsx
-import { createFileRoute } from '@tanstack/react-router'
 import { Schema as S } from 'effect'
 
 const productSearchSchema = S.standardSchemaV1(
@@ -369,9 +357,9 @@ Please read the [Search Params in Loaders](./data-loading.md#using-loaderdeps-to
 
 The search parameters and types of parents are merged as you go down the route tree, so child routes also have access to their parent's search params:
 
-- `shop.products.tsx`
+<!-- ::start:tabs variant="files" -->
 
-```tsx
+```tsx title="src/routes/shop/products.tsx"
 const productSearchSchema = z.object({
   page: z.number().catch(1),
   filter: z.string().catch(''),
@@ -385,9 +373,7 @@ export const Route = createFileRoute('/shop/products')({
 })
 ```
 
-- `shop.products.$productId.tsx`
-
-```tsx
+```tsx title="src/routes/shop/products/$productId.tsx"
 export const Route = createFileRoute('/shop/products/$productId')({
   beforeLoad: ({ search }) => {
     search
@@ -396,13 +382,13 @@ export const Route = createFileRoute('/shop/products/$productId')({
 })
 ```
 
+<!-- ::end:tabs -->
+
 ### Search Params in Components
 
 You can access your route's validated search params in your route's `component` via the `useSearch` hook.
 
-```tsx
-// /routes/shop.products.tsx
-
+```tsx title="src/routes/shop/products.tsx"
 export const Route = createFileRoute('/shop/products')({
   validateSearch: productSearchSchema,
 })
@@ -422,7 +408,7 @@ const ProductList = () => {
 You can access your route's validated search params anywhere in your app using the `useSearch` hook. By passing the `from` id/path of your origin route, you'll get even better type safety:
 
 ```tsx
-// /routes/shop.products.tsx
+// src/routes/shop.products.tsx
 export const Route = createFileRoute('/shop/products')({
   validateSearch: productSearchSchema,
   // ...
@@ -430,7 +416,7 @@ export const Route = createFileRoute('/shop/products')({
 
 // Somewhere else...
 
-// /components/product-list-sidebar.tsx
+// src/components/product-list-sidebar.tsx
 const routeApi = getRouteApi('/shop/products')
 
 const ProductList = () => {
@@ -474,8 +460,7 @@ The best way to update search params is to use the `search` prop on the `<Link /
 If the search for the current page shall be updated and the `from` prop is specified, the `to` prop can be omitted.  
 Here's an example:
 
-```tsx
-// /routes/shop.products.tsx
+```tsx title="src/routes/shop/products.tsx"
 export const Route = createFileRoute('/shop/products')({
   validateSearch: productSearchSchema,
 })
@@ -531,8 +516,7 @@ const PageSelector = () => {
 
 The `navigate` function also accepts a `search` option that works the same way as the `search` prop on `<Link />`:
 
-```tsx
-// /routes/shop.products.tsx
+```tsx title="src/routes/shop/products.tsx"
 export const Route = createFileRoute('/shop/products/$productId')({
   validateSearch: productSearchSchema,
 })
@@ -576,7 +560,6 @@ The following example shows how to make sure that for **every** link that is bei
 
 ```tsx
 import { z } from 'zod'
-import { createFileRoute } from '@tanstack/react-router'
 import { zodValidator } from '@tanstack/zod-adapter'
 
 const searchSchema = z.object({
@@ -601,6 +584,10 @@ export const Route = createRootRoute({
 
 Since this specific use case is quite common, TanStack Router provides a generic implementation to retain search params via `retainSearchParams`:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { z } from 'zod'
 import { createFileRoute, retainSearchParams } from '@tanstack/react-router'
@@ -618,8 +605,33 @@ export const Route = createRootRoute({
 })
 ```
 
+# Solid
+
+```tsx
+import { z } from 'zod'
+import { createFileRoute, retainSearchParams } from '@tanstack/solid-router'
+import { zodValidator } from '@tanstack/zod-adapter'
+
+const searchSchema = z.object({
+  rootValue: z.string().optional(),
+})
+
+export const Route = createRootRoute({
+  validateSearch: zodValidator(searchSchema),
+  search: {
+    middlewares: [retainSearchParams(['rootValue'])],
+  },
+})
+```
+
+<!-- ::end:framework -->
+
 Another common use case is to strip out search params from links if their default value is set. TanStack Router provides a generic implementation for this use case via `stripSearchParams`:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { z } from 'zod'
 import { createFileRoute, stripSearchParams } from '@tanstack/react-router'
@@ -644,8 +656,40 @@ export const Route = createFileRoute('/hello')({
 })
 ```
 
+# Solid
+
+```tsx
+import { z } from 'zod'
+import { createFileRoute, stripSearchParams } from '@tanstack/solid-router'
+import { zodValidator } from '@tanstack/zod-adapter'
+
+const defaultValues = {
+  one: 'abc',
+  two: 'xyz',
+}
+
+const searchSchema = z.object({
+  one: z.string().default(defaultValues.one),
+  two: z.string().default(defaultValues.two),
+})
+
+export const Route = createFileRoute('/hello')({
+  validateSearch: zodValidator(searchSchema),
+  search: {
+    // strip default values
+    middlewares: [stripSearchParams(defaultValues)],
+  },
+})
+```
+
+<!-- ::end:framework -->
+
 Multiple middlewares can be chained. The following example shows how to combine both `retainSearchParams` and `stripSearchParams`.
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import {
   Link,
@@ -674,3 +718,36 @@ export const Route = createFileRoute('/search')({
   },
 })
 ```
+
+# Solid
+
+```tsx
+import {
+  Link,
+  createFileRoute,
+  retainSearchParams,
+  stripSearchParams,
+} from '@tanstack/solid-router'
+import { z } from 'zod'
+import { zodValidator } from '@tanstack/zod-adapter'
+
+const defaultValues = ['foo', 'bar']
+
+export const Route = createFileRoute('/search')({
+  validateSearch: zodValidator(
+    z.object({
+      retainMe: z.string().optional(),
+      arrayWithDefaults: z.string().array().default(defaultValues),
+      required: z.string(),
+    }),
+  ),
+  search: {
+    middlewares: [
+      retainSearchParams(['retainMe']),
+      stripSearchParams({ arrayWithDefaults: defaultValues }),
+    ],
+  },
+})
+```
+
+<!-- ::end:framework -->
diff --git a/docs/router/framework/react/guide/ssr.md b/docs/router/guide/ssr.md
similarity index 69%
rename from docs/router/framework/react/guide/ssr.md
rename to docs/router/guide/ssr.md
index 73ab21276f..b51f1f2f7d 100644
--- a/docs/router/framework/react/guide/ssr.md
+++ b/docs/router/guide/ssr.md
@@ -24,6 +24,10 @@ Non-Streaming server-side rendering is the classic process of rendering the mark
 
 To implement non-streaming SSR with TanStack Router, you will need the following utilities:
 
+<!-- ::start:framework -->
+
+# React
+
 - `RouterClient` from `@tanstack/react-router`
   - e.g. `<RouterClient router={router} />`
   - Rendering this component in your client entry will render your application and also automatically implement the `Wrap` component option on `Router`
@@ -36,6 +40,22 @@ To implement non-streaming SSR with TanStack Router, you will need the following
   - `RouterServer` from `@tanstack/react-router`
     - This implements the `Wrap` component option on `Router`
 
+# Solid
+
+- `RouterClient` from `@tanstack/solid-router`
+  - e.g. `<RouterClient router={router} />`
+  - Rendering this component in your client entry will render your application and also automatically implement the `Wrap` component option on `Router`
+- And, either:
+  - `defaultRenderHandler` from `@tanstack/solid-router`
+    - This will render your application in your server entry and also automatically handle application-level hydration/dehydration and also automatically implement the RouterServer component.
+      or:
+  - `renderRouterToString` from `@tanstack/solid-router`
+    - This differs from defaultRenderHandler in that it allows you to manually specify the `Wrap` component option on `Router` together with any other providers you may need to wrap it with.
+  - `RouterServer` from `@tanstack/solid-router`
+    - This implements the `Wrap` component option on `Router`
+
+<!-- ::end:framework -->
+
 ### Automatic Server History
 
 On the client, Router defaults to using an instance of `createBrowserHistory`, which is the preferred type of history to use on the client. On the server, however, you will want to use an instance of `createMemoryHistory` instead. This is because `createBrowserHistory` uses the `window` object, which does not exist on the server. This is handled automatically for you in the RouterServer component.
@@ -52,8 +72,11 @@ For more information on how to utilize data loading, see the [Data Loading](./da
 
 Since your router will exist both on the server and the client, it's important that you create your router in a way that is consistent between both of these environments. The easiest way to do this is to expose a `createRouter` function in a shared file that can be imported and called by both your server and client entry files.
 
-```tsx
-// src/router.tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title='src/router.tsx'
 import { createRouter as createTanstackRouter } from '@tanstack/react-router'
 import { routeTree } from './routeTree.gen'
 
@@ -68,14 +91,36 @@ declare module '@tanstack/react-router' {
 }
 ```
 
+# Solid
+
+```tsx title='src/router.tsx'
+import { createRouter as createTanstackRouter } from '@tanstack/solid-router'
+import { routeTree } from './routeTree.gen'
+
+export function createRouter() {
+  return createTanstackRouter({ routeTree })
+}
+
+declare module '@tanstack/solid-router' {
+  interface Register {
+    router: ReturnType<typeof createRouter>
+  }
+}
+```
+
+<!-- ::end:framework -->
+
 ### Rendering the Application on the Server
 
 Now that you have a router instance that has loaded all the critical data for the current URL, you can render your application on the server:
 
 using `defaultRenderHandler`
 
-```tsx
-// src/entry-server.tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/entry-server.tsx"
 import {
   createRequestHandler,
   defaultRenderToString,
@@ -89,10 +134,31 @@ export async function render({ request }: { request: Request }) {
 }
 ```
 
+# Solid
+
+```tsx title="src/entry-server.tsx"
+import {
+  createRequestHandler,
+  defaultRenderToString,
+} from '@tanstack/solid-router/ssr/server'
+import { createRouter } from './router'
+
+export async function render({ request }: { request: Request }) {
+  const handler = createRequestHandler({ request, createRouter })
+
+  return await handler(defaultRenderHandler)
+}
+```
+
+<!-- ::end:framework -->
+
 using `renderRouterToString`
 
-```tsx
-// src/entry-server.tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/entry-server.tsx"
 import {
   createRequestHandler,
   renderRouterToString,
@@ -114,6 +180,32 @@ export function render({ request }: { request: Request }) {
 }
 ```
 
+# Solid
+
+```tsx title="src/entry-server.tsx"
+import {
+  createRequestHandler,
+  renderRouterToString,
+  RouterServer,
+} from '@tanstack/react-router/ssr/server'
+import { createRouter } from './router'
+
+export function render({ request }: { request: Request }) {
+  const handler = createRequestHandler({ request, createRouter })
+
+  return handler(({ request, responseHeaders, router }) =>
+    renderRouterToString({
+      request,
+      responseHeaders,
+      router,
+      children: <RouterServer router={router} />,
+    }),
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 NOTE: The createRequestHandler method requires a web api standard Request object, while the handler method will return a web api standard Response promise.
 
 Should you be using a server framework like Express that uses its own Request and Response objects you would need to convert from the one to the other. Please have a look at the examples for how such an implementation might look like.
@@ -125,10 +217,11 @@ On the client, things are much simpler.
 - Create your router instance
 - Render your application using the `<RouterClient />` component
 
-[//]: # 'ClientEntryFileExample'
+<!-- ::start:framework -->
 
-```tsx
-// src/entry-client.tsx
+# React
+
+```tsx title="src/entry-client.tsx"
 import { hydrateRoot } from 'react-dom/client'
 import { RouterClient } from '@tanstack/react-router/ssr/client'
 import { createRouter } from './router'
@@ -138,7 +231,19 @@ const router = createRouter()
 hydrateRoot(document, <RouterClient router={router} />)
 ```
 
-[//]: # 'ClientEntryFileExample'
+# Solid
+
+```tsx title="src/entry-client.tsx"
+import { hydrate } from 'solid-js/web'
+import { RouterClient } from '@tanstack/solid-router/ssr/client'
+import { createRouter } from './router'
+
+const router = createRouter()
+
+hydrate(() => <RouterClient router={router} />, document.body)
+```
+
+<!-- ::end:framework -->
 
 With this setup, your application will be rendered on the server and then hydrated on the client!
 
@@ -153,8 +258,11 @@ This pattern can be useful for pages that have slow or high-latency data fetchin
 
 using `defaultStreamHandler`
 
-```tsx
-// src/entry-server.tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/entry-server.tsx"
 import {
   createRequestHandler,
   defaultStreamHandler,
@@ -168,10 +276,31 @@ export async function render({ request }: { request: Request }) {
 }
 ```
 
+# Solid
+
+```tsx title="src/entry-server.tsx"
+import {
+  createRequestHandler,
+  defaultStreamHandler,
+} from '@tanstack/solid-router/ssr/server'
+import { createRouter } from './router'
+
+export async function render({ request }: { request: Request }) {
+  const handler = createRequestHandler({ request, createRouter })
+
+  return await handler(defaultStreamHandler)
+}
+```
+
+<!-- ::end:framework -->
+
 using `renderRouterToStream`
 
-```tsx
-// src/entry-server.tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/entry-server.tsx"
 import {
   createRequestHandler,
   renderRouterToStream,
@@ -193,6 +322,32 @@ export function render({ request }: { request: Request }) {
 }
 ```
 
+# Solid
+
+```tsx title="src/entry-server.tsx"
+import {
+  createRequestHandler,
+  renderRouterToStream,
+  RouterServer,
+} from '@tanstack/solid-router/ssr/server'
+import { createRouter } from './router'
+
+export function render({ request }: { request: Request }) {
+  const handler = createRequestHandler({ request, createRouter })
+
+  return handler(({ request, responseHeaders, router }) =>
+    renderRouterToStream({
+      request,
+      responseHeaders,
+      router,
+      children: <RouterServer router={router} />,
+    }),
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 ## Streaming Dehydration/Hydration
 
 Streaming dehydration/hydration is an advanced pattern that goes beyond markup and allows you to dehydrate and stream any supporting data from the server to the client and rehydrate it on arrival. This is useful for applications that may need to further use/manage the underlying data that was used to render the initial markup on the server.
diff --git a/docs/router/framework/react/guide/static-route-data.md b/docs/router/guide/static-route-data.md
similarity index 57%
rename from docs/router/framework/react/guide/static-route-data.md
rename to docs/router/guide/static-route-data.md
index f2442253d5..2df546330b 100644
--- a/docs/router/framework/react/guide/static-route-data.md
+++ b/docs/router/guide/static-route-data.md
@@ -8,9 +8,13 @@ In addition to being able to access this data from the route itself, you can als
 
 ## Example
 
-- `posts.tsx`
+<!-- ::start:framework -->
 
-```tsx
+# React
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title='src/routes/posts.tsx'
 import { createFileRoute } from '@tanstack/react-router'
 
 export const Route = createFileRoute('/posts')({
@@ -20,11 +24,13 @@ export const Route = createFileRoute('/posts')({
 })
 ```
 
+<!-- ::end:tabs -->
+
 You can then access this data anywhere you have access to your routes, including matches that can be mapped back to their routes.
 
-- `__root.tsx`
+<!-- ::start:tabs variant="files" -->
 
-```tsx
+```tsx title='src/routes/__root.tsx'
 import { createRootRoute } from '@tanstack/react-router'
 
 export const Route = createRootRoute({
@@ -42,10 +48,59 @@ export const Route = createRootRoute({
 })
 ```
 
+<!-- ::end:tabs -->
+
+# Solid
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title='src/routes/posts.tsx'
+import { createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/posts')({
+  staticData: {
+    customData: 'Hello!',
+  },
+})
+```
+
+<!-- ::end:tabs -->
+
+You can then access this data anywhere you have access to your routes, including matches that can be mapped back to their routes.
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title='src/routes/__root.tsx'
+import { createRootRoute, useMatches } from '@tanstack/solid-router'
+import { For } from 'solid-js'
+
+export const Route = createRootRoute({
+  component: () => {
+    const matches = useMatches()
+
+    return (
+      <div>
+        <For each={matches()}>
+          {(match) => <div>{match.staticData.customData}</div>}
+        </For>
+      </div>
+    )
+  },
+})
+```
+
+<!-- ::end:tabs -->
+
+<!-- ::end:framework -->
+
 ## Enforcing Static Data
 
 If you want to enforce that a route has static data, you can use declaration merging to add a type to the route's static option:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 declare module '@tanstack/react-router' {
   interface StaticDataRouteOption {
@@ -54,11 +109,21 @@ declare module '@tanstack/react-router' {
 }
 ```
 
-Now, if you try to create a route without the `customData` property, you'll get a type error:
+# Solid
 
 ```tsx
-import { createFileRoute } from '@tanstack/react-router'
+declare module '@tanstack/solid-router' {
+  interface StaticDataRouteOption {
+    customData: string
+  }
+}
+```
+
+<!-- ::end:framework -->
 
+Now, if you try to create a route without the `customData` property, you'll get a type error:
+
+```tsx
 export const Route = createFileRoute('/posts')({
   staticData: {
     // Property 'customData' is missing in type '{ customData: number; }' but required in type 'StaticDataRouteOption'.ts(2741)
@@ -70,6 +135,10 @@ export const Route = createFileRoute('/posts')({
 
 If you want to make static data optional, simply add a `?` to the property:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 declare module '@tanstack/react-router' {
   interface StaticDataRouteOption {
@@ -78,6 +147,18 @@ declare module '@tanstack/react-router' {
 }
 ```
 
+# Solid
+
+```tsx
+declare module '@tanstack/solid-router' {
+  interface StaticDataRouteOption {
+    customData?: string
+  }
+}
+```
+
+<!-- ::end:framework -->
+
 As long as there are any required properties on the `StaticDataRouteOption`, you'll be required to pass in an object.
 
 ## Common Patterns
@@ -86,14 +167,19 @@ As long as there are any required properties on the `StaticDataRouteOption`, you
 
 Use staticData to control which routes show or hide layout elements:
 
-```tsx
-// routes/admin/route.tsx
+<!-- ::start:tabs variant="files" -->
+
+```tsx title='src/routes/admin/route.tsx'
 export const Route = createFileRoute('/admin')({
   staticData: { showNavbar: false },
   component: AdminLayout,
 })
 ```
 
+<!-- ::end:tabs -->
+
+<!-- ::start:tabs variant="files" -->
+
 ```tsx
 // routes/__root.tsx
 function RootComponent() {
@@ -112,10 +198,17 @@ function RootComponent() {
 }
 ```
 
+<!-- ::end:tabs -->
+
 ### Route Titles for Breadcrumbs
 
-```tsx
-// routes/posts/$postId.tsx
+<!-- ::start:framework -->
+
+# React
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title='src/routes/posts/$postId.tsx'
 export const Route = createFileRoute('/posts/$postId')({
   staticData: {
     getTitle: () => 'Post Details',
@@ -123,8 +216,11 @@ export const Route = createFileRoute('/posts/$postId')({
 })
 ```
 
-```tsx
-// In a Breadcrumb component
+<!-- ::end:tabs -->
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title='src/components/Breadcrumbs.tsx'
 function Breadcrumbs() {
   const matches = useMatches()
 
@@ -140,6 +236,45 @@ function Breadcrumbs() {
 }
 ```
 
+<!-- ::end:tabs -->
+
+# Solid
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title='src/routes/posts/$postId.tsx'
+export const Route = createFileRoute('/posts/$postId')({
+  staticData: {
+    getTitle: () => 'Post Details',
+  },
+})
+```
+
+<!-- ::end:tabs -->
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title='src/components/Breadcrumbs.tsx'
+import { useMatches } from '@tanstack/solid-router'
+import { For } from 'solid-js'
+
+function Breadcrumbs() {
+  const matches = useMatches()
+
+  return (
+    <nav>
+      <For each={matches().filter((m) => m.staticData?.getTitle)}>
+        {(m) => <span>{m.staticData.getTitle()}</span>}
+      </For>
+    </nav>
+  )
+}
+```
+
+<!-- ::end:tabs -->
+
+<!-- ::end:framework -->
+
 ### When to Use staticData vs Context
 
 | staticData                             | context                         |
diff --git a/docs/router/framework/react/guide/type-safety.md b/docs/router/guide/type-safety.md
similarity index 98%
rename from docs/router/framework/react/guide/type-safety.md
rename to docs/router/guide/type-safety.md
index fe17ae3d69..2adffc58c5 100644
--- a/docs/router/framework/react/guide/type-safety.md
+++ b/docs/router/guide/type-safety.md
@@ -28,6 +28,10 @@ const parentRoute = createRoute({
 
 For the types of your router to work with top-level exports like `Link`, `useNavigate`, `useParams`, etc. they must permeate the TypeScript module boundary and be registered right into the library. To do this, we use declaration merging on the exported `Register` interface.
 
+<!-- ::start:framework -->
+
+# React
+
 ```ts
 const router = createRouter({
   // ...
@@ -40,6 +44,22 @@ declare module '@tanstack/react-router' {
 }
 ```
 
+# Solid
+
+```ts
+const router = createRouter({
+  // ...
+})
+
+declare module '@tanstack/solid-router' {
+  interface Register {
+    router: typeof router
+  }
+}
+```
+
+<!-- ::end:framework -->
+
 By registering your router with the module, you can now use the exported hooks, components, and utilities with your router's exact types.
 
 ## Fixing the Component Context Problem
diff --git a/docs/router/framework/react/guide/type-utilities.md b/docs/router/guide/type-utilities.md
similarity index 69%
rename from docs/router/framework/react/guide/type-utilities.md
rename to docs/router/guide/type-utilities.md
index a0b39abcd5..8db99d28e2 100644
--- a/docs/router/framework/react/guide/type-utilities.md
+++ b/docs/router/guide/type-utilities.md
@@ -9,6 +9,10 @@ Most types exposed by TanStack Router are internal, subject to breaking changes
 
 `ValidateLinkOptions` type checks object literal types to ensure they conform to `Link` options at inference sites. For example, you may have a generic `HeadingLink` component which accepts a `title` prop along with `linkOptions`, the idea being this component can be re-used for any navigation.
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 export interface HeaderLinkProps<
   TRouter extends RegisteredRouter = RegisteredRouter,
@@ -31,6 +35,32 @@ export function HeadingLink(props: HeaderLinkProps): React.ReactNode {
 }
 ```
 
+# Solid
+
+```tsx
+export interface HeaderLinkProps<
+  TRouter extends RegisteredRouter = RegisteredRouter,
+  TOptions = unknown,
+> {
+  title: string
+  linkOptions: ValidateLinkOptions<TRouter, TOptions>
+}
+
+export function HeadingLink<TRouter extends RegisteredRouter, TOptions>(
+  props: HeaderLinkProps<TRouter, TOptions>,
+): Solid.JSX.Element
+export function HeadingLink(props: HeaderLinkProps): Solid.JSX.Element {
+  return (
+    <>
+      <h1>{props.title}</h1>
+      <Link {...props.linkOptions} />
+    </>
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 A more permissive overload of `HeadingLink` is used to avoid type assertions you would otherwise have to do with the generic signature. Using a looser signature without type parameters is an easy way to avoid type assertions in the implementation of `HeadingLink`
 
 All type parameters for utilities are optional but for the best TypeScript performance `TRouter` should always be specified for the public facing signature. And `TOptions` should always be used at inference sites like `HeadingLink` to infer the `linkOptions` to correctly narrow `params` and `search`
@@ -46,6 +76,10 @@ The result of this is that `linkOptions` in the following is completely type-saf
 
 All navigation type utilities have an array variant. `ValidateLinkOptionsArray` enables type checking of an array of `Link` options. For example, you might have a generic `Menu` component where each item is a `Link`.
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 export interface MenuProps<
   TRouter extends RegisteredRouter = RegisteredRouter,
@@ -71,6 +105,39 @@ export function Menu(props: MenuProps): React.ReactNode {
 }
 ```
 
+# Solid
+
+```tsx
+import { For } from 'solid-js'
+
+export interface MenuProps<
+  TRouter extends RegisteredRouter = RegisteredRouter,
+  TItems extends ReadonlyArray<unknown> = ReadonlyArray<unknown>,
+> {
+  items: ValidateLinkOptionsArray<TRouter, TItems>
+}
+
+export function Menu<
+  TRouter extends RegisteredRouter = RegisteredRouter,
+  TItems extends ReadonlyArray<unknown>,
+>(props: MenuProps<TRouter, TItems>): Solid.JSX.Element
+export function Menu(props: MenuProps): Solid.JSX.Element {
+  return (
+    <ul>
+      <For each={props.items}>
+        {(item) => (
+          <li>
+            <Link {...item} />
+          </li>
+        )}
+      </For>
+    </ul>
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 This of course allows the following `items` prop to be completely type-safe
 
 ```tsx
@@ -84,7 +151,11 @@ This of course allows the following `items` prop to be completely type-safe
 
 It is also possible to fix `from` for each `Link` options in the array. This would allow all `Menu` items to navigate relative to `from`. Additional type checking of `from` can be provided by the `ValidateFromPath` utility
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+```ts
 export interface MenuProps<
   TRouter extends RegisteredRouter = RegisteredRouter,
   TItems extends ReadonlyArray<unknown> = ReadonlyArray<unknown>,
@@ -112,6 +183,42 @@ export function Menu(props: MenuProps): React.ReactNode {
 }
 ```
 
+# Solid
+
+```ts
+import { For } from 'solid-js'
+
+export interface MenuProps<
+  TRouter extends RegisteredRouter = RegisteredRouter,
+  TItems extends ReadonlyArray<unknown> = ReadonlyArray<unknown>,
+  TFrom extends string = string,
+> {
+  from: ValidateFromPath<TRouter, TFrom>
+  items: ValidateLinkOptionsArray<TRouter, TItems, TFrom>
+}
+
+export function Menu<
+  TRouter extends RegisteredRouter = RegisteredRouter,
+  TItems extends ReadonlyArray<unknown>,
+  TFrom extends string = string,
+>(props: MenuProps<TRouter, TItems, TFrom>): Solid.JSX.Element
+export function Menu(props: MenuProps): Solid.JSX.Element {
+  return (
+    <ul>
+      <For each={props.items}>
+        {(item) => (
+          <li>
+            <Link {...item} from={props.from} />
+          </li>
+        )}
+      </For>
+    </ul>
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 `ValidateLinkOptionsArray` allows you to fix `from` by providing an extra type parameter. The result is a type safe array of `Link` options providing navigation relative to `from`
 
 ```tsx
@@ -157,7 +264,9 @@ fetchOrRedirect('http://example.com/', { to: '/login' })
 
 `ValidateNavigateOptions` type checks object literal types to ensure they conform to navigate options at inference sites. For example, you may want to write a custom hook to enable/disable navigation.
 
-[//]: # 'TypeCheckingNavigateOptionsWithValidateNavigateOptionsImpl'
+<!-- ::start:framework -->
+
+# React
 
 ```tsx
 export interface UseConditionalNavigateResult {
@@ -189,7 +298,41 @@ export function useConditionalNavigate(
 }
 ```
 
-[//]: # 'TypeCheckingNavigateOptionsWithValidateNavigateOptionsImpl'
+# Solid
+
+```tsx
+import { createSignal } from 'solid-js'
+
+export interface UseConditionalNavigateResult {
+  enable: () => void
+  disable: () => void
+  navigate: () => void
+}
+
+export function useConditionalNavigate<
+  TRouter extends RegisteredRouter = RegisteredRouter,
+  TOptions = unknown,
+>(
+  navigateOptions: ValidateNavigateOptions<TRouter, TOptions>,
+): UseConditionalNavigateResult
+export function useConditionalNavigate(
+  navigateOptions: ValidateNavigateOptions,
+): UseConditionalNavigateResult {
+  const [enabled, setEnabled] = createSignal(false)
+  const navigate = useNavigate()
+  return {
+    enable: () => setEnabled(true),
+    disable: () => setEnabled(false),
+    navigate: () => {
+      if (enabled()) {
+        navigate(navigateOptions)
+      }
+    },
+  }
+}
+```
+
+<!-- ::end:framework -->
 
 The result of this is that `navigateOptions` passed to `useConditionalNavigate` is completely type-safe and we can enable/disable navigation based on react state
 
diff --git a/docs/router/framework/react/guide/url-rewrites.md b/docs/router/guide/url-rewrites.md
similarity index 100%
rename from docs/router/framework/react/guide/url-rewrites.md
rename to docs/router/guide/url-rewrites.md
diff --git a/docs/router/framework/react/how-to/README.md b/docs/router/how-to/README.md
similarity index 100%
rename from docs/router/framework/react/how-to/README.md
rename to docs/router/how-to/README.md
diff --git a/docs/router/framework/react/how-to/arrays-objects-dates-search-params.md b/docs/router/how-to/arrays-objects-dates-search-params.md
similarity index 100%
rename from docs/router/framework/react/how-to/arrays-objects-dates-search-params.md
rename to docs/router/how-to/arrays-objects-dates-search-params.md
diff --git a/docs/router/framework/react/how-to/debug-router-issues.md b/docs/router/how-to/debug-router-issues.md
similarity index 100%
rename from docs/router/framework/react/how-to/debug-router-issues.md
rename to docs/router/how-to/debug-router-issues.md
diff --git a/docs/router/framework/react/how-to/deploy-to-production.md b/docs/router/how-to/deploy-to-production.md
similarity index 100%
rename from docs/router/framework/react/how-to/deploy-to-production.md
rename to docs/router/how-to/deploy-to-production.md
diff --git a/docs/router/framework/react/how-to/drafts/README.md b/docs/router/how-to/drafts/README.md
similarity index 100%
rename from docs/router/framework/react/how-to/drafts/README.md
rename to docs/router/how-to/drafts/README.md
diff --git a/docs/router/framework/react/how-to/drafts/build-search-filtering-systems.draft.md b/docs/router/how-to/drafts/build-search-filtering-systems.draft.md
similarity index 100%
rename from docs/router/framework/react/how-to/drafts/build-search-filtering-systems.draft.md
rename to docs/router/how-to/drafts/build-search-filtering-systems.draft.md
diff --git a/docs/router/framework/react/how-to/drafts/optimize-search-param-performance.draft.md b/docs/router/how-to/drafts/optimize-search-param-performance.draft.md
similarity index 100%
rename from docs/router/framework/react/how-to/drafts/optimize-search-param-performance.draft.md
rename to docs/router/how-to/drafts/optimize-search-param-performance.draft.md
diff --git a/docs/router/framework/react/how-to/drafts/search-params-in-forms.draft.md b/docs/router/how-to/drafts/search-params-in-forms.draft.md
similarity index 100%
rename from docs/router/framework/react/how-to/drafts/search-params-in-forms.draft.md
rename to docs/router/how-to/drafts/search-params-in-forms.draft.md
diff --git a/docs/router/framework/react/how-to/install.md b/docs/router/how-to/install.md
similarity index 100%
rename from docs/router/framework/react/how-to/install.md
rename to docs/router/how-to/install.md
diff --git a/docs/router/framework/react/how-to/integrate-chakra-ui.md b/docs/router/how-to/integrate-chakra-ui.md
similarity index 100%
rename from docs/router/framework/react/how-to/integrate-chakra-ui.md
rename to docs/router/how-to/integrate-chakra-ui.md
diff --git a/docs/router/framework/react/how-to/integrate-framer-motion.md b/docs/router/how-to/integrate-framer-motion.md
similarity index 100%
rename from docs/router/framework/react/how-to/integrate-framer-motion.md
rename to docs/router/how-to/integrate-framer-motion.md
diff --git a/docs/router/framework/react/how-to/integrate-material-ui.md b/docs/router/how-to/integrate-material-ui.md
similarity index 100%
rename from docs/router/framework/react/how-to/integrate-material-ui.md
rename to docs/router/how-to/integrate-material-ui.md
diff --git a/docs/router/framework/react/how-to/integrate-shadcn-ui.md b/docs/router/how-to/integrate-shadcn-ui.md
similarity index 100%
rename from docs/router/framework/react/how-to/integrate-shadcn-ui.md
rename to docs/router/how-to/integrate-shadcn-ui.md
diff --git a/docs/router/framework/react/how-to/migrate-from-react-router.md b/docs/router/how-to/migrate-from-react-router.md
similarity index 100%
rename from docs/router/framework/react/how-to/migrate-from-react-router.md
rename to docs/router/how-to/migrate-from-react-router.md
diff --git a/docs/router/framework/react/how-to/navigate-with-search-params.md b/docs/router/how-to/navigate-with-search-params.md
similarity index 100%
rename from docs/router/framework/react/how-to/navigate-with-search-params.md
rename to docs/router/how-to/navigate-with-search-params.md
diff --git a/docs/router/framework/react/how-to/setup-auth-providers.md b/docs/router/how-to/setup-auth-providers.md
similarity index 100%
rename from docs/router/framework/react/how-to/setup-auth-providers.md
rename to docs/router/how-to/setup-auth-providers.md
diff --git a/docs/router/framework/react/how-to/setup-authentication.md b/docs/router/how-to/setup-authentication.md
similarity index 100%
rename from docs/router/framework/react/how-to/setup-authentication.md
rename to docs/router/how-to/setup-authentication.md
diff --git a/docs/router/framework/react/how-to/setup-basic-search-params.md b/docs/router/how-to/setup-basic-search-params.md
similarity index 100%
rename from docs/router/framework/react/how-to/setup-basic-search-params.md
rename to docs/router/how-to/setup-basic-search-params.md
diff --git a/docs/router/framework/react/how-to/setup-rbac.md b/docs/router/how-to/setup-rbac.md
similarity index 100%
rename from docs/router/framework/react/how-to/setup-rbac.md
rename to docs/router/how-to/setup-rbac.md
diff --git a/docs/router/framework/react/how-to/setup-ssr.md b/docs/router/how-to/setup-ssr.md
similarity index 99%
rename from docs/router/framework/react/how-to/setup-ssr.md
rename to docs/router/how-to/setup-ssr.md
index 03dc916495..6a72cc945a 100644
--- a/docs/router/framework/react/how-to/setup-ssr.md
+++ b/docs/router/how-to/setup-ssr.md
@@ -142,7 +142,7 @@ hydrateRoot(document, <RouterClient router={router} />)
 // vite.config.ts
 import path from 'node:path'
 import url from 'node:url'
-import { TanStackRouterVite } from '@tanstack/router-plugin/vite'
+import { tanstackRouter } from '@tanstack/router-plugin/vite'
 import { defineConfig } from 'vite'
 import react from '@vitejs/plugin-react'
 
@@ -151,7 +151,7 @@ const __dirname = path.dirname(__filename)
 
 export default defineConfig(({ isSsrBuild }) => ({
   plugins: [
-    TanStackRouterVite({
+    tanstackRouter({
       autoCodeSplitting: true,
     }),
     react(),
@@ -407,7 +407,7 @@ For streaming SSR, update your Vite config:
 // vite.config.ts
 export default defineConfig(({ isSsrBuild }) => ({
   plugins: [
-    TanStackRouterVite({
+    tanstackRouter({
       autoCodeSplitting: true,
       enableStreaming: true, // Enable streaming support
     }),
diff --git a/docs/router/framework/react/how-to/setup-testing.md b/docs/router/how-to/setup-testing.md
similarity index 100%
rename from docs/router/framework/react/how-to/setup-testing.md
rename to docs/router/how-to/setup-testing.md
diff --git a/docs/router/framework/react/how-to/share-search-params-across-routes.md b/docs/router/how-to/share-search-params-across-routes.md
similarity index 100%
rename from docs/router/framework/react/how-to/share-search-params-across-routes.md
rename to docs/router/how-to/share-search-params-across-routes.md
diff --git a/docs/router/framework/react/how-to/test-file-based-routing.md b/docs/router/how-to/test-file-based-routing.md
similarity index 99%
rename from docs/router/framework/react/how-to/test-file-based-routing.md
rename to docs/router/how-to/test-file-based-routing.md
index 7227e8a78c..aa679719b5 100644
--- a/docs/router/framework/react/how-to/test-file-based-routing.md
+++ b/docs/router/how-to/test-file-based-routing.md
@@ -38,11 +38,11 @@ Create `vitest.config.ts` with file-based routing support:
 ```ts
 import { defineConfig } from 'vitest/config'
 import react from '@vitejs/plugin-react'
-import { TanStackRouterVite } from '@tanstack/router-plugin/vite'
+import { tanstackRouter } from '@tanstack/router-plugin/vite'
 
 export default defineConfig({
   plugins: [
-    TanStackRouterVite({
+    tanstackRouter({
       // Configure for test environment
       routesDirectory: './src/routes',
       generatedRouteTree: './src/routeTree.gen.ts',
@@ -898,7 +898,7 @@ Error: Cannot find module '../routeTree.gen'
 // vitest.config.ts
 export default defineConfig({
   plugins: [
-    TanStackRouterVite(), // Ensure this runs before tests
+    tanstackRouter(), // Ensure this runs before tests
     react(),
   ],
   test: {
diff --git a/docs/router/framework/react/how-to/use-environment-variables.md b/docs/router/how-to/use-environment-variables.md
similarity index 99%
rename from docs/router/framework/react/how-to/use-environment-variables.md
rename to docs/router/how-to/use-environment-variables.md
index b54146ee1d..2d35308158 100644
--- a/docs/router/framework/react/how-to/use-environment-variables.md
+++ b/docs/router/how-to/use-environment-variables.md
@@ -436,13 +436,13 @@ export const Route = createFileRoute('/api-data')({
 // vite.config.ts
 import { defineConfig } from 'vite'
 import react from '@vitejs/plugin-react'
-import { TanStackRouterVite } from '@tanstack/router-vite-plugin'
+import { tanstackRouter } from '@tanstack/router-plugin/vite'
 
 export default defineConfig({
   plugins: [
     react(),
-    // TanStackRouterVite generates route tree and enables file-based routing
-    TanStackRouterVite(),
+    // tanstackRouter generates route tree and enables file-based routing
+    tanstackRouter(),
   ],
   // Environment variables are handled automatically
   // Custom environment variable handling:
diff --git a/docs/router/framework/react/how-to/validate-search-params.md b/docs/router/how-to/validate-search-params.md
similarity index 100%
rename from docs/router/framework/react/how-to/validate-search-params.md
rename to docs/router/how-to/validate-search-params.md
diff --git a/docs/router/framework/react/installation/manual.md b/docs/router/installation/manual.md
similarity index 58%
rename from docs/router/framework/react/installation/manual.md
rename to docs/router/installation/manual.md
index 6583abf908..76d1f1fe6a 100644
--- a/docs/router/framework/react/installation/manual.md
+++ b/docs/router/installation/manual.md
@@ -8,21 +8,23 @@ To set up TanStack Router manually in a React project, follow the steps below. T
 
 #### Install TanStack Router, Vite Plugin, and the Router Devtools
 
-```sh
-npm install @tanstack/react-router @tanstack/react-router-devtools
-npm install -D @tanstack/router-plugin
-# or
-pnpm add @tanstack/react-router @tanstack/react-router-devtools
-pnpm add -D @tanstack/router-plugin
-# or
-yarn add @tanstack/react-router @tanstack/react-router-devtools
-yarn add -D @tanstack/router-plugin
-# or
-bun add @tanstack/react-router @tanstack/react-router-devtools
-bun add -D @tanstack/router-plugin
-# or
-deno add npm:@tanstack/react-router npm:@tanstack/router-plugin npm:@tanstack/react-router-devtools
-```
+Install the necessary core dependencies:
+
+<!-- ::start:tabs variant="package-managers" -->
+
+react: @tanstack/react-router @tanstack/react-router-devtools
+solid: @tanstack/solid-router @tanstack/solid-router-devtools
+
+<!-- ::end:tabs -->
+
+Install the necessary development dependencies:
+
+<!-- ::start:tabs variant="package-managers" mode="dev-install" -->
+
+react: @tanstack/router-plugin
+solid: @tanstack/router-plugin
+
+<!-- ::end:tabs -->
 
 #### Configure the Vite Plugin
 
@@ -56,9 +58,13 @@ Create the following files:
 - `src/routes/about.tsx`
 - `src/main.tsx`
 
-#### `src/routes/__root.tsx`
+<!-- ::start:framework -->
 
-```tsx
+# React
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/routes/__root.tsx"
 import { createRootRoute, Link, Outlet } from '@tanstack/react-router'
 import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
 
@@ -81,9 +87,7 @@ const RootLayout = () => (
 export const Route = createRootRoute({ component: RootLayout })
 ```
 
-#### `src/routes/index.tsx`
-
-```tsx
+```tsx title="src/routes/index.tsx"
 import { createFileRoute } from '@tanstack/react-router'
 
 export const Route = createFileRoute('/')({
@@ -99,9 +103,7 @@ function Index() {
 }
 ```
 
-#### `src/routes/about.tsx`
-
-```tsx
+```tsx title="src/routes/about.tsx"
 import { createFileRoute } from '@tanstack/react-router'
 
 export const Route = createFileRoute('/about')({
@@ -113,13 +115,7 @@ function About() {
 }
 ```
 
-#### `src/main.tsx`
-
-Regardless of whether you are using the `@tanstack/router-plugin` package and running the `npm run dev`/`npm run build` scripts, or manually running the `tsr watch`/`tsr generate` commands from your package scripts, the route tree file will be generated at `src/routeTree.gen.ts`.
-
-Import the generated route tree and create a new router instance:
-
-```tsx
+```tsx title="src/main.tsx"
 import { StrictMode } from 'react'
 import ReactDOM from 'react-dom/client'
 import { RouterProvider, createRouter } from '@tanstack/react-router'
@@ -149,6 +145,93 @@ if (!rootElement.innerHTML) {
 }
 ```
 
+<!-- ::end:tabs -->
+
+# Solid
+
+<!-- ::start:tabs variant="files" -->
+
+```tsx title="src/routes/__root.tsx"
+import { createRootRoute, Link, Outlet } from '@tanstack/solid-router'
+import { TanStackRouterDevtools } from '@tanstack/solid-router-devtools'
+
+const RootLayout = () => (
+  <>
+    <div class="p-2 flex gap-2">
+      <Link to="/" class="[&.active]:font-bold">
+        Home
+      </Link>{' '}
+      <Link to="/about" class="[&.active]:font-bold">
+        About
+      </Link>
+    </div>
+    <hr />
+    <Outlet />
+    <TanStackRouterDevtools />
+  </>
+)
+
+export const Route = createRootRoute({ component: RootLayout })
+```
+
+```tsx title="src/routes/index.tsx"
+import { createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/')({
+  component: Index,
+})
+
+function Index() {
+  return (
+    <div class="p-2">
+      <h3>Welcome Home!</h3>
+    </div>
+  )
+}
+```
+
+```tsx title="src/routes/about.tsx"
+import { createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/about')({
+  component: About,
+})
+
+function About() {
+  return <div class="p-2">Hello from About!</div>
+}
+```
+
+```tsx title="src/main.tsx"
+/* @refresh reload */
+import { render } from 'solid-js/web'
+import { RouterProvider, createRouter } from '@tanstack/solid-router'
+
+// Import the generated route tree
+import { routeTree } from './routeTree.gen'
+
+// Create a new router instance
+const router = createRouter({ routeTree })
+
+// Register the router instance for type safety
+declare module '@tanstack/solid-router' {
+  interface Register {
+    router: typeof router
+  }
+}
+
+// Render the app
+const rootElement = document.getElementById('root')!
+
+render(() => <RouterProvider router={router} />, rootElement)
+```
+
+<!-- ::end:tabs -->
+
+<!-- ::end:framework -->
+
+Regardless of whether you are using the `@tanstack/router-plugin` package and running the `npm run dev`/`npm run build` scripts, or manually running the `tsr watch`/`tsr generate` commands from your package scripts, the route tree file will be generated at `src/routeTree.gen.ts`.
+
 If you are working with this pattern you should change the `id` of the root `<div>` on your `index.html` file to `<div id='root'></div>`
 
 ## Using Code-Based Route Configuration
@@ -156,6 +239,10 @@ If you are working with this pattern you should change the `id` of the root `<di
 > [!IMPORTANT]
 > The following example shows how to configure routes using code, and for simplicity's sake is in a single file for this demo. While code-based generation allows you to declare many routes and even the router instance in a single file, we recommend splitting your routes into separate files for better organization and performance as your application grows.
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { StrictMode } from 'react'
 import ReactDOM from 'react-dom/client'
@@ -228,4 +315,73 @@ if (!rootElement.innerHTML) {
 }
 ```
 
+# Solid
+
+```tsx
+/* @refresh reload */
+import { render } from 'solid-js/web'
+import {
+  Outlet,
+  RouterProvider,
+  Link,
+  createRouter,
+  createRoute,
+  createRootRoute,
+} from '@tanstack/solid-router'
+import { TanStackRouterDevtools } from '@tanstack/solid-router-devtools'
+
+const rootRoute = createRootRoute({
+  component: () => (
+    <>
+      <div class="p-2 flex gap-2">
+        <Link to="/" class="[&.active]:font-bold">
+          Home
+        </Link>{' '}
+        <Link to="/about" class="[&.active]:font-bold">
+          About
+        </Link>
+      </div>
+      <hr />
+      <Outlet />
+      <TanStackRouterDevtools />
+    </>
+  ),
+})
+
+const indexRoute = createRoute({
+  getParentRoute: () => rootRoute,
+  path: '/',
+  component: function Index() {
+    return (
+      <div class="p-2">
+        <h3>Welcome Home!</h3>
+      </div>
+    )
+  },
+})
+
+const aboutRoute = createRoute({
+  getParentRoute: () => rootRoute,
+  path: '/about',
+  component: function About() {
+    return <div class="p-2">Hello from About!</div>
+  },
+})
+
+const routeTree = rootRoute.addChildren([indexRoute, aboutRoute])
+
+const router = createRouter({ routeTree })
+
+declare module '@tanstack/solid-router' {
+  interface Register {
+    router: typeof router
+  }
+}
+
+const rootElement = document.getElementById('app')!
+render(() => <RouterProvider router={router} />, rootElement)
+```
+
+<!-- ::end:framework -->
+
 If you glossed over these examples or didn't understand something, we don't blame you, because there's so much more to learn to really take advantage of TanStack Router! Let's move on.
diff --git a/docs/router/framework/solid/installation/with-esbuild.md b/docs/router/installation/with-esbuild.md
similarity index 82%
rename from docs/router/framework/solid/installation/with-esbuild.md
rename to docs/router/installation/with-esbuild.md
index ac8044ee82..b5cad0622c 100644
--- a/docs/router/framework/solid/installation/with-esbuild.md
+++ b/docs/router/installation/with-esbuild.md
@@ -2,18 +2,40 @@
 title: Installation with Esbuild
 ---
 
-[//]: # 'BundlerConfiguration'
-
 To use file-based routing with **Esbuild**, you'll need to install the `@tanstack/router-plugin` package.
 
-```sh
-npm install -D @tanstack/router-plugin
-```
+<!-- ::start:tabs variant="package-manager" mode="dev-install" -->
+
+react: @tanstack/router-plugin
+solid: @tanstack/router-plugin
+
+<!-- ::end:tabs -->
 
 Once installed, you'll need to add the plugin to your configuration.
 
-```tsx
-// build.js
+<!-- ::start:framework -->
+
+# React
+
+```ts title="esbuild.config.js"
+import { tanstackRouter } from '@tanstack/router-plugin/esbuild'
+
+export default {
+  // ...
+  plugins: [
+    tanstackRouter({
+      target: 'react',
+      autoCodeSplitting: true,
+    }),
+  ],
+}
+```
+
+Or, you can clone our [Quickstart Esbuild example](https://github.com/TanStack/router/tree/main/examples/react/quickstart-esbuild-file-based) and get started.
+
+# Solid
+
+```ts title="build.js"
 import * as esbuild from 'esbuild'
 import { solidPlugin } from 'esbuild-plugin-solid'
 import { tanstackRouter } from '@tanstack/router-plugin/esbuild'
@@ -46,9 +68,9 @@ if (isDev) {
 
 Or, you can clone our [Quickstart Esbuild example](https://github.com/TanStack/router/tree/main/examples/solid/quickstart-esbuild-file-based) and get started.
 
-Now that you've added the plugin to your Esbuild configuration, you're all set to start using file-based routing with TanStack Router.
+<!-- ::end:framework -->
 
-[//]: # 'BundlerConfiguration'
+Now that you've added the plugin to your Esbuild configuration, you're all set to start using file-based routing with TanStack Router.
 
 ## Ignoring the generated route tree file
 
@@ -96,4 +118,4 @@ When using the TanStack Router Plugin with Esbuild for File-based routing, it co
 
 If these defaults work for your project, you don't need to configure anything at all! However, if you need to customize the configuration, you can do so by editing the configuration object passed into the `tanstackRouter` function.
 
-You can find all the available configuration options in the [File-based Routing API Reference](../../../api/file-based-routing.md).
+You can find all the available configuration options in the [File-based Routing API Reference](../api/file-based-routing.md).
diff --git a/docs/router/framework/react/installation/with-router-cli.md b/docs/router/installation/with-router-cli.md
similarity index 80%
rename from docs/router/framework/react/installation/with-router-cli.md
rename to docs/router/installation/with-router-cli.md
index 3f5e616595..b0363aaf41 100644
--- a/docs/router/framework/react/installation/with-router-cli.md
+++ b/docs/router/installation/with-router-cli.md
@@ -7,9 +7,12 @@ title: Installation with Router CLI
 
 To use file-based routing with the TanStack Router CLI, you'll need to install the `@tanstack/router-cli` package.
 
-```sh
-npm install -D @tanstack/router-cli
-```
+<!-- ::start:tabs variant="package-manager" mode="dev-install" -->
+
+react: @tanstack/router-cli
+solid: @tanstack/router-cli
+
+<!-- ::end:tabs -->
 
 Once installed, you'll need to amend your scripts in your `package.json` for the CLI to `watch` and `generate` files.
 
@@ -24,6 +27,25 @@ Once installed, you'll need to amend your scripts in your `package.json` for the
 }
 ```
 
+<!-- ::start:framework -->
+
+# Solid
+
+If you are using TypeScript, you should also add the following options to your `tsconfig.json`:
+
+```json
+{
+  "compilerOptions": {
+    "jsx": "preserve",
+    "jsxImportSource": "solid-js"
+  }
+}
+```
+
+With that, you're all set to start using file-based routing with TanStack Router.
+
+<!-- ::end:framework -->
+
 [//]: # 'AfterScripts'
 [//]: # 'AfterScripts'
 
@@ -86,18 +108,34 @@ You can use those settings either at a user level or only for a single workspace
 
 When using the TanStack Router CLI for File-based routing, it comes with some sane defaults that should work for most projects:
 
+<!-- ::start:framework -->
+
+# React
+
 ```json
 {
   "routesDirectory": "./src/routes",
   "generatedRouteTree": "./src/routeTree.gen.ts",
   "routeFileIgnorePrefix": "-",
-  "quoteStyle": "single"
+  "quoteStyle": "single",
+  "target": "react"
 }
 ```
 
-If these defaults work for your project, you don't need to configure anything at all! However, if you need to customize the configuration, you can do so by creating a `tsr.config.json` file in the root of your project directory.
+# Solid
+
+```json
+{
+  "routesDirectory": "./src/routes",
+  "generatedRouteTree": "./src/routeTree.gen.ts",
+  "routeFileIgnorePrefix": "-",
+  "quoteStyle": "single",
+  "target": "solid"
+}
+```
+
+<!-- ::end:framework -->
 
-[//]: # 'TargetConfiguration'
-[//]: # 'TargetConfiguration'
+If these defaults work for your project, you don't need to configure anything at all! However, if you need to customize the configuration, you can do so by creating a `tsr.config.json` file in the root of your project directory.
 
-You can find all the available configuration options in the [File-based Routing API Reference](../../../api/file-based-routing.md).
+You can find all the available configuration options in the [File-based Routing API Reference](../api/file-based-routing.md).
diff --git a/docs/router/framework/solid/installation/with-rspack.md b/docs/router/installation/with-rspack.md
similarity index 77%
rename from docs/router/framework/solid/installation/with-rspack.md
rename to docs/router/installation/with-rspack.md
index c592bcd22a..f384831d5a 100644
--- a/docs/router/framework/solid/installation/with-rspack.md
+++ b/docs/router/installation/with-rspack.md
@@ -2,18 +2,46 @@
 title: Installation with Rspack
 ---
 
-[//]: # 'BundlerConfiguration'
-
 To use file-based routing with **Rspack** or **Rsbuild**, you'll need to install the `@tanstack/router-plugin` package.
 
-```sh
-npm install -D @tanstack/router-plugin
-```
+<!-- ::start:tabs variant="package-manager" mode="dev-install" -->
+
+react: @tanstack/router-plugin
+solid: @tanstack/router-plugin
+
+<!-- ::end:tabs -->
 
 Once installed, you'll need to add the plugin to your configuration.
 
-```tsx
-// rsbuild.config.ts
+<!-- ::start:framework -->
+
+# React
+
+```ts title="rsbuild.config.ts"
+import { defineConfig } from '@rsbuild/core'
+import { pluginReact } from '@rsbuild/plugin-react'
+import { tanstackRouter } from '@tanstack/router-plugin/rspack'
+
+export default defineConfig({
+  plugins: [pluginReact()],
+  tools: {
+    rspack: {
+      plugins: [
+        tanstackRouter({
+          target: 'react',
+          autoCodeSplitting: true,
+        }),
+      ],
+    },
+  },
+})
+```
+
+Or, you can clone our [Quickstart Rspack/Rsbuild example](https://github.com/TanStack/router/tree/main/examples/react/quickstart-rspack-file-based) and get started.
+
+# Solid
+
+```ts title="rsbuild.config.ts"
 import { defineConfig } from '@rsbuild/core'
 import { pluginBabel } from '@rsbuild/plugin-babel'
 import { pluginSolid } from '@rsbuild/plugin-solid'
@@ -36,9 +64,9 @@ export default defineConfig({
 
 Or, you can clone our [Quickstart Rspack/Rsbuild example](https://github.com/TanStack/router/tree/main/examples/solid/quickstart-rspack-file-based) and get started.
 
-Now that you've added the plugin to your Rspack/Rsbuild configuration, you're all set to start using file-based routing with TanStack Router.
+<!-- ::end:framework -->
 
-[//]: # 'BundlerConfiguration'
+Now that you've added the plugin to your Rspack/Rsbuild configuration, you're all set to start using file-based routing with TanStack Router.
 
 ## Ignoring the generated route tree file
 
@@ -86,4 +114,4 @@ When using the TanStack Router Plugin with Rspack (or Rsbuild) for File-based ro
 
 If these defaults work for your project, you don't need to configure anything at all! However, if you need to customize the configuration, you can do so by editing the configuration object passed into the `tanstackRouter` function.
 
-You can find all the available configuration options in the [File-based Routing API Reference](../../../api/file-based-routing.md).
+You can find all the available configuration options in the [File-based Routing API Reference](../api/file-based-routing.md).
diff --git a/docs/router/framework/react/installation/with-vite.md b/docs/router/installation/with-vite.md
similarity index 78%
rename from docs/router/framework/react/installation/with-vite.md
rename to docs/router/installation/with-vite.md
index 3288c7759d..64cf2cb2b7 100644
--- a/docs/router/framework/react/installation/with-vite.md
+++ b/docs/router/installation/with-vite.md
@@ -2,18 +2,22 @@
 title: Installation with Vite
 ---
 
-[//]: # 'BundlerConfiguration'
-
 To use file-based routing with **Vite**, you'll need to install the `@tanstack/router-plugin` package.
 
-```sh
-npm install -D @tanstack/router-plugin
-```
+<!-- ::start:tabs variant="package-manager" mode="dev-install" -->
+
+react: @tanstack/router-plugin
+solid: @tanstack/router-plugin
+
+<!-- ::end:tabs -->
 
 Once installed, you'll need to add the plugin to your Vite configuration.
 
-```ts
-// vite.config.ts
+<!-- ::start:framework -->
+
+# React
+
+```ts title="vite.config.ts"
 import { defineConfig } from 'vite'
 import react from '@vitejs/plugin-react'
 import { tanstackRouter } from '@tanstack/router-plugin/vite'
@@ -34,12 +38,31 @@ export default defineConfig({
 
 Or, you can clone our [Quickstart Vite example](https://github.com/TanStack/router/tree/main/examples/react/quickstart-file-based) and get started.
 
-> [!WARNING]
-> If you are using the older `@tanstack/router-vite-plugin` package, you can still continue to use it, as it will be aliased to the `@tanstack/router-plugin/vite` package. However, we would recommend using the `@tanstack/router-plugin` package directly.
+# Solid
 
-Now that you've added the plugin to your Vite configuration, you're all set to start using file-based routing with TanStack Router.
+```ts title="vite.config.ts"
+import { defineConfig } from 'vite'
+import solid from 'vite-plugin-solid'
+import { tanstackRouter } from '@tanstack/router-plugin/vite'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+  plugins: [
+    tanstackRouter({
+      target: 'solid',
+      autoCodeSplitting: true,
+    }),
+    solid(),
+    // ...
+  ],
+})
+```
 
-[//]: # 'BundlerConfiguration'
+Or, you can clone our [Quickstart Vite example](https://github.com/TanStack/router/tree/main/examples/solid/quickstart-file-based) and get started.
+
+<!-- ::end:framework -->
+
+Now that you've added the plugin to your Vite configuration, you're all set to start using file-based routing with TanStack Router.
 
 ## Ignoring the generated route tree file
 
@@ -87,4 +110,4 @@ When using the TanStack Router Plugin with Vite for File-based routing, it comes
 
 If these defaults work for your project, you don't need to configure anything at all! However, if you need to customize the configuration, you can do so by editing the configuration object passed into the `tanstackRouter` function.
 
-You can find all the available configuration options in the [File-based Routing API Reference](../../../api/file-based-routing.md).
+You can find all the available configuration options in the [File-based Routing API Reference](../api/file-based-routing.md).
diff --git a/docs/router/framework/solid/installation/with-webpack.md b/docs/router/installation/with-webpack.md
similarity index 81%
rename from docs/router/framework/solid/installation/with-webpack.md
rename to docs/router/installation/with-webpack.md
index ef884aacbf..ecee96a5ab 100644
--- a/docs/router/framework/solid/installation/with-webpack.md
+++ b/docs/router/installation/with-webpack.md
@@ -2,18 +2,39 @@
 title: Installation with Webpack
 ---
 
-[//]: # 'BundlerConfiguration'
-
 To use file-based routing with **Webpack**, you'll need to install the `@tanstack/router-plugin` package.
 
-```sh
-npm install -D @tanstack/router-plugin
-```
+<!-- ::start:tabs variant="package-manager" mode="dev-install" -->
+
+react: @tanstack/router-plugin
+solid: @tanstack/router-plugin
+
+<!-- ::end:tabs -->
 
 Once installed, you'll need to add the plugin to your configuration.
 
-```tsx
-// webpack.config.ts
+<!-- ::start:framework -->
+
+# React
+
+```ts title="webpack.config.ts"
+import { tanstackRouter } from '@tanstack/router-plugin/webpack'
+
+export default {
+  plugins: [
+    tanstackRouter({
+      target: 'react',
+      autoCodeSplitting: true,
+    }),
+  ],
+}
+```
+
+Or, you can clone our [Quickstart Webpack example](https://github.com/TanStack/router/tree/main/examples/react/quickstart-webpack-file-based) and get started.
+
+# Solid
+
+```ts title="webpack.config.ts"
 import { tanstackRouter } from '@tanstack/router-plugin/webpack'
 
 export default {
@@ -39,9 +60,9 @@ And in the .babelrc (SWC doesn't support solid-js, see [here](https://www.answer
 
 Or, for a full webpack.config.js, you can clone our [Quickstart Webpack example](https://github.com/TanStack/router/tree/main/examples/solid/quickstart-webpack-file-based) and get started.
 
-Now that you've added the plugin to your Webpack configuration, you're all set to start using file-based routing with TanStack Router.
+<!-- ::end:framework -->
 
-[//]: # 'BundlerConfiguration'
+Now that you've added the plugin to your Webpack configuration, you're all set to start using file-based routing with TanStack Router.
 
 ## Ignoring the generated route tree file
 
@@ -89,4 +110,4 @@ When using the TanStack Router Plugin with Webpack for File-based routing, it co
 
 If these defaults work for your project, you don't need to configure anything at all! However, if you need to customize the configuration, you can do so by editing the configuration object passed into the `tanstackRouter` function.
 
-You can find all the available configuration options in the [File-based Routing API Reference](../../../api/file-based-routing.md).
+You can find all the available configuration options in the [File-based Routing API Reference](../api/file-based-routing.md).
diff --git a/docs/router/integrations/query.md b/docs/router/integrations/query.md
index ab6687a870..22fbb927c8 100644
--- a/docs/router/integrations/query.md
+++ b/docs/router/integrations/query.md
@@ -4,7 +4,7 @@ title: TanStack Query Integration
 ---
 
 > [!IMPORTANT]
-> This integration automates SSR dehydration/hydration and streaming between TanStack Router and TanStack Query. If you haven't read the standard [External Data Loading](../framework/react/guide/external-data-loading.md) guide, start there.
+> This integration automates SSR dehydration/hydration and streaming between TanStack Router and TanStack Query. If you haven't read the standard [External Data Loading](../guide/external-data-loading.md) guide, start there.
 
 ## What you get
 
@@ -17,22 +17,22 @@ title: TanStack Query Integration
 
 The TanStack query integration is a separate package that you need to install:
 
-```sh
-npm install @tanstack/react-router-ssr-query
-# or
-pnpm add @tanstack/react-router-ssr-query
-# or
-yarn add @tanstack/react-router-ssr-query
-# or
-bun add @tanstack/react-router-ssr-query
-```
+<!-- ::start:tabs variant="package-manager" mode="dev-install" -->
+
+react: @tanstack/react-router-ssr-query
+solid: @tanstack/solid-router-ssr-query
+
+<!-- ::end:tabs -->
 
 ## Setup
 
 Create your router and wire up the integration. Ensure a fresh `QueryClient` is created per request in SSR environments.
 
-```tsx
-// src/router.tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/router.tsx"
 import { QueryClient } from '@tanstack/react-query'
 import { createRouter } from '@tanstack/react-router'
 import { setupRouterSsrQueryIntegration } from '@tanstack/react-router-ssr-query'
@@ -60,6 +60,8 @@ export function getRouter() {
 }
 ```
 
+<!-- ::end:framework -->
+
 By default, the integration wraps your router with a `QueryClientProvider`. If you already provide your own provider, pass `wrapQueryClient: false` and keep your custom wrapper.
 
 ## SSR behavior and streaming
@@ -83,12 +85,29 @@ const { data } = useSuspenseQuery(postsQuery)
 const { data, isLoading } = useQuery(postsQuery)
 ```
 
+<!-- ::start:framework -->
+
+# React
+
+```tsx
+// Suspense: executes on server and streams
+const { data } = useSuspenseQuery(postsQuery)
+
+// Non-suspense: executes only on client
+const { data, isLoading } = useQuery(postsQuery)
+```
+
+<!-- ::end:framework -->
+
 ### Preload with a loader and read with a hook
 
 Preload critical data in the route `loader` to avoid waterfalls and loading flashes, then read it in the component. The integration ensures server-fetched data is dehydrated and streamed to the client during SSR.
 
-```tsx
-// src/routes/posts.tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/posts.tsx"
 import { queryOptions, useSuspenseQuery, useQuery } from '@tanstack/react-query'
 import { createFileRoute } from '@tanstack/react-router'
 
@@ -110,11 +129,17 @@ function PostsPage() {
 }
 ```
 
+<!-- ::end:framework -->
+
 ### Prefetching and streaming
 
 You can also prefetch with `fetchQuery` or `ensureQueryData` in a loader without consuming the data in a component. If you return the promise directly from the loader, it will be awaited and thus block the SSR request until the query finishes. If you don't await the promise nor return it, the query will be started on the server and will be streamed to the client without blocking the SSR request.
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/users.$id.tsx"
 import { createFileRoute } from '@tanstack/react-router'
 import { queryOptions, useQuery } from '@tanstack/react-query'
 
@@ -132,6 +157,8 @@ export const Route = createFileRoute('/user/$id')({
 })
 ```
 
+<!-- ::end:framework -->
+
 ## Redirect handling
 
 If a query or mutation throws a `redirect(...)`, the integration intercepts it on the client and performs a router navigation.
diff --git a/docs/router/framework/react/llm-support.md b/docs/router/llm-support.md
similarity index 100%
rename from docs/router/framework/react/llm-support.md
rename to docs/router/llm-support.md
diff --git a/docs/router/framework/react/overview.md b/docs/router/overview.md
similarity index 100%
rename from docs/router/framework/react/overview.md
rename to docs/router/overview.md
diff --git a/docs/router/framework/react/quick-start.md b/docs/router/quick-start.md
similarity index 69%
rename from docs/router/framework/react/quick-start.md
rename to docs/router/quick-start.md
index 11f861e790..69ec50c538 100644
--- a/docs/router/framework/react/quick-start.md
+++ b/docs/router/quick-start.md
@@ -7,32 +7,22 @@ title: Quick Start
 
 The fastest way to get started with TanStack Router is to scaffold a new project. Just run:
 
-[//]: # 'createAppCommand'
+<!-- ::start:tabs variant="package-managers" mode="local-install" -->
 
-```sh
-npx create-tsrouter-app@latest
-```
+react: create-tsrouter-app@latest
+solid: create-tsrouter-app@latest --framework solid
 
-[//]: # 'createAppCommand'
+<!-- ::end:tabs -->
 
 The CLI will guide you through a short series of prompts to customize your setup, including options for:
 
-[//]: # 'CLIPrompts'
-
 - File-based or code-based route configuration
 - TypeScript support
 - Tailwind CSS integration
 - Toolchain setup
 - Git initialization
 
-[//]: # 'CLIPrompts'
-
-Once complete, a new React project will be generated with TanStack Router installed and ready to use:
-
-```sh
-cd your-project-name
-npm run dev
-```
+Once complete, a new project will be generated with TanStack Router installed and ready to use.
 
 > [!TIP]
 > For full details on available options and templates, visit the [`create-tsrouter-app` documentation](https://github.com/TanStack/create-tsrouter-app/tree/main/cli/create-tsrouter-app).
@@ -45,32 +35,25 @@ TanStack Router supports both file-based and code-based route configurations. Yo
 
 The file-based approach is the recommended option for most projects. It automatically creates routes based on your file structure, giving you the best mix of performance, simplicity, and developer experience.
 
-[//]: # 'createAppCommandFileBased'
+<!-- ::start:tabs variant="package-manager" mode="local-install" -->
 
-```sh
-npx create-tsrouter-app@latest my-app --template file-router
-```
+react: create-tsrouter-app@latest my-app --template file-router
+solid: create-tsrouter-app@latest my-app --framework solid --template file-router
 
-[//]: # 'createAppCommandFileBased'
+<!-- ::end:tabs -->
 
 ### Code-Based Route Configuration
 
 If you prefer to define routes programmatically, you can use the code-based route configuration. This approach gives you full control over routing logic.
 
-[//]: # 'createAppCommandCodeBased'
+<!-- ::start:tabs variant="package-manager" mode="local-install" -->
 
-```sh
-npx create-tsrouter-app@latest my-app
-```
-
-[//]: # 'createAppCommandCodeBased'
+react: create-tsrouter-app@latest my-app
+solid: create-tsrouter-app@latest my-app --framework solid
 
-With either approach, navigate to your project directory and start the development server:
+<!-- ::end:tabs -->
 
-```sh
-cd my-app
-npm run dev
-```
+With either approach, navigate to your project directory and start the development server.
 
 ## Existing Project
 
@@ -80,12 +63,18 @@ If you have an existing React project and want to add TanStack Router to it, you
 
 Before installing TanStack Router, please ensure your project meets the following requirements:
 
-[//]: # 'Requirements'
+<!-- ::start:framework -->
+
+# React
 
 - `react` v18 or later with `createRoot` support.
 - `react-dom` v18 or later.
 
-[//]: # 'Requirements'
+# Solid
+
+- `solid-js` v1.x.x
+
+<!-- ::end:framework -->
 
 > [!NOTE]
 > Using TypeScript (`v5.3.x or higher`) is recommended for the best development experience, though not strictly required. We aim to support the last 5 minor versions of TypeScript, but using the latest version will help avoid potential issues.
@@ -96,25 +85,18 @@ TanStack Router is currently only compatible with React (with ReactDOM) and Soli
 
 To install TanStack Router in your project, run the following command using your preferred package manager:
 
-[//]: # 'installCommand'
-
-```sh
-npm install @tanstack/react-router
-# or
-pnpm add @tanstack/react-router
-#or
-yarn add @tanstack/react-router
-# or
-bun add @tanstack/react-router
-# or
-deno add npm:@tanstack/react-router
-```
+<!-- ::start:tabs variant="package-managers" -->
+
+react: @tanstack/react-router
+solid: @tanstack/solid-router
 
-[//]: # 'installCommand'
+<!-- ::end:tabs -->
 
 Once installed, you can verify the installation by checking your `package.json` file for the dependency.
 
-[//]: # 'packageJson'
+<!-- ::start:framework -->
+
+# React
 
 ```json
 {
@@ -124,4 +106,14 @@ Once installed, you can verify the installation by checking your `package.json`
 }
 ```
 
-[//]: # 'packageJson'
+# Solid
+
+```json
+{
+  "dependencies": {
+    "@tanstack/solid-router": "^x.x.x"
+  }
+}
+```
+
+<!-- ::end:framework -->
diff --git a/docs/router/framework/react/routing/code-based-routing.md b/docs/router/routing/code-based-routing.md
similarity index 86%
rename from docs/router/framework/react/routing/code-based-routing.md
rename to docs/router/routing/code-based-routing.md
index 06fa322162..d3102cafd6 100644
--- a/docs/router/framework/react/routing/code-based-routing.md
+++ b/docs/router/routing/code-based-routing.md
@@ -40,6 +40,10 @@ routes/
 
 And here is a summarized code-based version:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 import { createRootRoute, createRoute } from '@tanstack/react-router'
 
@@ -111,6 +115,81 @@ const filesRoute = createRoute({
 })
 ```
 
+# Solid
+
+```tsx
+import { createRootRoute, createRoute } from '@tanstack/solid-router'
+
+const rootRoute = createRootRoute()
+
+const indexRoute = createRoute({
+  getParentRoute: () => rootRoute,
+  path: '/',
+})
+
+const aboutRoute = createRoute({
+  getParentRoute: () => rootRoute,
+  path: 'about',
+})
+
+const postsRoute = createRoute({
+  getParentRoute: () => rootRoute,
+  path: 'posts',
+})
+
+const postsIndexRoute = createRoute({
+  getParentRoute: () => postsRoute,
+  path: '/',
+})
+
+const postRoute = createRoute({
+  getParentRoute: () => postsRoute,
+  path: '$postId',
+})
+
+const postEditorRoute = createRoute({
+  getParentRoute: () => rootRoute,
+  path: 'posts/$postId/edit',
+})
+
+const settingsRoute = createRoute({
+  getParentRoute: () => rootRoute,
+  path: 'settings',
+})
+
+const profileRoute = createRoute({
+  getParentRoute: () => settingsRoute,
+  path: 'profile',
+})
+
+const notificationsRoute = createRoute({
+  getParentRoute: () => settingsRoute,
+  path: 'notifications',
+})
+
+const pathlessLayoutRoute = createRoute({
+  getParentRoute: () => rootRoute,
+  id: 'pathlessLayout',
+})
+
+const pathlessLayoutARoute = createRoute({
+  getParentRoute: () => pathlessLayoutRoute,
+  path: 'route-a',
+})
+
+const pathlessLayoutBRoute = createRoute({
+  getParentRoute: () => pathlessLayoutRoute,
+  path: 'route-b',
+})
+
+const filesRoute = createRoute({
+  getParentRoute: () => rootRoute,
+  path: 'files/$',
+})
+```
+
+<!-- ::end:framework -->
+
 ## Anatomy of a Route
 
 All other routes other than the root route are configured using the `createRoute` function:
@@ -198,6 +277,10 @@ Creating a root route in code-based routing is thankfully the same as doing so i
 
 Unlike file-based routing however, you do not need to export the root route if you don't want to. It's certainly not recommended to build an entire route tree and application in a single file (although you can and we do this in the examples to demonstrate routing concepts in brevity).
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 // Standard root route
 import { createRootRoute } from '@tanstack/react-router'
@@ -214,6 +297,26 @@ export interface MyRouterContext {
 const rootRoute = createRootRouteWithContext<MyRouterContext>()
 ```
 
+# Solid
+
+```tsx
+// Standard root route
+import { createRootRoute } from '@tanstack/solid-router'
+
+const rootRoute = createRootRoute()
+
+// Root route with Context
+import { createRootRouteWithContext } from '@tanstack/solid-router'
+import type { QueryClient } from '@tanstack/solid-query'
+
+export interface MyRouterContext {
+  queryClient: QueryClient
+}
+const rootRoute = createRootRouteWithContext<MyRouterContext>()
+```
+
+<!-- ::end:framework -->
+
 To learn more about Context in TanStack Router, see the [Router Context](../guide/router-context.md) guide.
 
 ## Basic Routes
diff --git a/docs/router/framework/react/routing/file-based-routing.md b/docs/router/routing/file-based-routing.md
similarity index 96%
rename from docs/router/framework/react/routing/file-based-routing.md
rename to docs/router/routing/file-based-routing.md
index d20827174e..6be11e55d6 100644
--- a/docs/router/framework/react/routing/file-based-routing.md
+++ b/docs/router/routing/file-based-routing.md
@@ -111,14 +111,23 @@ To get started with file-based routing, you'll need to configure your project's
 
 To enable file-based routing, you'll need to be using React with a supported bundler. See if your bundler is listed in the configuration guides below.
 
-[//]: # 'SupportedBundlersList'
+<!-- ::start:framework -->
+
+# React
+
+- [Installation with Vite](../installation/with-vite)
+- [Installation with Rspack/Rsbuild](../installation/with-rspack)
+- [Installation with Webpack](../installation/with-webpack)
+- [Installation with Esbuild](../installation/with-esbuild)
+
+# Solid
 
 - [Installation with Vite](../installation/with-vite)
 - [Installation with Rspack/Rsbuild](../installation/with-rspack)
 - [Installation with Webpack](../installation/with-webpack)
 - [Installation with Esbuild](../installation/with-esbuild)
 
-[//]: # 'SupportedBundlersList'
+<!-- ::end:framework -->
 
 When using TanStack Router's file-based routing through one of the supported bundlers, our plugin will **automatically generate your route configuration through your bundler's dev and build processes**. It is the easiest way to use TanStack Router's route generation features.
 
diff --git a/docs/router/framework/react/routing/file-naming-conventions.md b/docs/router/routing/file-naming-conventions.md
similarity index 86%
rename from docs/router/framework/react/routing/file-naming-conventions.md
rename to docs/router/routing/file-naming-conventions.md
index 2425e694a4..115310f5b3 100644
--- a/docs/router/framework/react/routing/file-naming-conventions.md
+++ b/docs/router/routing/file-naming-conventions.md
@@ -4,20 +4,20 @@ title: File Naming Conventions
 
 File-based routing requires that you follow a few simple file naming conventions to ensure that your routes are generated correctly. The concepts these conventions enable are covered in detail in the [Route Trees & Nesting](./route-trees.md) guide.
 
-| Feature                            | Description                                                                                                                                                                                                                                                                                                                                                                                                                |
-| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| **`__root.tsx`**                   | The root route file must be named `__root.tsx` and must be placed in the root of the configured `routesDirectory`.                                                                                                                                                                                                                                                                                                         |
-| **`.` Separator**                  | Routes can use the `.` character to denote a nested route. For example, `blog.post` will be generated as a child of `blog`.                                                                                                                                                                                                                                                                                                |
-| **`$` Token**                      | Route segments with the `$` token are parameterized and will extract the value from the URL pathname as a route `param`.                                                                                                                                                                                                                                                                                                   |
-| **`_` Prefix**                     | Route segments with the `_` prefix are considered to be pathless layout routes and will not be used when matching its child routes against the URL pathname.                                                                                                                                                                                                                                                               |
-| **`_` Suffix**                     | Route segments with the `_` suffix exclude the route from being nested under any parent routes.                                                                                                                                                                                                                                                                                                                            |
-| **`-` Prefix**                     | Files and folders with the `-` prefix are excluded from the route tree. They will not be added to the `routeTree.gen.ts` file and can be used to colocate logic in route folders.                                                                                                                                                                                                                                          |
-| **`(folder)` folder name pattern** | A folder that matches this pattern is treated as a **route group**, preventing the folder from being included in the route's URL path.                                                                                                                                                                                                                                                                                     |
-| **`[x]` Escaping**                 | Square brackets escape special characters in filenames that would otherwise have routing meaning. For example, `script[.]js.tsx` becomes `/script.js` and `api[.]v1.tsx` becomes `/api.v1`.                                                                                                                                                                                                                                |
-| **`index` Token**                  | Route segments ending with the `index` token (before any file extensions) will match the parent route when the URL pathname matches the parent route exactly. This can be configured via the `indexToken` configuration option (supports both strings and regex patterns), see [options](../../../api/file-based-routing.md#indextoken).                                                                                   |
-| **`.route.tsx` File Type**         | When using directories to organise routes, the `route` suffix can be used to create a route file at the directory's path. For example, `blog.post.route.tsx` or `blog/post/route.tsx` can be used as the route file for the `/blog/post` route. This can be configured via the `routeToken` configuration option (supports both strings and regex patterns), see [options](../../../api/file-based-routing.md#routetoken). |
-
-> **💡 Remember:** The file-naming conventions for your project could be affected by what [options](../../../api/file-based-routing.md) are configured.
+| Feature                            | Description                                                                                                                                                                                                                                                                                                                                                                                                          |
+| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| **`__root.tsx`**                   | The root route file must be named `__root.tsx` and must be placed in the root of the configured `routesDirectory`.                                                                                                                                                                                                                                                                                                   |
+| **`.` Separator**                  | Routes can use the `.` character to denote a nested route. For example, `blog.post` will be generated as a child of `blog`.                                                                                                                                                                                                                                                                                          |
+| **`$` Token**                      | Route segments with the `$` token are parameterized and will extract the value from the URL pathname as a route `param`.                                                                                                                                                                                                                                                                                             |
+| **`_` Prefix**                     | Route segments with the `_` prefix are considered to be pathless layout routes and will not be used when matching its child routes against the URL pathname.                                                                                                                                                                                                                                                         |
+| **`_` Suffix**                     | Route segments with the `_` suffix exclude the route from being nested under any parent routes.                                                                                                                                                                                                                                                                                                                      |
+| **`-` Prefix**                     | Files and folders with the `-` prefix are excluded from the route tree. They will not be added to the `routeTree.gen.ts` file and can be used to colocate logic in route folders.                                                                                                                                                                                                                                    |
+| **`(folder)` folder name pattern** | A folder that matches this pattern is treated as a **route group**, preventing the folder from being included in the route's URL path.                                                                                                                                                                                                                                                                               |
+| **`[x]` Escaping**                 | Square brackets escape special characters in filenames that would otherwise have routing meaning. For example, `script[.]js.tsx` becomes `/script.js` and `api[.]v1.tsx` becomes `/api.v1`.                                                                                                                                                                                                                          |
+| **`index` Token**                  | Route segments ending with the `index` token (before any file extensions) will match the parent route when the URL pathname matches the parent route exactly. This can be configured via the `indexToken` configuration option (supports both strings and regex patterns), see [options](../api/file-based-routing.md#indextoken).                                                                                   |
+| **`.route.tsx` File Type**         | When using directories to organise routes, the `route` suffix can be used to create a route file at the directory's path. For example, `blog.post.route.tsx` or `blog/post/route.tsx` can be used as the route file for the `/blog/post` route. This can be configured via the `routeToken` configuration option (supports both strings and regex patterns), see [options](../api/file-based-routing.md#routetoken). |
+
+> **💡 Remember:** The file-naming conventions for your project could be affected by what [options](../api/file-based-routing.md) are configured.
 
 ## Dynamic Path Params
 
diff --git a/docs/router/framework/react/routing/route-matching.md b/docs/router/routing/route-matching.md
similarity index 100%
rename from docs/router/framework/react/routing/route-matching.md
rename to docs/router/routing/route-matching.md
diff --git a/docs/router/framework/react/routing/route-trees.md b/docs/router/routing/route-trees.md
similarity index 100%
rename from docs/router/framework/react/routing/route-trees.md
rename to docs/router/routing/route-trees.md
diff --git a/docs/router/framework/react/routing/routing-concepts.md b/docs/router/routing/routing-concepts.md
similarity index 74%
rename from docs/router/framework/react/routing/routing-concepts.md
rename to docs/router/routing/routing-concepts.md
index dfb6bc91af..bcd507a45f 100644
--- a/docs/router/framework/react/routing/routing-concepts.md
+++ b/docs/router/routing/routing-concepts.md
@@ -10,7 +10,11 @@ Each of these concepts is useful and powerful, and we'll dive into each of them
 
 All other routes, other than the [Root Route](#the-root-route), are configured using the `createFileRoute` function, which provides type safety when using file-based routing:
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/index.tsx"
 import { createFileRoute } from '@tanstack/react-router'
 
 export const Route = createFileRoute('/')({
@@ -18,6 +22,18 @@ export const Route = createFileRoute('/')({
 })
 ```
 
+# Solid
+
+```tsx title="src/routes/index.tsx"
+import { createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/')({
+  component: PostsComponent,
+})
+```
+
+<!-- ::end:framework -->
+
 The `createFileRoute` function takes a single argument, the file-route's path as a string.
 
 **❓❓❓ "Wait, you're making me pass the path of the route file to `createFileRoute`?"**
@@ -43,6 +59,10 @@ Even though it doesn't have a path, the root route has access to all of the same
 
 To create a root route, call the `createRootRoute()` function and export it as the `Route` variable in your route file:
 
+<!-- ::start:framework -->
+
+# React
+
 ```tsx
 // Standard root route
 import { createRootRoute } from '@tanstack/react-router'
@@ -59,6 +79,26 @@ export interface MyRouterContext {
 export const Route = createRootRouteWithContext<MyRouterContext>()
 ```
 
+# Solid
+
+```tsx
+// Standard root route
+import { createRootRoute } from '@tanstack/solid-router'
+
+export const Route = createRootRoute()
+
+// Root route with Context
+import { createRootRouteWithContext } from '@tanstack/solid-router'
+import type { QueryClient } from '@tanstack/solid-query'
+
+export interface MyRouterContext {
+  queryClient: QueryClient
+}
+export const Route = createRootRouteWithContext<MyRouterContext>()
+```
+
+<!-- ::end:framework -->
+
 To learn more about Context in TanStack Router, see the [Router Context](../guide/router-context.md) guide.
 
 ## Basic Routes
@@ -67,8 +107,11 @@ Basic routes match a specific path, for example `/about`, `/settings`, `/setting
 
 Let's take a look at an `/about` route:
 
-```tsx
-// about.tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/about.tsx"
 import { createFileRoute } from '@tanstack/react-router'
 
 export const Route = createFileRoute('/about')({
@@ -80,6 +123,22 @@ function AboutComponent() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/about.tsx"
+import { createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/about')({
+  component: AboutComponent,
+})
+
+function AboutComponent() {
+  return <div>About</div>
+}
+```
+
+<!-- ::end:framework -->
+
 Basic routes are simple and straightforward. They match the path exactly and render the provided component.
 
 ## Index Routes
@@ -88,8 +147,11 @@ Index routes specifically target their parent route when it is **matched exactly
 
 Let's take a look at an index route for a `/posts` URL:
 
-```tsx
-// posts.index.tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/posts.index.tsx"
 import { createFileRoute } from '@tanstack/react-router'
 
 // Note the trailing slash, which is used to target index routes
@@ -102,6 +164,23 @@ function PostsIndexComponent() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/posts.index.tsx"
+import { createFileRoute } from '@tanstack/solid-router'
+
+// Note the trailing slash, which is used to target index routes
+export const Route = createFileRoute('/posts/')({
+  component: PostsIndexComponent,
+})
+
+function PostsIndexComponent() {
+  return <div>Please select a post!</div>
+}
+```
+
+<!-- ::end:framework -->
+
 This route will be matched when the URL is `/posts` exactly.
 
 ## Dynamic Route Segments
@@ -110,7 +189,11 @@ Route path segments that start with a `$` followed by a label are dynamic and ca
 
 These params are then usable in your route's configuration and components! Let's look at a `posts.$postId.tsx` route:
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/posts.tsx"
 import { createFileRoute } from '@tanstack/react-router'
 
 export const Route = createFileRoute('/posts/$postId')({
@@ -127,6 +210,27 @@ function PostComponent() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/posts.tsx"
+import { createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/posts/$postId')({
+  // In a loader
+  loader: ({ params }) => fetchPost(params.postId),
+  // Or in a component
+  component: PostComponent,
+})
+
+function PostComponent() {
+  // In a component!
+  const { postId } = Route.useParams()
+  return <div>Post ID: {postId()}</div>
+}
+```
+
+<!-- ::end:framework -->
+
 > 🧠 Dynamic segments work at **each** segment of the path. For example, you could have a route with the path of `/posts/$postId/$revisionId` and each `$` segment would be captured into the `params` object.
 
 ## Splat / Catch-All Routes
@@ -149,8 +253,12 @@ For example, a route targeting the `files/$` path is a splat route. If the URL p
 
 Optional path parameters allow you to define route segments that may or may not be present in the URL. They use the `{-$paramName}` syntax and provide flexible routing patterns where certain parameters are optional.
 
-```tsx
-// posts.{-$category}.tsx - Optional category parameter
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/posts.{-$category}.tsx"
+// The `-$category` segment is optional, so this route matches both `/posts` and `/posts/tech`
 import { createFileRoute } from '@tanstack/react-router'
 
 export const Route = createFileRoute('/posts/{-$category}')({
@@ -164,17 +272,55 @@ function PostsComponent() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/posts.{-$category}.tsx"
+// The `-$category` segment is optional, so this route matches both `/posts` and `/posts/tech`
+import { createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/posts/{-$category}')({
+  component: PostsComponent,
+})
+
+function PostsComponent() {
+  const { category } = Route.useParams()
+
+  return <div>{category ? `Posts in ${category()}` : 'All Posts'}</div>
+}
+```
+
+<!-- ::end:framework -->
+
 This route will match both `/posts` (category is `undefined`) and `/posts/tech` (category is `"tech"`).
 
 You can also define multiple optional parameters in a single route:
 
-```tsx
-// posts.{-$category}.{-$slug}.tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/posts.{-$category}.${-$slug}.tsx"
+// The `-$category` segment is optional, so this route matches both `/posts` and `/posts/tech`
+import { createFileRoute } from '@tanstack/react-router'
+
 export const Route = createFileRoute('/posts/{-$category}/{-$slug}')({
   component: PostsComponent,
 })
 ```
 
+# Solid
+
+```tsx title="src/routes/posts.{-$category}.${-$slug}.tsx"
+// The `-$category` segment is optional, so this route matches both `/posts` and `/posts/tech`
+import { createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/posts/{-$category}/{-$slug}')({
+  component: PostsComponent,
+})
+```
+
+<!-- ::end:framework -->
+
 This route matches `/posts`, `/posts/tech`, and `/posts/tech/hello-world`.
 
 > 🧠 Routes with optional parameters are ranked lower in priority than exact matches, ensuring that more specific routes like `/posts/featured` are matched before `/posts/{-$category}`.
@@ -203,7 +349,11 @@ In the tree above, `app.tsx` is a layout route that wraps two child routes, `app
 
 This tree structure is used to wrap the child routes with a layout component:
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/app.tsx"
 import { Outlet, createFileRoute } from '@tanstack/react-router'
 
 export const Route = createFileRoute('/app')({
@@ -220,6 +370,27 @@ function AppLayoutComponent() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/app.tsx"
+import { Outlet, createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/app')({
+  component: AppLayoutComponent,
+})
+
+function AppLayoutComponent() {
+  return (
+    <div>
+      <h1>App Layout</h1>
+      <Outlet />
+    </div>
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 The following table shows which component(s) will be rendered based on the URL:
 
 | URL Path         | Component                |
@@ -274,7 +445,11 @@ In the tree above, `_pathlessLayout.tsx` is a pathless layout route that wraps t
 
 The `_pathlessLayout.tsx` route is used to wrap the child routes with a Pathless layout component:
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/_pathlessLayout.tsx"
 import { Outlet, createFileRoute } from '@tanstack/react-router'
 
 export const Route = createFileRoute('/_pathlessLayout')({
@@ -291,6 +466,27 @@ function PathlessLayoutComponent() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/_pathlessLayout.tsx"
+import { Outlet, createFileRoute } from '@tanstack/solid-router'
+
+export const Route = createFileRoute('/_pathlessLayout')({
+  component: PathlessLayoutComponent,
+})
+
+function PathlessLayoutComponent() {
+  return (
+    <div>
+      <h1>Pathless layout</h1>
+      <Outlet />
+    </div>
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 The following table shows which component will be rendered based on the URL:
 
 | URL Path | Component             |
@@ -370,7 +566,11 @@ routes/
 
 We can import from the excluded files into our posts route
 
-```tsx
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="src/routes/posts.tsx"
 import { createFileRoute } from '@tanstack/react-router'
 import { PostsTable } from './-posts-table'
 import { PostsHeader } from './-components/header'
@@ -394,6 +594,34 @@ function PostComponent() {
 }
 ```
 
+# Solid
+
+```tsx title="src/routes/posts.tsx"
+import { createFileRoute } from '@tanstack/solid-router'
+import { PostsTable } from './-posts-table'
+import { PostsHeader } from './-components/header'
+import { PostsFooter } from './-components/footer'
+
+export const Route = createFileRoute('/posts')({
+  loader: () => fetchPosts(),
+  component: PostComponent,
+})
+
+function PostComponent() {
+  const posts = Route.useLoaderData()
+
+  return (
+    <div>
+      <PostsHeader />
+      <PostsTable posts={posts} />
+      <PostsFooter />
+    </div>
+  )
+}
+```
+
+<!-- ::end:framework -->
+
 The excluded files will not be added to `routeTree.gen.ts`.
 
 ## Pathless Route Group Directories
diff --git a/docs/router/framework/react/routing/virtual-file-routes.md b/docs/router/routing/virtual-file-routes.md
similarity index 90%
rename from docs/router/framework/react/routing/virtual-file-routes.md
rename to docs/router/routing/virtual-file-routes.md
index a285a49223..79754685e1 100644
--- a/docs/router/framework/react/routing/virtual-file-routes.md
+++ b/docs/router/routing/virtual-file-routes.md
@@ -49,8 +49,11 @@ Virtual file routes can be configured either via:
 
 If you're using the `TanStackRouter` plugin for Vite/Rspack/Webpack, you can configure virtual file routes by passing the path of your routes file to the `virtualRoutesConfig` option when setting up the plugin:
 
-```tsx
-// vite.config.ts
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="vite.config.ts"
 import { defineConfig } from 'vite'
 import react from '@vitejs/plugin-react'
 import { tanstackRouter } from '@tanstack/router-plugin/vite'
@@ -66,6 +69,26 @@ export default defineConfig({
 })
 ```
 
+# Solid
+
+```tsx title="vite.config.ts"
+import { defineConfig } from 'vite'
+import solid from 'vite-plugin-solid'
+import { tanstackRouter } from '@tanstack/router-plugin/vite'
+
+export default defineConfig({
+  plugins: [
+    tanstackRouter({
+      target: 'solid',
+      virtualRouteConfig: './routes.ts',
+    }),
+    solid(),
+  ],
+})
+```
+
+<!-- ::end:framework -->
+
 Or, you choose to define the virtual routes directly in the configuration:
 
 ```tsx
@@ -84,6 +107,48 @@ export default defineConfig({
 })
 ```
 
+<!-- ::start:framework -->
+
+# React
+
+```tsx title="vite.config.ts"
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+import { tanstackRouter } from '@tanstack/router-plugin/vite'
+
+const routes = rootRoute('root.tsx', [
+  // ... the rest of your virtual route tree
+])
+
+export default defineConfig({
+  plugins: [
+    tanstackRouter({ virtualRouteConfig: routes, target: 'react' }),
+    react(),
+  ],
+})
+```
+
+# Solid
+
+```tsx title="vite.config.ts"
+import { defineConfig } from 'vite'
+import solid from 'vite-plugin-solid'
+import { tanstackRouter } from '@tanstack/router-plugin/vite'
+
+const routes = rootRoute('root.tsx', [
+  // ... the rest of your virtual route tree
+])
+
+export default defineConfig({
+  plugins: [
+    tanstackRouter({ virtualRouteConfig: routes, target: 'solid' }),
+    solid(),
+  ],
+})
+```
+
+<!-- ::end:framework -->
+
 ## Creating Virtual File Routes
 
 To create virtual file routes, you'll need to import the `@tanstack/virtual-file-routes` package. This package provides a set of functions that allow you to create virtual routes that reference real files in your project. A few utility functions are exported from the package:
diff --git a/docs/start/config.json b/docs/start/config.json
index 396b1be4af..63604bea87 100644
--- a/docs/start/config.json
+++ b/docs/start/config.json
@@ -137,6 +137,10 @@
               "label": "Server Entry Point",
               "to": "framework/react/guide/server-entry-point"
             },
+            {
+              "label": "CDN Asset URLs",
+              "to": "framework/react/guide/cdn-asset-urls"
+            },
             {
               "label": "Client Entry Point",
               "to": "framework/react/guide/client-entry-point"
diff --git a/docs/start/framework/react/getting-started.md b/docs/start/framework/react/getting-started.md
index b88de7dc1e..7f3c1223d8 100644
--- a/docs/start/framework/react/getting-started.md
+++ b/docs/start/framework/react/getting-started.md
@@ -15,7 +15,7 @@ title: Getting Started
 Choose one of the following options to start building a _new_ TanStack Start project:
 
 - [TanStack Start CLI](./quick-start) - Just run `npm create @tanstack/start@latest`. Local, fast, and optionally customizable
-- [TanStack Builder](#) (coming soon!) - A visual interface to configure new TanStack projects with a few clicks
+- [TanStack Builder](https://tanstack.com/builder) - A visual interface to configure new TanStack projects with a few clicks
 - [Quick Start Examples](./quick-start) Download or clone one of our official examples
 - [Build a project from scratch](./build-from-scratch) - A guide to building a TanStack Start project line-by-line, file-by-file.
 
diff --git a/docs/start/framework/react/guide/cdn-asset-urls.md b/docs/start/framework/react/guide/cdn-asset-urls.md
new file mode 100644
index 0000000000..977c030c68
--- /dev/null
+++ b/docs/start/framework/react/guide/cdn-asset-urls.md
@@ -0,0 +1,224 @@
+---
+id: cdn-asset-urls
+title: CDN Asset URLs
+---
+
+# CDN Asset URLs
+
+> **Experimental:** `transformAssetUrls` is experimental and subject to change.
+
+When deploying to production, you may want to serve your static assets (JavaScript, CSS) from a CDN. The `transformAssetUrls` option on `createStartHandler` lets you rewrite asset URLs at runtime — for example, prepending a CDN origin that is only known when the server starts.
+
+## Why Runtime URL Rewriting?
+
+Vite's `base` config is evaluated at build time. If your CDN URL is determined at deploy time (via environment variables, dynamic configuration, etc.), you need a way to rewrite URLs at runtime. `transformAssetUrls` solves this for the URLs that TanStack Start manages in its manifest:
+
+- `<link rel="modulepreload">` tags (JS preloads)
+- `<link rel="stylesheet">` tags (CSS)
+- The client entry `<script>` tag
+
+## Basic Usage
+
+### String Prefix
+
+The simplest usage is passing a string. Every manifest asset URL will be prefixed with it:
+
+```tsx
+// src/server.ts
+import {
+  createStartHandler,
+  defaultStreamHandler,
+} from '@tanstack/react-start/server'
+import { createServerEntry } from '@tanstack/react-start/server-entry'
+
+const handler = createStartHandler({
+  handler: defaultStreamHandler,
+  transformAssetUrls: process.env.CDN_ORIGIN || '',
+})
+
+export default createServerEntry({ fetch: handler })
+```
+
+If `CDN_ORIGIN` is `https://cdn.example.com` and an asset URL is `/assets/index-abc123.js`, the resulting URL will be `https://cdn.example.com/assets/index-abc123.js`.
+
+When the string is empty (or not set), the URLs are left unchanged.
+
+### Callback
+
+For more control, pass a callback that receives `{ url, type }` and returns a new URL (or a `Promise` of one). By default, the transformed manifest is cached after the first request (`cache: true`), so the callback only runs once in production:
+
+```tsx
+// src/server.ts
+import {
+  createStartHandler,
+  defaultStreamHandler,
+} from '@tanstack/react-start/server'
+import { createServerEntry } from '@tanstack/react-start/server-entry'
+
+const handler = createStartHandler({
+  handler: defaultStreamHandler,
+  transformAssetUrls: ({ url, type }) => {
+    // Only rewrite JS and CSS, leave client entry unchanged
+    if (type === 'clientEntry') return url
+    return `https://cdn.example.com${url}`
+  },
+})
+
+export default createServerEntry({ fetch: handler })
+```
+
+If you need per-request behavior (for example, choosing a CDN based on a header), use the object form with `cache: false`.
+
+The `type` parameter tells you what kind of asset URL is being transformed:
+
+| `type`            | Description                                          |
+| ----------------- | ---------------------------------------------------- |
+| `'modulepreload'` | JS module preload URL (`<link rel="modulepreload">`) |
+| `'stylesheet'`    | CSS stylesheet URL (`<link rel="stylesheet">`)       |
+| `'clientEntry'`   | Client entry module URL (used in `import('...')`)    |
+
+### Object Form (Explicit Cache Control)
+
+For per-request transforms — where the CDN URL depends on request-specific data like headers — use the object form with `cache: false`:
+
+```tsx
+// src/server.ts
+import {
+  createStartHandler,
+  defaultStreamHandler,
+} from '@tanstack/react-start/server'
+import { createServerEntry } from '@tanstack/react-start/server-entry'
+import { getRequest } from '@tanstack/react-start/server'
+
+const handler = createStartHandler({
+  handler: defaultStreamHandler,
+  transformAssetUrls: {
+    transform: ({ url, type }) => {
+      const region = getRequest().headers.get('x-region') || 'us'
+      const cdnBase =
+        region === 'eu'
+          ? 'https://cdn-eu.example.com'
+          : 'https://cdn-us.example.com'
+      return `${cdnBase}${url}`
+    },
+    cache: false,
+  },
+})
+
+export default createServerEntry({ fetch: handler })
+```
+
+The object form accepts:
+
+| Property          | Type                                                                                                     | Description                                                                                                                   |
+| ----------------- | -------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
+| `transform`       | `string \| (asset) => string \| Promise<string>`                                                         | A string prefix or callback, same as the shorthand forms above.                                                               |
+| `createTransform` | `(ctx: { warmup: true } \| { warmup: false; request: Request }) => (asset) => string \| Promise<string>` | Async factory that runs once per manifest computation and returns a per-asset transform. Mutually exclusive with `transform`. |
+| `cache`           | `boolean`                                                                                                | Whether to cache the transformed manifest. Defaults to `true`.                                                                |
+| `warmup`          | `boolean`                                                                                                | When `true`, warms up the cached manifest on server startup (prod only). Defaults to `false`.                                 |
+
+If you need to do async work once per manifest computation (e.g. fetch a CDN origin from a service) and then transform many URLs, prefer `createTransform`:
+
+```ts
+transformAssetUrls: {
+  cache: false,
+  async createTransform(ctx) {
+    if (ctx.warmup) {
+      // optional: return a default transform during warmup
+      return ({ url }) => url
+    }
+
+    const region = ctx.request.headers.get('x-region') || 'us'
+    const cdnBase = await fetchCdnBaseForRegion(region)
+    return ({ url }) => `${cdnBase}${url}`
+  },
+}
+```
+
+## Caching Behavior
+
+By default, **all forms** of `transformAssetUrls` cache the transformed manifest after the first request (`cache: true`). This means the transform function runs once on the first request, and the result is reused for every subsequent request in production.
+
+| Form                                   | Default cache | Behavior                                                   |
+| -------------------------------------- | ------------- | ---------------------------------------------------------- |
+| String prefix                          | `true`        | Computed once, cached forever in prod.                     |
+| Callback                               | `true`        | Runs once on first request, cached forever in prod.        |
+| Object with `cache: true` (or omitted) | `true`        | Same as above.                                             |
+| Object with `cache: false`             | `false`       | Deep-clones base manifest and transforms on every request. |
+
+Use `cache: false` only when the transform depends on per-request data (e.g., geo-routing based on request headers). For static CDN prefixes, the default `cache: true` is recommended.
+
+### Optional Warmup (Avoid First-Request Latency)
+
+If you're using the object form with `cache: true`, you can set `warmup: true`
+to compute the transformed manifest in the background at server startup.
+
+```ts
+transformAssetUrls: {
+  transform: process.env.CDN_ORIGIN || '',
+  cache: true,
+  warmup: true,
+}
+```
+
+This has no effect in development mode, or when `cache: false`.
+
+> **Note:** In development mode (`TSS_DEV_SERVER`), caching is always skipped regardless of the `cache` setting, so you always get fresh manifests.
+
+## Recommended: Set `base: ''` for Client-Side Navigation
+
+`transformAssetUrls` rewrites the URLs in the SSR HTML — modulepreload hints, stylesheets, and the client entry script. This means the browser's initial page load fetches all assets from the CDN.
+
+However, when users navigate client-side (e.g., clicking a `<Link>`), TanStack Router lazy-loads route chunks using `import()` calls with paths that were baked in at **build time** by Vite. By default, Vite uses `base: '/'`, which produces absolute paths like `/assets/about-abc123.js`. These resolve against the **app server's origin**, not the CDN — even though the entry module was loaded from the CDN.
+
+To fix this, set `base: ''` in your Vite config:
+
+```ts
+// vite.config.ts
+export default defineConfig({
+  base: '',
+  // ... plugins, etc.
+})
+```
+
+With `base: ''`, Vite generates **relative** import paths for client-side chunks. Since the client entry module was loaded from the CDN (thanks to `transformAssetUrls`), all relative `import()` calls resolve against the CDN origin. This ensures that lazy-loaded route chunks during client-side navigation are also served from the CDN.
+
+Using an empty string rather than `'./'` is important — both produce relative client-side imports, but `base: ''` preserves the correct root-relative paths (`/assets/...`) in the SSR manifest so that `transformAssetUrls` can properly prepend the CDN origin.
+
+| `base` setting  | SSR assets (initial load)      | Client-side navigation chunks  |
+| --------------- | ------------------------------ | ------------------------------ |
+| `'/'` (default) | CDN (via `transformAssetUrls`) | App server                     |
+| `''`            | CDN (via `transformAssetUrls`) | CDN (relative to entry module) |
+
+> **Tip:** `base: ''` is recommended whenever you use `transformAssetUrls` so that all assets — both on initial load and during client-side navigation — are consistently served from the CDN.
+
+## What This Does NOT Cover
+
+`transformAssetUrls` only rewrites URLs in the TanStack Start manifest — the tags emitted during SSR for preloading and bootstrapping the application.
+
+It does **not** rewrite asset URLs that are imported directly in your components:
+
+```tsx
+// This import resolves to a URL at build time by Vite
+import logo from './logo.svg'
+
+function Header() {
+  return <img src={logo} /> // This URL is NOT affected by transformAssetUrls
+}
+```
+
+For these asset imports, use Vite's `experimental.renderBuiltUrl` in your `vite.config.ts`:
+
+```ts
+// vite.config.ts
+export default defineConfig({
+  experimental: {
+    renderBuiltUrl(filename, { hostType }) {
+      if (hostType === 'js') {
+        return { relative: true }
+      }
+      return `https://cdn.example.com/${filename}`
+    },
+  },
+})
+```
diff --git a/docs/start/framework/react/guide/hosting.md b/docs/start/framework/react/guide/hosting.md
index 94da0258c7..14b5f77e07 100644
--- a/docs/start/framework/react/guide/hosting.md
+++ b/docs/start/framework/react/guide/hosting.md
@@ -236,6 +236,25 @@ export default defineConfig({
 })
 ```
 
+#### Performance Tip: FastResponse
+
+If you're deploying to Node.js with Nitro (which uses [srvx](https://srvx.h3.dev/) under the hood), you can get a ~5% throughput improvement by replacing the global `Response` constructor with srvx's optimized `FastResponse`.
+
+First, install srvx:
+
+```bash
+npm install srvx
+```
+
+Then add this to your server entry point (`src/server.ts`):
+
+```ts
+import { FastResponse } from 'srvx'
+globalThis.Response = FastResponse
+```
+
+This works because srvx's `FastResponse` includes an optimized `_toNodeResponse()` path that avoids the overhead of the standard Web `Response` to Node.js conversion. This optimization only applies to Node.js deployments using Nitro/h3/srvx.
+
 ### Vercel
 
 Follow the [`Nitro`](#nitro) deployment instructions.
diff --git a/docs/start/framework/react/guide/isr.md b/docs/start/framework/react/guide/isr.md
index 600a282c20..ad1e322130 100644
--- a/docs/start/framework/react/guide/isr.md
+++ b/docs/start/framework/react/guide/isr.md
@@ -442,5 +442,5 @@ Track key metrics:
 - [Static Prerendering](./static-prerendering.md) - Build-time page generation
 - [Hosting](./hosting.md) - CDN deployment configurations
 - [Server Functions](./server-functions.md) - Creating dynamic data endpoints
-- [Data Loading](../../router/framework/react/guide/data-loading.md) - Client-side cache control
+- [Data Loading](../../../../router/guide/data-loading.md) - Client-side cache control
 - [Middleware](./middleware.md) - Request/response customization
diff --git a/docs/start/framework/react/guide/middleware.md b/docs/start/framework/react/guide/middleware.md
index 6578b0d5ca..b2e159814a 100644
--- a/docs/start/framework/react/guide/middleware.md
+++ b/docs/start/framework/react/guide/middleware.md
@@ -166,6 +166,8 @@ export const Route = createFileRoute('/foo')({
 You can pass middleware to specific server route methods by using the `createHandlers` utility and passing a middleware array to the `middleware` property of the method object.
 
 ```tsx
+import { createMiddleware } from '@tanstack/react-start'
+
 const loggingMiddleware = createMiddleware().server(() => {
   //...
 })
@@ -324,6 +326,8 @@ const loggingMiddleware = createMiddleware({ type: 'function' })
 **Client context is NOT sent to the server by default since this could end up unintentionally sending large payloads to the server.** If you need to send client context to the server, you must call the `next` function with a `sendContext` property and object to transmit any data to the server. Any properties passed to `sendContext` will be merged, serialized and sent to the server along with the data and will be available on the normal context object of any nested server middleware.
 
 ```tsx
+import { createMiddleware } from '@tanstack/react-start'
+
 const requestLogger = createMiddleware({ type: 'function' })
   .client(async ({ next, context }) => {
     return next({
@@ -345,6 +349,7 @@ const requestLogger = createMiddleware({ type: 'function' })
 You may have noticed that in the example above that while client-sent context is type-safe, it is is not required to be validated at runtime. If you pass dynamic user-generated data via context, that could pose a security concern, so **if you are sending dynamic data from the client to the server via context, you should validate it in the server-side middleware before using it.**
 
 ```tsx
+import { createMiddleware } from '@tanstack/react-start'
 import { zodValidator } from '@tanstack/zod-adapter'
 import { z } from 'zod'
 
@@ -372,6 +377,8 @@ Similar to sending client context to the server, you can also send server contex
 > The return type of `next` in `client` can only be inferred from middleware known in the current middleware chain. Therefore the most accurate return type of `next` is in middleware at the end of the middleware chain
 
 ```tsx
+import { createMiddleware } from '@tanstack/react-start'
+
 const serverTimer = createMiddleware({ type: 'function' }).server(
   async ({ next }) => {
     return next({
@@ -407,7 +414,7 @@ To have a middleware run for **every request handled by Start**, create a `src/s
 
 ```tsx
 // src/start.ts
-import { createStart } from '@tanstack/react-start'
+import { createStart, createMiddleware } from '@tanstack/react-start'
 
 const myGlobalMiddleware = createMiddleware().server(() => {
   //...
@@ -452,6 +459,8 @@ Middleware is executed dependency-first, starting with global middleware, follow
 - `fn`
 
 ```tsx
+import { createMiddleware, createServerFn } from '@tanstack/react-start'
+
 const globalMiddleware1 = createMiddleware({ type: 'function' }).server(
   async ({ next }) => {
     console.log('globalMiddleware1')
@@ -513,6 +522,7 @@ Middleware that uses the `client` method executes in a **completely different cl
 You can add headers to the outgoing request by passing a `headers` object to `next`:
 
 ```tsx
+import { createMiddleware } from '@tanstack/react-start'
 import { getToken } from 'my-auth-library'
 
 const authMiddleware = createMiddleware({ type: 'function' }).client(
@@ -531,6 +541,8 @@ const authMiddleware = createMiddleware({ type: 'function' }).client(
 When multiple middlewares set headers, they are **merged together**. Later middlewares can add new headers or override headers set by earlier middlewares:
 
 ```tsx
+import { createMiddleware } from '@tanstack/react-start'
+
 const firstMiddleware = createMiddleware({ type: 'function' }).client(
   async ({ next }) => {
     return next({
@@ -588,6 +600,7 @@ For advanced use cases, you can provide a custom `fetch` implementation to contr
 **Via Client Middleware:**
 
 ```tsx
+import { createMiddleware } from '@tanstack/react-start'
 import type { CustomFetch } from '@tanstack/react-start'
 
 const customFetchMiddleware = createMiddleware({ type: 'function' }).client(
@@ -638,6 +651,9 @@ When custom fetch implementations are provided at multiple levels, the following
 **Key principle:** The call site always wins. This allows you to override middleware behavior for specific calls when needed.
 
 ```tsx
+import { createMiddleware, createServerFn } from '@tanstack/react-start'
+import type { CustomFetch } from '@tanstack/react-start'
+
 // Middleware sets a fetch that adds logging
 const loggingMiddleware = createMiddleware({ type: 'function' }).client(
   async ({ next }) => {
@@ -671,6 +687,9 @@ await myServerFn({ fetch: testFetch }) // Uses testFetch, NOT loggingFetch
 When multiple middlewares provide fetch, the last one wins:
 
 ```tsx
+import { createMiddleware, createServerFn } from '@tanstack/react-start'
+import type { CustomFetch } from '@tanstack/react-start'
+
 const firstMiddleware = createMiddleware({ type: 'function' }).client(
   async ({ next }) => {
     const firstFetch: CustomFetch = (url, init) => {
diff --git a/docs/start/framework/react/guide/server-entry-point.md b/docs/start/framework/react/guide/server-entry-point.md
index a07014947e..90d6b2270c 100644
--- a/docs/start/framework/react/guide/server-entry-point.md
+++ b/docs/start/framework/react/guide/server-entry-point.md
@@ -100,3 +100,7 @@ The server entry point is where you can configure server-specific behavior:
 - Logging and monitoring
 
 This flexibility allows you to customize how your TanStack Start application handles server-side rendering while maintaining the framework's conventions.
+
+## Cloudflare Workers
+
+When deploying to Cloudflare Workers, you can extend `server.ts` to handle additional Workers features like queues, scheduled events, and Durable Objects. For a comprehensive guide, see the [Cloudflare Workers documentation for TanStack Start](https://developers.cloudflare.com/workers/framework-guides/web-apps/tanstack-start/#custom-entrypoints).
diff --git a/docs/start/framework/react/quick-start.md b/docs/start/framework/react/quick-start.md
index 24dd4dab43..d16f6683db 100644
--- a/docs/start/framework/react/quick-start.md
+++ b/docs/start/framework/react/quick-start.md
@@ -5,7 +5,7 @@ title: Quick Start
 
 ## Impatient?
 
-The fastest way to get a Start project up and running is with the cli. Just run
+The fastest way to get a Start project up and running is with the CLI. Just run
 
 ```
 pnpm create @tanstack/start@latest
@@ -34,7 +34,7 @@ Once you've cloned the example you want, head back to the [Routing](./guide/rout
 
 ## Examples
 
-TanStack Start has load of examples to get you started. Pick one of the examples below to get started!
+TanStack Start has a load of examples to get you started. Pick one of the examples below to get started!
 
 - [Basic](https://github.com/TanStack/router/tree/main/examples/react/start-basic) (start-basic)
 - [Basic + Auth](https://github.com/TanStack/router/tree/main/examples/react/start-basic-auth) (start-basic-auth)
@@ -66,7 +66,7 @@ npm install
 npm run dev
 ```
 
-Once you've clone or deployed an example, head back to the [Routing](./guide/routing) guide to learn how to use TanStack Start!
+Once you've cloned or deployed an example, head back to the [Routing](./guide/routing) guide to learn how to use TanStack Start!
 
 ## Other Router Examples
 
diff --git a/docs/start/framework/solid/guide/hosting.md b/docs/start/framework/solid/guide/hosting.md
index 913a82447d..5c374e8fd1 100644
--- a/docs/start/framework/solid/guide/hosting.md
+++ b/docs/start/framework/solid/guide/hosting.md
@@ -225,6 +225,25 @@ export default defineConfig({
 })
 ```
 
+#### Performance Tip: FastResponse
+
+If you're deploying to Node.js with Nitro (which uses [srvx](https://srvx.h3.dev/) under the hood), you can get a ~5% throughput improvement by replacing the global `Response` constructor with srvx's optimized `FastResponse`.
+
+First, install srvx:
+
+```bash
+pnpm install srvx
+```
+
+Then add this to your server entry point (`src/server.ts`):
+
+```ts
+import { FastResponse } from 'srvx'
+globalThis.Response = FastResponse
+```
+
+This works because srvx's `FastResponse` includes an optimized `_toNodeResponse()` path that avoids the overhead of the standard Web `Response` to Node.js conversion. This optimization only applies to Node.js deployments using Nitro/h3/srvx.
+
 ### Vercel
 
 Follow the [`Nitro`](#nitro) deployment instructions.
diff --git a/docs/start/framework/solid/quick-start.md b/docs/start/framework/solid/quick-start.md
index 320fc58f69..b311e8850a 100644
--- a/docs/start/framework/solid/quick-start.md
+++ b/docs/start/framework/solid/quick-start.md
@@ -17,7 +17,7 @@ or
 npm create @tanstack/start@latest -- --framework solid
 ```
 
-depending on your package manage of choice. You'll be prompted to add things like Tailwind, eslint, and a ton of other options.
+depending on your package manager of choice. You'll be prompted to add things like Tailwind, eslint, and a ton of other options.
 
 You can also clone and run the [Basic](https://github.com/TanStack/router/tree/main/examples/solid/start-basic) example right away with the following commands:
 
@@ -34,7 +34,7 @@ Once you've cloned the example you want, head back to the [Routing](./guide/rout
 
 ## Examples
 
-TanStack Start has load of examples to get you started. Pick one of the examples below to get started!
+TanStack Start has loads of examples to get you started. Pick one of the examples below to get started!
 
 - [Bare](https://github.com/TanStack/router/tree/main/examples/solid/start-bare) (start-bare)
 - [Basic](https://github.com/TanStack/router/tree/main/examples/solid/start-basic) (start-basic)
@@ -60,4 +60,4 @@ npm install
 npm run dev
 ```
 
-Once you've clone or deployed an example, head back to the [Routing](./guide/routing) guide to learn how to use TanStack Start!
+Once you've cloned or deployed an example, head back to the [Routing](./guide/routing) guide to learn how to use TanStack Start!
diff --git a/e2e/react-router/basic-file-based-code-splitting/src/routeTree.gen.ts b/e2e/react-router/basic-file-based-code-splitting/src/routeTree.gen.ts
index 442312342a..dfc5027f49 100644
--- a/e2e/react-router/basic-file-based-code-splitting/src/routeTree.gen.ts
+++ b/e2e/react-router/basic-file-based-code-splitting/src/routeTree.gen.ts
@@ -13,6 +13,7 @@ import type { CreateFileRoute, FileRoutesByPath } from '@tanstack/react-router'
 import { Route as rootRouteImport } from './routes/__root'
 import { Route as WithoutLoaderRouteImport } from './routes/without-loader'
 import { Route as ViewportTestRouteImport } from './routes/viewport-test'
+import { Route as SharedSingletonRouteImport } from './routes/shared-singleton'
 import { Route as PostsRouteImport } from './routes/posts'
 import { Route as LayoutRouteImport } from './routes/_layout'
 import { Route as IndexRouteImport } from './routes/index'
@@ -32,6 +33,11 @@ const ViewportTestRoute = ViewportTestRouteImport.update({
   path: '/viewport-test',
   getParentRoute: () => rootRouteImport,
 } as any)
+const SharedSingletonRoute = SharedSingletonRouteImport.update({
+  id: '/shared-singleton',
+  path: '/shared-singleton',
+  getParentRoute: () => rootRouteImport,
+} as any)
 const PostsRoute = PostsRouteImport.update({
   id: '/posts',
   path: '/posts',
@@ -74,6 +80,7 @@ const LayoutLayout2LayoutARoute = LayoutLayout2LayoutARouteImport.update({
 export interface FileRoutesByFullPath {
   '/': typeof IndexRoute
   '/posts': typeof PostsRouteWithChildren
+  '/shared-singleton': typeof SharedSingletonRoute
   '/viewport-test': typeof ViewportTestRoute
   '/without-loader': typeof WithoutLoaderRoute
   '/posts/$postId': typeof PostsPostIdRoute
@@ -83,6 +90,7 @@ export interface FileRoutesByFullPath {
 }
 export interface FileRoutesByTo {
   '/': typeof IndexRoute
+  '/shared-singleton': typeof SharedSingletonRoute
   '/viewport-test': typeof ViewportTestRoute
   '/without-loader': typeof WithoutLoaderRoute
   '/posts/$postId': typeof PostsPostIdRoute
@@ -95,6 +103,7 @@ export interface FileRoutesById {
   '/': typeof IndexRoute
   '/_layout': typeof LayoutRouteWithChildren
   '/posts': typeof PostsRouteWithChildren
+  '/shared-singleton': typeof SharedSingletonRoute
   '/viewport-test': typeof ViewportTestRoute
   '/without-loader': typeof WithoutLoaderRoute
   '/_layout/_layout-2': typeof LayoutLayout2RouteWithChildren
@@ -108,6 +117,7 @@ export interface FileRouteTypes {
   fullPaths:
     | '/'
     | '/posts'
+    | '/shared-singleton'
     | '/viewport-test'
     | '/without-loader'
     | '/posts/$postId'
@@ -117,6 +127,7 @@ export interface FileRouteTypes {
   fileRoutesByTo: FileRoutesByTo
   to:
     | '/'
+    | '/shared-singleton'
     | '/viewport-test'
     | '/without-loader'
     | '/posts/$postId'
@@ -128,6 +139,7 @@ export interface FileRouteTypes {
     | '/'
     | '/_layout'
     | '/posts'
+    | '/shared-singleton'
     | '/viewport-test'
     | '/without-loader'
     | '/_layout/_layout-2'
@@ -141,6 +153,7 @@ export interface RootRouteChildren {
   IndexRoute: typeof IndexRoute
   LayoutRoute: typeof LayoutRouteWithChildren
   PostsRoute: typeof PostsRouteWithChildren
+  SharedSingletonRoute: typeof SharedSingletonRoute
   ViewportTestRoute: typeof ViewportTestRoute
   WithoutLoaderRoute: typeof WithoutLoaderRoute
 }
@@ -161,6 +174,13 @@ declare module '@tanstack/react-router' {
       preLoaderRoute: typeof ViewportTestRouteImport
       parentRoute: typeof rootRouteImport
     }
+    '/shared-singleton': {
+      id: '/shared-singleton'
+      path: '/shared-singleton'
+      fullPath: '/shared-singleton'
+      preLoaderRoute: typeof SharedSingletonRouteImport
+      parentRoute: typeof rootRouteImport
+    }
     '/posts': {
       id: '/posts'
       path: '/posts'
@@ -171,7 +191,7 @@ declare module '@tanstack/react-router' {
     '/_layout': {
       id: '/_layout'
       path: ''
-      fullPath: ''
+      fullPath: '/'
       preLoaderRoute: typeof LayoutRouteImport
       parentRoute: typeof rootRouteImport
     }
@@ -199,7 +219,7 @@ declare module '@tanstack/react-router' {
     '/_layout/_layout-2': {
       id: '/_layout/_layout-2'
       path: ''
-      fullPath: ''
+      fullPath: '/'
       preLoaderRoute: typeof LayoutLayout2RouteImport
       parentRoute: typeof LayoutRoute
     }
@@ -247,6 +267,15 @@ declare module './routes/posts' {
     FileRoutesByPath['/posts']['fullPath']
   >
 }
+declare module './routes/shared-singleton' {
+  const createFileRoute: CreateFileRoute<
+    '/shared-singleton',
+    FileRoutesByPath['/shared-singleton']['parentRoute'],
+    FileRoutesByPath['/shared-singleton']['id'],
+    FileRoutesByPath['/shared-singleton']['path'],
+    FileRoutesByPath['/shared-singleton']['fullPath']
+  >
+}
 declare module './routes/viewport-test' {
   const createFileRoute: CreateFileRoute<
     '/viewport-test',
@@ -352,6 +381,7 @@ const rootRouteChildren: RootRouteChildren = {
   IndexRoute: IndexRoute,
   LayoutRoute: LayoutRouteWithChildren,
   PostsRoute: PostsRouteWithChildren,
+  SharedSingletonRoute: SharedSingletonRoute,
   ViewportTestRoute: ViewportTestRoute,
   WithoutLoaderRoute: WithoutLoaderRoute,
 }
diff --git a/e2e/react-router/basic-file-based-code-splitting/src/routes/__root.tsx b/e2e/react-router/basic-file-based-code-splitting/src/routes/__root.tsx
index 8820f73e53..cb2a94ee19 100644
--- a/e2e/react-router/basic-file-based-code-splitting/src/routes/__root.tsx
+++ b/e2e/react-router/basic-file-based-code-splitting/src/routes/__root.tsx
@@ -51,6 +51,15 @@ function RootComponent() {
         >
           without-loader
         </Link>{' '}
+        <Link
+          to="/shared-singleton"
+          activeProps={{
+            className: 'font-bold',
+          }}
+          data-testid="shared-singleton-link"
+        >
+          shared-singleton
+        </Link>{' '}
         <Link
           // @ts-expect-error
           to="/this-route-does-not-exist"
diff --git a/e2e/react-router/basic-file-based-code-splitting/src/routes/shared-singleton.tsx b/e2e/react-router/basic-file-based-code-splitting/src/routes/shared-singleton.tsx
new file mode 100644
index 0000000000..b0a20b5991
--- /dev/null
+++ b/e2e/react-router/basic-file-based-code-splitting/src/routes/shared-singleton.tsx
@@ -0,0 +1,54 @@
+import * as React from 'react'
+
+// All shared state lives in declarations — no bare expression statements.
+// The singleton tracks how many times this module scope executes.
+const singleton = (() => {
+  const g = globalThis as any
+  g.__tsrSharedSingleton ??= { initCount: 0 }
+  g.__tsrSharedSingleton.initCount++
+  return { initCountAtCreate: g.__tsrSharedSingleton.initCount as number }
+})()
+
+function getInitCount() {
+  return (globalThis as any).__tsrSharedSingleton?.initCount as number
+}
+
+export const Route = createFileRoute({
+  loader: () => {
+    return {
+      loaderSawInitCount: getInitCount(),
+      initCountAtCreateFromLoader: singleton.initCountAtCreate,
+    }
+  },
+  component: SharedSingletonComponent,
+})
+
+function SharedSingletonComponent() {
+  const data = Route.useLoaderData()
+
+  return (
+    <div className="p-2 space-y-2">
+      <h3 className="text-lg font-bold">Shared Singleton</h3>
+      <div>
+        initCount (global):{' '}
+        <span data-testid="shared-init-count">{getInitCount()}</span>
+      </div>
+      <div>
+        loaderSawInitCount:{' '}
+        <span data-testid="shared-loader-saw">{data.loaderSawInitCount}</span>
+      </div>
+      <div>
+        initCountAtCreate (loader module):{' '}
+        <span data-testid="shared-created-at-loader">
+          {data.initCountAtCreateFromLoader}
+        </span>
+      </div>
+      <div>
+        initCountAtCreate (component module):{' '}
+        <span data-testid="shared-created-at-module">
+          {singleton.initCountAtCreate}
+        </span>
+      </div>
+    </div>
+  )
+}
diff --git a/e2e/react-router/basic-file-based-code-splitting/tests/shared-bindings.spec.ts b/e2e/react-router/basic-file-based-code-splitting/tests/shared-bindings.spec.ts
new file mode 100644
index 0000000000..512943c10d
--- /dev/null
+++ b/e2e/react-router/basic-file-based-code-splitting/tests/shared-bindings.spec.ts
@@ -0,0 +1,17 @@
+import { expect, test } from '@playwright/test'
+
+test.beforeEach(async ({ page }) => {
+  await page.goto('/')
+})
+
+test('shared module bindings should init once', async ({ page }) => {
+  await page.getByTestId('shared-singleton-link').click()
+
+  // If module scope is duplicated between reference + split chunk, this becomes "2".
+  await expect(page.getByTestId('shared-init-count')).toHaveText('1')
+
+  // Extra signals (useful when debugging failures)
+  await expect(page.getByTestId('shared-loader-saw')).toHaveText('1')
+  await expect(page.getByTestId('shared-created-at-loader')).toHaveText('1')
+  await expect(page.getByTestId('shared-created-at-module')).toHaveText('1')
+})
diff --git a/e2e/react-router/basic-file-based/src/routeTree.gen.ts b/e2e/react-router/basic-file-based/src/routeTree.gen.ts
index ad5f737ec7..0453e9ae8a 100644
--- a/e2e/react-router/basic-file-based/src/routeTree.gen.ts
+++ b/e2e/react-router/basic-file-based/src/routeTree.gen.ts
@@ -42,6 +42,7 @@ import { Route as anotherGroupOnlyrouteinsideRouteImport } from './routes/(anoth
 import { Route as RelativeUseNavigateRouteRouteImport } from './routes/relative/useNavigate/route'
 import { Route as RelativeLinkRouteRouteImport } from './routes/relative/link/route'
 import { Route as PathlessLayoutLayoutRouteRouteImport } from './routes/pathless-layout/_layout/route'
+import { Route as ParamsPsStrictFalseRouteRouteImport } from './routes/params-ps/strict-false/route'
 import { Route as ParamsPsNonNestedRouteRouteImport } from './routes/params-ps/non-nested/route'
 import { Route as NonNestedSuffixRouteRouteImport } from './routes/non-nested/suffix/route'
 import { Route as NonNestedPrefixRouteRouteImport } from './routes/non-nested/prefix/route'
@@ -87,6 +88,7 @@ import { Route as LayoutLayout2LayoutBRouteImport } from './routes/_layout/_layo
 import { Route as LayoutLayout2LayoutARouteImport } from './routes/_layout/_layout-2/layout-a'
 import { Route as groupSubfolderInsideRouteImport } from './routes/(group)/subfolder/inside'
 import { Route as groupLayoutInsidelayoutRouteImport } from './routes/(group)/_layout.insidelayout'
+import { Route as ParamsPsStrictFalseVersionRouteRouteImport } from './routes/params-ps/strict-false/$version.route'
 import { Route as ParamsPsNonNestedFooRouteRouteImport } from './routes/params-ps/non-nested/$foo_/route'
 import { Route as ParamsPsNamedFooRouteRouteImport } from './routes/params-ps/named/$foo/route'
 import { Route as NonNestedSuffixChar123bazChar125suffixRouteRouteImport } from './routes/non-nested/suffix/{$baz}suffix.route'
@@ -295,6 +297,12 @@ const PathlessLayoutLayoutRouteRoute =
     id: '/_layout',
     getParentRoute: () => PathlessLayoutRouteRoute,
   } as any)
+const ParamsPsStrictFalseRouteRoute =
+  ParamsPsStrictFalseRouteRouteImport.update({
+    id: '/params-ps/strict-false',
+    path: '/params-ps/strict-false',
+    getParentRoute: () => rootRouteImport,
+  } as any)
 const ParamsPsNonNestedRouteRoute = ParamsPsNonNestedRouteRouteImport.update({
   id: '/params-ps/non-nested',
   path: '/params-ps/non-nested',
@@ -539,6 +547,12 @@ const groupLayoutInsidelayoutRoute = groupLayoutInsidelayoutRouteImport.update({
   path: '/insidelayout',
   getParentRoute: () => groupLayoutRoute,
 } as any)
+const ParamsPsStrictFalseVersionRouteRoute =
+  ParamsPsStrictFalseVersionRouteRouteImport.update({
+    id: '/$version',
+    path: '/$version',
+    getParentRoute: () => ParamsPsStrictFalseRouteRoute,
+  } as any)
 const ParamsPsNonNestedFooRouteRoute =
   ParamsPsNonNestedFooRouteRouteImport.update({
     id: '/$foo_',
@@ -780,6 +794,7 @@ export interface FileRoutesByFullPath {
   '/non-nested/prefix': typeof NonNestedPrefixRouteRouteWithChildren
   '/non-nested/suffix': typeof NonNestedSuffixRouteRouteWithChildren
   '/params-ps/non-nested': typeof ParamsPsNonNestedRouteRouteWithChildren
+  '/params-ps/strict-false': typeof ParamsPsStrictFalseRouteRouteWithChildren
   '/relative/link': typeof RelativeLinkRouteRouteWithChildren
   '/relative/useNavigate': typeof RelativeUseNavigateRouteRouteWithChildren
   '/onlyrouteinside': typeof anotherGroupOnlyrouteinsideRoute
@@ -801,6 +816,7 @@ export interface FileRoutesByFullPath {
   '/non-nested/suffix/{$baz}suffix': typeof NonNestedSuffixChar123bazChar125suffixRouteRouteWithChildren
   '/params-ps/named/$foo': typeof ParamsPsNamedFooRouteRouteWithChildren
   '/params-ps/non-nested/$foo': typeof ParamsPsNonNestedFooRouteRouteWithChildren
+  '/params-ps/strict-false/$version': typeof ParamsPsStrictFalseVersionRouteRoute
   '/insidelayout': typeof groupLayoutInsidelayoutRoute
   '/subfolder/inside': typeof groupSubfolderInsideRoute
   '/layout-a': typeof LayoutLayout2LayoutARoute
@@ -892,6 +908,7 @@ export interface FileRoutesByTo {
   '/non-nested/prefix': typeof NonNestedPrefixRouteRouteWithChildren
   '/non-nested/suffix': typeof NonNestedSuffixRouteRouteWithChildren
   '/params-ps/non-nested': typeof ParamsPsNonNestedRouteRouteWithChildren
+  '/params-ps/strict-false': typeof ParamsPsStrictFalseRouteRouteWithChildren
   '/relative/link': typeof RelativeLinkRouteRouteWithChildren
   '/relative/useNavigate': typeof RelativeUseNavigateRouteRouteWithChildren
   '/onlyrouteinside': typeof anotherGroupOnlyrouteinsideRoute
@@ -907,6 +924,7 @@ export interface FileRoutesByTo {
   '/search-params': typeof SearchParamsIndexRoute
   '/params-ps/named/$foo': typeof ParamsPsNamedFooRouteRouteWithChildren
   '/params-ps/non-nested/$foo': typeof ParamsPsNonNestedFooRouteRouteWithChildren
+  '/params-ps/strict-false/$version': typeof ParamsPsStrictFalseVersionRouteRoute
   '/insidelayout': typeof groupLayoutInsidelayoutRoute
   '/subfolder/inside': typeof groupSubfolderInsideRoute
   '/layout-a': typeof LayoutLayout2LayoutARoute
@@ -999,6 +1017,7 @@ export interface FileRoutesById {
   '/non-nested/prefix': typeof NonNestedPrefixRouteRouteWithChildren
   '/non-nested/suffix': typeof NonNestedSuffixRouteRouteWithChildren
   '/params-ps/non-nested': typeof ParamsPsNonNestedRouteRouteWithChildren
+  '/params-ps/strict-false': typeof ParamsPsStrictFalseRouteRouteWithChildren
   '/pathless-layout/_layout': typeof PathlessLayoutLayoutRouteRouteWithChildren
   '/relative/link': typeof RelativeLinkRouteRouteWithChildren
   '/relative/useNavigate': typeof RelativeUseNavigateRouteRouteWithChildren
@@ -1023,6 +1042,7 @@ export interface FileRoutesById {
   '/non-nested/suffix/{$baz}suffix': typeof NonNestedSuffixChar123bazChar125suffixRouteRouteWithChildren
   '/params-ps/named/$foo': typeof ParamsPsNamedFooRouteRouteWithChildren
   '/params-ps/non-nested/$foo_': typeof ParamsPsNonNestedFooRouteRouteWithChildren
+  '/params-ps/strict-false/$version': typeof ParamsPsStrictFalseVersionRouteRoute
   '/(group)/_layout/insidelayout': typeof groupLayoutInsidelayoutRoute
   '/(group)/subfolder/inside': typeof groupSubfolderInsideRoute
   '/_layout/_layout-2/layout-a': typeof LayoutLayout2LayoutARoute
@@ -1118,6 +1138,7 @@ export interface FileRouteTypes {
     | '/non-nested/prefix'
     | '/non-nested/suffix'
     | '/params-ps/non-nested'
+    | '/params-ps/strict-false'
     | '/relative/link'
     | '/relative/useNavigate'
     | '/onlyrouteinside'
@@ -1139,6 +1160,7 @@ export interface FileRouteTypes {
     | '/non-nested/suffix/{$baz}suffix'
     | '/params-ps/named/$foo'
     | '/params-ps/non-nested/$foo'
+    | '/params-ps/strict-false/$version'
     | '/insidelayout'
     | '/subfolder/inside'
     | '/layout-a'
@@ -1230,6 +1252,7 @@ export interface FileRouteTypes {
     | '/non-nested/prefix'
     | '/non-nested/suffix'
     | '/params-ps/non-nested'
+    | '/params-ps/strict-false'
     | '/relative/link'
     | '/relative/useNavigate'
     | '/onlyrouteinside'
@@ -1245,6 +1268,7 @@ export interface FileRouteTypes {
     | '/search-params'
     | '/params-ps/named/$foo'
     | '/params-ps/non-nested/$foo'
+    | '/params-ps/strict-false/$version'
     | '/insidelayout'
     | '/subfolder/inside'
     | '/layout-a'
@@ -1336,6 +1360,7 @@ export interface FileRouteTypes {
     | '/non-nested/prefix'
     | '/non-nested/suffix'
     | '/params-ps/non-nested'
+    | '/params-ps/strict-false'
     | '/pathless-layout/_layout'
     | '/relative/link'
     | '/relative/useNavigate'
@@ -1360,6 +1385,7 @@ export interface FileRouteTypes {
     | '/non-nested/suffix/{$baz}suffix'
     | '/params-ps/named/$foo'
     | '/params-ps/non-nested/$foo_'
+    | '/params-ps/strict-false/$version'
     | '/(group)/_layout/insidelayout'
     | '/(group)/subfolder/inside'
     | '/_layout/_layout-2/layout-a'
@@ -1450,6 +1476,7 @@ export interface RootRouteChildren {
   PostsRoute: typeof PostsRouteWithChildren
   RemountDepsRoute: typeof RemountDepsRoute
   ParamsPsNonNestedRouteRoute: typeof ParamsPsNonNestedRouteRouteWithChildren
+  ParamsPsStrictFalseRouteRoute: typeof ParamsPsStrictFalseRouteRouteWithChildren
   RelativeLinkRouteRoute: typeof RelativeLinkRouteRouteWithChildren
   RelativeUseNavigateRouteRoute: typeof RelativeUseNavigateRouteRouteWithChildren
   anotherGroupOnlyrouteinsideRoute: typeof anotherGroupOnlyrouteinsideRoute
@@ -1712,6 +1739,13 @@ declare module '@tanstack/react-router' {
       preLoaderRoute: typeof PathlessLayoutLayoutRouteRouteImport
       parentRoute: typeof PathlessLayoutRouteRoute
     }
+    '/params-ps/strict-false': {
+      id: '/params-ps/strict-false'
+      path: '/params-ps/strict-false'
+      fullPath: '/params-ps/strict-false'
+      preLoaderRoute: typeof ParamsPsStrictFalseRouteRouteImport
+      parentRoute: typeof rootRouteImport
+    }
     '/params-ps/non-nested': {
       id: '/params-ps/non-nested'
       path: '/params-ps/non-nested'
@@ -2027,6 +2061,13 @@ declare module '@tanstack/react-router' {
       preLoaderRoute: typeof groupLayoutInsidelayoutRouteImport
       parentRoute: typeof groupLayoutRoute
     }
+    '/params-ps/strict-false/$version': {
+      id: '/params-ps/strict-false/$version'
+      path: '/$version'
+      fullPath: '/params-ps/strict-false/$version'
+      preLoaderRoute: typeof ParamsPsStrictFalseVersionRouteRouteImport
+      parentRoute: typeof ParamsPsStrictFalseRouteRoute
+    }
     '/params-ps/non-nested/$foo_': {
       id: '/params-ps/non-nested/$foo_'
       path: '/$foo'
@@ -2669,6 +2710,20 @@ const ParamsPsNonNestedRouteRouteWithChildren =
     ParamsPsNonNestedRouteRouteChildren,
   )
 
+interface ParamsPsStrictFalseRouteRouteChildren {
+  ParamsPsStrictFalseVersionRouteRoute: typeof ParamsPsStrictFalseVersionRouteRoute
+}
+
+const ParamsPsStrictFalseRouteRouteChildren: ParamsPsStrictFalseRouteRouteChildren =
+  {
+    ParamsPsStrictFalseVersionRouteRoute: ParamsPsStrictFalseVersionRouteRoute,
+  }
+
+const ParamsPsStrictFalseRouteRouteWithChildren =
+  ParamsPsStrictFalseRouteRoute._addFileChildren(
+    ParamsPsStrictFalseRouteRouteChildren,
+  )
+
 interface RelativeLinkRouteRouteChildren {
   RelativeLinkRelativeLinkARoute: typeof RelativeLinkRelativeLinkARoute
   RelativeLinkRelativeLinkBRoute: typeof RelativeLinkRelativeLinkBRoute
@@ -2811,6 +2866,7 @@ const rootRouteChildren: RootRouteChildren = {
   PostsRoute: PostsRouteWithChildren,
   RemountDepsRoute: RemountDepsRoute,
   ParamsPsNonNestedRouteRoute: ParamsPsNonNestedRouteRouteWithChildren,
+  ParamsPsStrictFalseRouteRoute: ParamsPsStrictFalseRouteRouteWithChildren,
   RelativeLinkRouteRoute: RelativeLinkRouteRouteWithChildren,
   RelativeUseNavigateRouteRoute: RelativeUseNavigateRouteRouteWithChildren,
   anotherGroupOnlyrouteinsideRoute: anotherGroupOnlyrouteinsideRoute,
diff --git a/e2e/react-router/basic-file-based/src/routes/params-ps/index.tsx b/e2e/react-router/basic-file-based/src/routes/params-ps/index.tsx
index 02235bc3da..b8976b901b 100644
--- a/e2e/react-router/basic-file-based/src/routes/params-ps/index.tsx
+++ b/e2e/react-router/basic-file-based/src/routes/params-ps/index.tsx
@@ -122,6 +122,28 @@ function RouteComponent() {
           </Link>
         </li>
       </ul>
+      <hr />
+      <h3 className="pb-2">Parsed params with strict false</h3>
+      <ul className="grid mb-2">
+        <li>
+          <Link
+            data-testid="strict-false-version-1"
+            to="/params-ps/strict-false/$version"
+            params={{ version: 1 }}
+          >
+            /params-ps/strict-false/$version (1)
+          </Link>
+        </li>
+        <li>
+          <Link
+            data-testid="strict-false-version-2"
+            to="/params-ps/strict-false/$version"
+            params={{ version: 2 }}
+          >
+            /params-ps/strict-false/$version (2)
+          </Link>
+        </li>
+      </ul>
     </div>
   )
 }
diff --git a/e2e/react-router/basic-file-based/src/routes/params-ps/strict-false/$version.route.tsx b/e2e/react-router/basic-file-based/src/routes/params-ps/strict-false/$version.route.tsx
new file mode 100644
index 0000000000..6803de8c9b
--- /dev/null
+++ b/e2e/react-router/basic-file-based/src/routes/params-ps/strict-false/$version.route.tsx
@@ -0,0 +1,21 @@
+import { createFileRoute, useParams } from '@tanstack/react-router'
+
+export const Route = createFileRoute('/params-ps/strict-false/$version')({
+  params: {
+    parse: (params) => ({
+      ...params,
+      version: parseInt(params.version),
+    }),
+    stringify: (params) => ({
+      ...params,
+      version: `${params.version}`,
+    }),
+  },
+  component: RouteComponent,
+})
+
+function RouteComponent() {
+  const { version } = useParams({ strict: false })
+
+  return <div data-testid="strict-false-child-version">{String(version)}</div>
+}
diff --git a/e2e/react-router/basic-file-based/src/routes/params-ps/strict-false/route.tsx b/e2e/react-router/basic-file-based/src/routes/params-ps/strict-false/route.tsx
new file mode 100644
index 0000000000..f9f96cb7da
--- /dev/null
+++ b/e2e/react-router/basic-file-based/src/routes/params-ps/strict-false/route.tsx
@@ -0,0 +1,44 @@
+import {
+  Link,
+  Outlet,
+  createFileRoute,
+  useParams,
+} from '@tanstack/react-router'
+
+export const Route = createFileRoute('/params-ps/strict-false')({
+  component: RouteComponent,
+})
+
+function RouteComponent() {
+  const { version } = useParams({ strict: false })
+  return (
+    <div>
+      <h3>ParamsStrictFalseParse</h3>
+      <div>
+        Type:{' '}
+        <span data-testid="strict-false-version-type">{typeof version}</span>
+      </div>
+      <div>
+        Value:{' '}
+        <span data-testid="strict-false-version-value">{String(version)}</span>
+      </div>
+      <Link
+        data-testid="strict-false-version-1"
+        from={Route.fullPath}
+        to="./$version"
+        params={{ version: 1 }}
+      >
+        Version 1
+      </Link>
+      <Link
+        data-testid="strict-false-version-2"
+        from={Route.fullPath}
+        to="./$version"
+        params={{ version: 2 }}
+      >
+        Version 2
+      </Link>
+      <Outlet />
+    </div>
+  )
+}
diff --git a/e2e/react-router/basic-file-based/tests/params.spec.ts b/e2e/react-router/basic-file-based/tests/params.spec.ts
index 6b43dba314..a867696ff8 100644
--- a/e2e/react-router/basic-file-based/tests/params.spec.ts
+++ b/e2e/react-router/basic-file-based/tests/params.spec.ts
@@ -492,3 +492,29 @@ test.describe('Unicode params', () => {
     })
   })
 })
+
+test.describe('useParams strict false uses parsed child params', () => {
+  test.beforeEach(async ({ page }) => {
+    await page.goto('/params-ps')
+  })
+
+  test('parent receives parsed values after child navigation', async ({
+    page,
+  }) => {
+    await page.getByTestId('strict-false-version-1').click()
+    await page.waitForURL('/params-ps/strict-false/1')
+
+    await expect(page.getByTestId('strict-false-version-type')).toHaveText(
+      'number',
+    )
+    await expect(page.getByTestId('strict-false-version-value')).toHaveText('1')
+
+    await page.getByTestId('strict-false-version-2').click()
+    await page.waitForURL('/params-ps/strict-false/2')
+
+    await expect(page.getByTestId('strict-false-version-type')).toHaveText(
+      'number',
+    )
+    await expect(page.getByTestId('strict-false-version-value')).toHaveText('2')
+  })
+})
diff --git a/e2e/react-start/basic-react-query/package.json b/e2e/react-start/basic-react-query/package.json
index d44674ecaa..2fce084cc9 100644
--- a/e2e/react-start/basic-react-query/package.json
+++ b/e2e/react-start/basic-react-query/package.json
@@ -33,7 +33,7 @@
     "@types/react": "^19.0.8",
     "@types/react-dom": "^19.0.3",
     "@vitejs/plugin-react": "^4.3.4",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite-tsconfig-paths": "^5.1.4"
diff --git a/e2e/react-start/basic-tsr-config/package.json b/e2e/react-start/basic-tsr-config/package.json
index 1b1a16d999..e175d6766c 100644
--- a/e2e/react-start/basic-tsr-config/package.json
+++ b/e2e/react-start/basic-tsr-config/package.json
@@ -22,7 +22,7 @@
     "@types/node": "^22.10.2",
     "@types/react": "^19.0.8",
     "@types/react-dom": "^19.0.3",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "typescript": "^5.7.2"
   }
 }
diff --git a/e2e/react-start/basic/package.json b/e2e/react-start/basic/package.json
index aef55c3531..883627bb4f 100644
--- a/e2e/react-start/basic/package.json
+++ b/e2e/react-start/basic/package.json
@@ -41,7 +41,7 @@
     "@types/react-dom": "^19.0.3",
     "@vitejs/plugin-react": "^4.3.4",
     "combinate": "^1.1.11",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite": "^7.3.1",
diff --git a/e2e/react-start/basic/src/routeTree.gen.ts b/e2e/react-start/basic/src/routeTree.gen.ts
index b5ecc4a50f..6efad91f8d 100644
--- a/e2e/react-start/basic/src/routeTree.gen.ts
+++ b/e2e/react-start/basic/src/routeTree.gen.ts
@@ -19,6 +19,7 @@ import { Route as LinksRouteImport } from './routes/links'
 import { Route as InlineScriptsRouteImport } from './routes/inline-scripts'
 import { Route as DeferredRouteImport } from './routes/deferred'
 import { Route as ClientOnlyRouteImport } from './routes/client-only'
+import { Route as AsyncScriptsRouteImport } from './routes/async-scripts'
 import { Route as LayoutRouteImport } from './routes/_layout'
 import { Route as SpecialCharsRouteRouteImport } from './routes/specialChars/route'
 import { Route as SearchParamsRouteRouteImport } from './routes/search-params/route'
@@ -118,6 +119,11 @@ const ClientOnlyRoute = ClientOnlyRouteImport.update({
   path: '/client-only',
   getParentRoute: () => rootRouteImport,
 } as any)
+const AsyncScriptsRoute = AsyncScriptsRouteImport.update({
+  id: '/async-scripts',
+  path: '/async-scripts',
+  getParentRoute: () => rootRouteImport,
+} as any)
 const LayoutRoute = LayoutRouteImport.update({
   id: '/_layout',
   getParentRoute: () => rootRouteImport,
@@ -374,6 +380,7 @@ export interface FileRoutesByFullPath {
   '/not-found': typeof NotFoundRouteRouteWithChildren
   '/search-params': typeof SearchParamsRouteRouteWithChildren
   '/specialChars': typeof SpecialCharsRouteRouteWithChildren
+  '/async-scripts': typeof AsyncScriptsRoute
   '/client-only': typeof ClientOnlyRoute
   '/deferred': typeof DeferredRoute
   '/inline-scripts': typeof InlineScriptsRoute
@@ -430,6 +437,7 @@ export interface FileRoutesByFullPath {
 export interface FileRoutesByTo {
   '/': typeof IndexRoute
   '/specialChars': typeof SpecialCharsRouteRouteWithChildren
+  '/async-scripts': typeof AsyncScriptsRoute
   '/client-only': typeof ClientOnlyRoute
   '/deferred': typeof DeferredRoute
   '/inline-scripts': typeof InlineScriptsRoute
@@ -485,6 +493,7 @@ export interface FileRoutesById {
   '/search-params': typeof SearchParamsRouteRouteWithChildren
   '/specialChars': typeof SpecialCharsRouteRouteWithChildren
   '/_layout': typeof LayoutRouteWithChildren
+  '/async-scripts': typeof AsyncScriptsRoute
   '/client-only': typeof ClientOnlyRoute
   '/deferred': typeof DeferredRoute
   '/inline-scripts': typeof InlineScriptsRoute
@@ -546,6 +555,7 @@ export interface FileRouteTypes {
     | '/not-found'
     | '/search-params'
     | '/specialChars'
+    | '/async-scripts'
     | '/client-only'
     | '/deferred'
     | '/inline-scripts'
@@ -602,6 +612,7 @@ export interface FileRouteTypes {
   to:
     | '/'
     | '/specialChars'
+    | '/async-scripts'
     | '/client-only'
     | '/deferred'
     | '/inline-scripts'
@@ -656,6 +667,7 @@ export interface FileRouteTypes {
     | '/search-params'
     | '/specialChars'
     | '/_layout'
+    | '/async-scripts'
     | '/client-only'
     | '/deferred'
     | '/inline-scripts'
@@ -717,6 +729,7 @@ export interface RootRouteChildren {
   SearchParamsRouteRoute: typeof SearchParamsRouteRouteWithChildren
   SpecialCharsRouteRoute: typeof SpecialCharsRouteRouteWithChildren
   LayoutRoute: typeof LayoutRouteWithChildren
+  AsyncScriptsRoute: typeof AsyncScriptsRoute
   ClientOnlyRoute: typeof ClientOnlyRoute
   DeferredRoute: typeof DeferredRoute
   InlineScriptsRoute: typeof InlineScriptsRoute
@@ -808,6 +821,13 @@ declare module '@tanstack/react-router' {
       preLoaderRoute: typeof ClientOnlyRouteImport
       parentRoute: typeof rootRouteImport
     }
+    '/async-scripts': {
+      id: '/async-scripts'
+      path: '/async-scripts'
+      fullPath: '/async-scripts'
+      preLoaderRoute: typeof AsyncScriptsRouteImport
+      parentRoute: typeof rootRouteImport
+    }
     '/_layout': {
       id: '/_layout'
       path: ''
@@ -1343,6 +1363,7 @@ const rootRouteChildren: RootRouteChildren = {
   SearchParamsRouteRoute: SearchParamsRouteRouteWithChildren,
   SpecialCharsRouteRoute: SpecialCharsRouteRouteWithChildren,
   LayoutRoute: LayoutRouteWithChildren,
+  AsyncScriptsRoute: AsyncScriptsRoute,
   ClientOnlyRoute: ClientOnlyRoute,
   DeferredRoute: DeferredRoute,
   InlineScriptsRoute: InlineScriptsRoute,
diff --git a/e2e/react-start/basic/src/routes/__root.tsx b/e2e/react-start/basic/src/routes/__root.tsx
index e1862b499c..581510f616 100644
--- a/e2e/react-start/basic/src/routes/__root.tsx
+++ b/e2e/react-start/basic/src/routes/__root.tsx
@@ -141,6 +141,14 @@ function RootDocument({ children }: { children: React.ReactNode }) {
           >
             Scripts
           </Link>{' '}
+          <Link
+            to="/async-scripts"
+            activeProps={{
+              className: 'font-bold',
+            }}
+          >
+            Async Scripts
+          </Link>{' '}
           <Link
             to="/inline-scripts"
             activeProps={{
diff --git a/e2e/react-start/basic/src/routes/async-scripts.tsx b/e2e/react-start/basic/src/routes/async-scripts.tsx
new file mode 100644
index 0000000000..cb2cca9bab
--- /dev/null
+++ b/e2e/react-start/basic/src/routes/async-scripts.tsx
@@ -0,0 +1,26 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+export const Route = createFileRoute('/async-scripts')({
+  head: () => ({
+    scripts: [
+      {
+        src: 'script.js',
+        async: true,
+      },
+      {
+        src: 'script2.js',
+        defer: true,
+      },
+    ],
+  }),
+  component: AsyncScriptsComponent,
+})
+
+function AsyncScriptsComponent() {
+  return (
+    <div className="p-2">
+      <h3 data-testid="async-scripts-test-heading">Async Scripts Test</h3>
+      <p>This page tests scripts with async and defer attributes.</p>
+    </div>
+  )
+}
diff --git a/e2e/react-start/basic/tests/open-redirect-prevention.spec.ts b/e2e/react-start/basic/tests/open-redirect-prevention.spec.ts
index 4267de8b64..e497109889 100644
--- a/e2e/react-start/basic/tests/open-redirect-prevention.spec.ts
+++ b/e2e/react-start/basic/tests/open-redirect-prevention.spec.ts
@@ -1,5 +1,6 @@
 import { expect } from '@playwright/test'
 import { test } from '@tanstack/router-e2e-utils'
+import { isSpaMode } from './utils/isSpaMode'
 
 test.use({
   whitelistErrors: [
@@ -80,7 +81,7 @@ test.describe('Open redirect prevention', () => {
       // the result could be //evil.com/ which is a protocol-relative URL
       // Our fix collapses these to /evil.com/ to prevent external redirects
       // This is already tested above, but we verify the collapsed path works
-      await page.goto('/%0d/test-path/')
+      const res = await page.goto('/%0d/test-path/')
       await page.waitForLoadState('networkidle')
 
       // Should stay on the same origin
@@ -89,6 +90,9 @@ test.describe('Open redirect prevention', () => {
       expect(url.origin).toBe(new URL(baseURL!).origin)
       // Path should be collapsed to /test-path (not //test-path/)
       expect(url.pathname).toMatch(/^\/test-path\/?$/)
+      if (!isSpaMode) {
+        expect(res?.request().redirectedFrom()?.url()).not.toBe(undefined)
+      }
     })
   })
 
diff --git a/e2e/react-start/basic/tests/script-duplication.spec.ts b/e2e/react-start/basic/tests/script-duplication.spec.ts
index 2ed98a3a73..46e3bff00b 100644
--- a/e2e/react-start/basic/tests/script-duplication.spec.ts
+++ b/e2e/react-start/basic/tests/script-duplication.spec.ts
@@ -1,5 +1,50 @@
 import { expect, test } from '@playwright/test'
 
+test.describe('Async Script Hydration', () => {
+  test('should not show hydration warning for async scripts', async ({
+    page,
+  }) => {
+    const warnings: Array<string> = []
+    page.on('console', (msg) => {
+      if (
+        msg.type() === 'warning' ||
+        (msg.type() === 'error' &&
+          msg.text().toLowerCase().includes('hydration'))
+      ) {
+        warnings.push(msg.text())
+      }
+    })
+
+    await page.goto('/async-scripts')
+    await expect(
+      page.getByTestId('async-scripts-test-heading'),
+    ).toBeInViewport()
+
+    await page.waitForFunction(() => (window as any).SCRIPT_1 === true)
+
+    // Filter for hydration-related warnings
+    const hydrationWarnings = warnings.filter(
+      (w) =>
+        w.toLowerCase().includes('hydration') ||
+        w.toLowerCase().includes('mismatch'),
+    )
+
+    expect(hydrationWarnings).toHaveLength(0)
+  })
+
+  test('should load async and defer scripts correctly', async ({ page }) => {
+    await page.goto('/async-scripts')
+    await expect(
+      page.getByTestId('async-scripts-test-heading'),
+    ).toBeInViewport()
+
+    // script.js (async) sets window.SCRIPT_1 = true
+    // script2.js (defer) sets window.SCRIPT_2 = true
+    expect(await page.evaluate('window.SCRIPT_1')).toBe(true)
+    expect(await page.evaluate('window.SCRIPT_2')).toBe(true)
+  })
+})
+
 test.describe('Script Duplication Prevention', () => {
   test('should not create duplicate scripts on SSR route', async ({ page }) => {
     await page.goto('/scripts')
diff --git a/e2e/react-start/csp/package.json b/e2e/react-start/csp/package.json
index da553e7c99..66117ba3e6 100644
--- a/e2e/react-start/csp/package.json
+++ b/e2e/react-start/csp/package.json
@@ -23,7 +23,7 @@
     "@types/node": "^22.10.2",
     "@types/react": "^19.0.8",
     "@types/react-dom": "^19.0.3",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "typescript": "^5.7.2"
   }
 }
diff --git a/e2e/react-start/css-modules/package.json b/e2e/react-start/css-modules/package.json
index 4955ec0804..73b874f8f7 100644
--- a/e2e/react-start/css-modules/package.json
+++ b/e2e/react-start/css-modules/package.json
@@ -41,7 +41,7 @@
     "@vitejs/plugin-react": "^4.3.4",
     "nitro": "3.0.1-alpha.2",
     "sass": "^1.97.2",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "typescript": "^5.7.2",
     "vite": "^7.3.1",
     "vite-tsconfig-paths": "^5.1.4",
diff --git a/e2e/react-start/custom-basepath/package.json b/e2e/react-start/custom-basepath/package.json
index ee805c4a6b..d2df8be146 100644
--- a/e2e/react-start/custom-basepath/package.json
+++ b/e2e/react-start/custom-basepath/package.json
@@ -29,7 +29,7 @@
     "@types/react-dom": "^19.0.3",
     "@vitejs/plugin-react": "^4.3.4",
     "cross-env": "^10.0.0",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "tsx": "^4.20.3",
     "typescript": "^5.7.2",
diff --git a/e2e/react-start/scroll-restoration/package.json b/e2e/react-start/scroll-restoration/package.json
index 9fc003689d..5d8191e15e 100644
--- a/e2e/react-start/scroll-restoration/package.json
+++ b/e2e/react-start/scroll-restoration/package.json
@@ -32,7 +32,7 @@
     "@types/react-dom": "^19.0.3",
     "@vitejs/plugin-react": "^4.3.4",
     "combinate": "^1.1.11",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite-tsconfig-paths": "^5.1.4"
diff --git a/e2e/react-start/selective-ssr/package.json b/e2e/react-start/selective-ssr/package.json
index 9640fe72a7..e8479cf91f 100644
--- a/e2e/react-start/selective-ssr/package.json
+++ b/e2e/react-start/selective-ssr/package.json
@@ -28,7 +28,7 @@
     "@types/react": "^19.0.8",
     "@types/react-dom": "^19.0.3",
     "@vitejs/plugin-react": "^4.3.4",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2"
   }
diff --git a/e2e/react-start/serialization-adapters/package.json b/e2e/react-start/serialization-adapters/package.json
index dd05aa4012..9623c42fff 100644
--- a/e2e/react-start/serialization-adapters/package.json
+++ b/e2e/react-start/serialization-adapters/package.json
@@ -28,7 +28,7 @@
     "@types/react": "^19.0.8",
     "@types/react-dom": "^19.0.3",
     "@vitejs/plugin-react": "^4.3.4",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2"
   }
diff --git a/e2e/react-start/server-functions-global-middleware/package.json b/e2e/react-start/server-functions-global-middleware/package.json
index da5e243044..e2979f9d53 100644
--- a/e2e/react-start/server-functions-global-middleware/package.json
+++ b/e2e/react-start/server-functions-global-middleware/package.json
@@ -26,7 +26,7 @@
     "@types/react": "^19.0.8",
     "@types/react-dom": "^19.0.3",
     "@vitejs/plugin-react": "^4.3.4",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite-tsconfig-paths": "^5.1.4"
diff --git a/e2e/react-start/server-functions-global-middleware/src/routeTree.gen.ts b/e2e/react-start/server-functions-global-middleware/src/routeTree.gen.ts
index bcc17d676e..c75f87fec0 100644
--- a/e2e/react-start/server-functions-global-middleware/src/routeTree.gen.ts
+++ b/e2e/react-start/server-functions-global-middleware/src/routeTree.gen.ts
@@ -10,6 +10,7 @@
 
 import { Route as rootRouteImport } from './routes/__root'
 import { Route as SimpleRouteImport } from './routes/simple'
+import { Route as PathnameMiddlewareRouteImport } from './routes/pathname-middleware'
 import { Route as MultipleServerFunctionsRouteImport } from './routes/multiple-server-functions'
 import { Route as IndexRouteImport } from './routes/index'
 
@@ -18,6 +19,11 @@ const SimpleRoute = SimpleRouteImport.update({
   path: '/simple',
   getParentRoute: () => rootRouteImport,
 } as any)
+const PathnameMiddlewareRoute = PathnameMiddlewareRouteImport.update({
+  id: '/pathname-middleware',
+  path: '/pathname-middleware',
+  getParentRoute: () => rootRouteImport,
+} as any)
 const MultipleServerFunctionsRoute = MultipleServerFunctionsRouteImport.update({
   id: '/multiple-server-functions',
   path: '/multiple-server-functions',
@@ -32,30 +38,34 @@ const IndexRoute = IndexRouteImport.update({
 export interface FileRoutesByFullPath {
   '/': typeof IndexRoute
   '/multiple-server-functions': typeof MultipleServerFunctionsRoute
+  '/pathname-middleware': typeof PathnameMiddlewareRoute
   '/simple': typeof SimpleRoute
 }
 export interface FileRoutesByTo {
   '/': typeof IndexRoute
   '/multiple-server-functions': typeof MultipleServerFunctionsRoute
+  '/pathname-middleware': typeof PathnameMiddlewareRoute
   '/simple': typeof SimpleRoute
 }
 export interface FileRoutesById {
   __root__: typeof rootRouteImport
   '/': typeof IndexRoute
   '/multiple-server-functions': typeof MultipleServerFunctionsRoute
+  '/pathname-middleware': typeof PathnameMiddlewareRoute
   '/simple': typeof SimpleRoute
 }
 export interface FileRouteTypes {
   fileRoutesByFullPath: FileRoutesByFullPath
-  fullPaths: '/' | '/multiple-server-functions' | '/simple'
+  fullPaths: '/' | '/multiple-server-functions' | '/pathname-middleware' | '/simple'
   fileRoutesByTo: FileRoutesByTo
-  to: '/' | '/multiple-server-functions' | '/simple'
-  id: '__root__' | '/' | '/multiple-server-functions' | '/simple'
+  to: '/' | '/multiple-server-functions' | '/pathname-middleware' | '/simple'
+  id: '__root__' | '/' | '/multiple-server-functions' | '/pathname-middleware' | '/simple'
   fileRoutesById: FileRoutesById
 }
 export interface RootRouteChildren {
   IndexRoute: typeof IndexRoute
   MultipleServerFunctionsRoute: typeof MultipleServerFunctionsRoute
+  PathnameMiddlewareRoute: typeof PathnameMiddlewareRoute
   SimpleRoute: typeof SimpleRoute
 }
 
@@ -68,6 +78,13 @@ declare module '@tanstack/react-router' {
       preLoaderRoute: typeof SimpleRouteImport
       parentRoute: typeof rootRouteImport
     }
+    '/pathname-middleware': {
+      id: '/pathname-middleware'
+      path: '/pathname-middleware'
+      fullPath: '/pathname-middleware'
+      preLoaderRoute: typeof PathnameMiddlewareRouteImport
+      parentRoute: typeof rootRouteImport
+    }
     '/multiple-server-functions': {
       id: '/multiple-server-functions'
       path: '/multiple-server-functions'
@@ -88,6 +105,7 @@ declare module '@tanstack/react-router' {
 const rootRouteChildren: RootRouteChildren = {
   IndexRoute: IndexRoute,
   MultipleServerFunctionsRoute: MultipleServerFunctionsRoute,
+  PathnameMiddlewareRoute: PathnameMiddlewareRoute,
   SimpleRoute: SimpleRoute,
 }
 export const routeTree = rootRouteImport
diff --git a/e2e/react-start/server-functions-global-middleware/src/routes/index.tsx b/e2e/react-start/server-functions-global-middleware/src/routes/index.tsx
index 509affdf04..86c587071a 100644
--- a/e2e/react-start/server-functions-global-middleware/src/routes/index.tsx
+++ b/e2e/react-start/server-functions-global-middleware/src/routes/index.tsx
@@ -26,6 +26,12 @@ function Home() {
             global middleware
           </Link>
         </li>
+        <li>
+          <Link to="/pathname-middleware" data-testid="link-pathname">
+            Pathname test - verify pathname is passed to global request
+            middleware
+          </Link>
+        </li>
       </ul>
     </div>
   )
diff --git a/e2e/react-start/server-functions-global-middleware/src/routes/pathname-middleware.tsx b/e2e/react-start/server-functions-global-middleware/src/routes/pathname-middleware.tsx
new file mode 100644
index 0000000000..d363065888
--- /dev/null
+++ b/e2e/react-start/server-functions-global-middleware/src/routes/pathname-middleware.tsx
@@ -0,0 +1,41 @@
+import { createFileRoute } from '@tanstack/react-router'
+import { createServerFn } from '@tanstack/react-start'
+
+// Regression test for issue #6647:
+// Global request middleware in createStartHandler was not receiving `pathname`.
+// The `pathnameMiddleware` (registered as requestMiddleware in start.ts)
+// captures `pathname` into context as `requestMiddlewarePathname`.
+// This route verifies that value is defined and matches the actual route path.
+
+const getPathnameFromMiddleware = createServerFn().handler(
+  async ({ context }) => {
+    return {
+      requestMiddlewarePathname: context.requestMiddlewarePathname,
+    }
+  },
+)
+
+export const Route = createFileRoute('/pathname-middleware')({
+  loader: async () => {
+    return await getPathnameFromMiddleware()
+  },
+  component: PathnameMiddlewareComponent,
+})
+
+function PathnameMiddlewareComponent() {
+  const data = Route.useLoaderData()
+  const pathname = data.requestMiddlewarePathname
+
+  return (
+    <div className="p-8">
+      <h1 className="font-bold text-lg mb-4">
+        Pathname in Global Request Middleware (Issue #6647)
+      </h1>
+      <div>
+        <span data-testid="request-middleware-pathname">
+          {String(pathname)}
+        </span>
+      </div>
+    </div>
+  )
+}
diff --git a/e2e/react-start/server-functions-global-middleware/src/start.ts b/e2e/react-start/server-functions-global-middleware/src/start.ts
index 474968298d..7d22827605 100644
--- a/e2e/react-start/server-functions-global-middleware/src/start.ts
+++ b/e2e/react-start/server-functions-global-middleware/src/start.ts
@@ -49,6 +49,18 @@ export const loggingMiddleware = createMiddleware().server(async ({ next }) => {
   })
 })
 
+// Regression test for #6647: verify that pathname is correctly passed to
+// global request middleware by createStartHandler
+export const pathnameMiddleware = createMiddleware().server(
+  async ({ next, pathname }) => {
+    return next({
+      context: {
+        requestMiddlewarePathname: pathname,
+      },
+    })
+  },
+)
+
 // Global function middleware that should be deduped across server functions
 export const globalFunctionMiddleware = createMiddleware({
   type: 'function',
@@ -79,5 +91,5 @@ export const startInstance = createStart(() => ({
   functionMiddleware: [globalFunctionMiddleware, globalFunctionMiddleware2],
   // Request middleware - includes loggingMiddleware (issue #5239 scenario)
   // AND the same loggingMiddleware is also attached to server functions
-  requestMiddleware: [loggingMiddleware],
+  requestMiddleware: [loggingMiddleware, pathnameMiddleware],
 }))
diff --git a/e2e/react-start/server-functions-global-middleware/tests/global-middleware.spec.ts b/e2e/react-start/server-functions-global-middleware/tests/global-middleware.spec.ts
index dfc4ae315a..211d7f59c7 100644
--- a/e2e/react-start/server-functions-global-middleware/tests/global-middleware.spec.ts
+++ b/e2e/react-start/server-functions-global-middleware/tests/global-middleware.spec.ts
@@ -129,3 +129,27 @@ test.describe('Global middleware deduplication (issue #5239)', () => {
     })
   })
 })
+
+test.describe('Request middleware pathname (issue #6647)', () => {
+  test('pathname should be the page path on SSR', async ({ page }) => {
+    await page.goto('/pathname-middleware')
+    await page.waitForLoadState('networkidle')
+    await expect(page.getByTestId('request-middleware-pathname')).toHaveText(
+      '/pathname-middleware',
+    )
+  })
+
+  test('pathname should be the server function path on client-side navigation', async ({
+    page,
+  }) => {
+    await page.goto('/')
+    await page.waitForLoadState('networkidle')
+    await page.getByTestId('link-pathname').click()
+    await page.waitForLoadState('networkidle')
+    const pathnameText = await page
+      .getByTestId('request-middleware-pathname')
+      .textContent()
+    expect(pathnameText).toBeTruthy()
+    expect(pathnameText!.startsWith('/_serverFn/')).toBe(true)
+  })
+})
diff --git a/e2e/react-start/server-functions/package.json b/e2e/react-start/server-functions/package.json
index f4d6ca6d70..fed5440f06 100644
--- a/e2e/react-start/server-functions/package.json
+++ b/e2e/react-start/server-functions/package.json
@@ -35,7 +35,7 @@
     "@types/react-dom": "^19.0.3",
     "@vitejs/plugin-react": "^4.3.4",
     "combinate": "^1.1.11",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite-tsconfig-paths": "^5.1.4"
diff --git a/e2e/react-start/server-functions/src/routes/abort-signal/$method.tsx b/e2e/react-start/server-functions/src/routes/abort-signal/$method.tsx
index 7f7397a5ce..f8aef0cff0 100644
--- a/e2e/react-start/server-functions/src/routes/abort-signal/$method.tsx
+++ b/e2e/react-start/server-functions/src/routes/abort-signal/$method.tsx
@@ -1,5 +1,6 @@
 import { createFileRoute } from '@tanstack/react-router'
-import { createServerFn } from '@tanstack/react-start'
+import { createServerFn, createServerOnlyFn } from '@tanstack/react-start'
+import { getRequest } from '@tanstack/react-start/server'
 import React from 'react'
 import z from 'zod'
 
@@ -10,7 +11,9 @@ export const Route = createFileRoute('/abort-signal/$method')({
   component: RouteComponent,
 })
 
-function serverFnImpl(signal: AbortSignal) {
+const serverFnImpl = createServerOnlyFn(async () => {
+  const request = getRequest()
+  const signal = request.signal
   console.log('server function started', { signal })
   return new Promise<string>((resolve, reject) => {
     if (signal.aborted) {
@@ -27,13 +30,12 @@ function serverFnImpl(signal: AbortSignal) {
     }
     signal.addEventListener('abort', onAbort, { once: true })
   })
-}
-const abortableServerFnGET = createServerFn().handler(async ({ signal }) =>
-  serverFnImpl(signal),
-)
+})
+
+const abortableServerFnGET = createServerFn().handler(serverFnImpl)
 
 const abortableServerFnPOST = createServerFn({ method: 'POST' }).handler(
-  async ({ signal }) => serverFnImpl(signal),
+  serverFnImpl,
 )
 
 function RouteComponent() {
diff --git a/e2e/react-start/server-routes-global-middleware/package.json b/e2e/react-start/server-routes-global-middleware/package.json
index 7741e49fdc..a16121d3de 100644
--- a/e2e/react-start/server-routes-global-middleware/package.json
+++ b/e2e/react-start/server-routes-global-middleware/package.json
@@ -26,7 +26,7 @@
     "@types/react": "^19.0.8",
     "@types/react-dom": "^19.0.3",
     "@vitejs/plugin-react": "^4.3.4",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite-tsconfig-paths": "^5.1.4"
diff --git a/e2e/react-start/server-routes/package.json b/e2e/react-start/server-routes/package.json
index 7d1eccc8c9..90266607d6 100644
--- a/e2e/react-start/server-routes/package.json
+++ b/e2e/react-start/server-routes/package.json
@@ -35,7 +35,7 @@
     "@types/react-dom": "^19.0.3",
     "@vitejs/plugin-react": "^4.3.4",
     "combinate": "^1.1.11",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite-tsconfig-paths": "^5.1.4"
diff --git a/e2e/react-start/streaming-ssr/package.json b/e2e/react-start/streaming-ssr/package.json
index b50a7d4d6d..7b557842fb 100644
--- a/e2e/react-start/streaming-ssr/package.json
+++ b/e2e/react-start/streaming-ssr/package.json
@@ -25,7 +25,7 @@
     "@types/node": "^22.10.2",
     "@types/react": "^19.0.8",
     "@types/react-dom": "^19.0.3",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "typescript": "^5.7.2"
   }
 }
diff --git a/e2e/react-start/transform-asset-urls/.gitignore b/e2e/react-start/transform-asset-urls/.gitignore
new file mode 100644
index 0000000000..afc3a33f59
--- /dev/null
+++ b/e2e/react-start/transform-asset-urls/.gitignore
@@ -0,0 +1,18 @@
+node_modules
+package-lock.json
+yarn.lock
+
+.DS_Store
+.cache
+.env
+.vercel
+.output
+
+/build/
+/api/
+/server/build
+/public/build
+/test-results/
+/playwright-report/
+/blob-report/
+/playwright/.cache/
diff --git a/e2e/react-start/transform-asset-urls/.prettierignore b/e2e/react-start/transform-asset-urls/.prettierignore
new file mode 100644
index 0000000000..40a96e8819
--- /dev/null
+++ b/e2e/react-start/transform-asset-urls/.prettierignore
@@ -0,0 +1,4 @@
+**/build
+**/public
+pnpm-lock.yaml
+routeTree.gen.ts
diff --git a/e2e/react-start/transform-asset-urls/package.json b/e2e/react-start/transform-asset-urls/package.json
new file mode 100644
index 0000000000..a3af791f7a
--- /dev/null
+++ b/e2e/react-start/transform-asset-urls/package.json
@@ -0,0 +1,54 @@
+{
+  "name": "tanstack-react-start-e2e-transform-asset-urls",
+  "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",
+    "manual:cdn": "CDN_PORT=3002 node tests/cdn-server.mjs",
+    "manual:app": "pnpm build && PORT=3000 CDN_ORIGIN=http://localhost:3002 pnpm start",
+    "manual:both": "sh -c \"CDN_PORT=3002 node tests/cdn-server.mjs & pnpm build && PORT=3000 CDN_ORIGIN=http://localhost:3002 pnpm start\"",
+    "manual:both:string": "TRANSFORM_ASSET_URLS_MODE=string pnpm manual:both",
+    "manual:both:function": "TRANSFORM_ASSET_URLS_MODE=function pnpm manual:both",
+    "manual:both:options": "TRANSFORM_ASSET_URLS_MODE=options TRANSFORM_ASSET_URLS_OPTIONS_KIND=createTransform pnpm manual:both",
+    "manual:both:options:transform": "TRANSFORM_ASSET_URLS_MODE=options TRANSFORM_ASSET_URLS_OPTIONS_KIND=transform pnpm manual:both",
+    "manual:both:options:createTransform": "TRANSFORM_ASSET_URLS_MODE=options TRANSFORM_ASSET_URLS_OPTIONS_KIND=createTransform pnpm manual:both",
+    "test:e2e:string": "rm -rf dist; rm -rf port*.txt; TRANSFORM_ASSET_URLS_MODE=string playwright test --project=chromium",
+    "test:e2e:function": "rm -rf dist; rm -rf port*.txt; TRANSFORM_ASSET_URLS_MODE=function playwright test --project=chromium",
+    "test:e2e:options": "rm -rf dist; rm -rf port*.txt; TRANSFORM_ASSET_URLS_MODE=options TRANSFORM_ASSET_URLS_OPTIONS_KIND=transform playwright test --project=chromium",
+    "test:e2e:options:transform": "rm -rf dist; rm -rf port*.txt; TRANSFORM_ASSET_URLS_MODE=options TRANSFORM_ASSET_URLS_OPTIONS_KIND=transform playwright test --project=chromium",
+    "test:e2e:options:createTransform": "rm -rf dist; rm -rf port*.txt; TRANSFORM_ASSET_URLS_MODE=options TRANSFORM_ASSET_URLS_OPTIONS_KIND=createTransform playwright test --project=chromium",
+    "test:e2e:options:transform:cache-true:warmup-true": "rm -rf dist; rm -rf port*.txt; TRANSFORM_ASSET_URLS_MODE=options TRANSFORM_ASSET_URLS_OPTIONS_KIND=transform TRANSFORM_ASSET_URLS_OPTIONS_CACHE=true TRANSFORM_ASSET_URLS_OPTIONS_WARMUP=true playwright test --project=chromium",
+    "test:e2e:options:transform:cache-true:warmup-false": "rm -rf dist; rm -rf port*.txt; TRANSFORM_ASSET_URLS_MODE=options TRANSFORM_ASSET_URLS_OPTIONS_KIND=transform TRANSFORM_ASSET_URLS_OPTIONS_CACHE=true TRANSFORM_ASSET_URLS_OPTIONS_WARMUP=false playwright test --project=chromium",
+    "test:e2e:options:transform:cache-false:warmup-true": "rm -rf dist; rm -rf port*.txt; TRANSFORM_ASSET_URLS_MODE=options TRANSFORM_ASSET_URLS_OPTIONS_KIND=transform TRANSFORM_ASSET_URLS_OPTIONS_CACHE=false TRANSFORM_ASSET_URLS_OPTIONS_WARMUP=true playwright test --project=chromium",
+    "test:e2e:options:transform:cache-false:warmup-false": "rm -rf dist; rm -rf port*.txt; TRANSFORM_ASSET_URLS_MODE=options TRANSFORM_ASSET_URLS_OPTIONS_KIND=transform TRANSFORM_ASSET_URLS_OPTIONS_CACHE=false TRANSFORM_ASSET_URLS_OPTIONS_WARMUP=false playwright test --project=chromium",
+    "test:e2e:options:createTransform:cache-true:warmup-true": "rm -rf dist; rm -rf port*.txt; TRANSFORM_ASSET_URLS_MODE=options TRANSFORM_ASSET_URLS_OPTIONS_KIND=createTransform TRANSFORM_ASSET_URLS_OPTIONS_CACHE=true TRANSFORM_ASSET_URLS_OPTIONS_WARMUP=true playwright test --project=chromium",
+    "test:e2e:options:createTransform:cache-true:warmup-false": "rm -rf dist; rm -rf port*.txt; TRANSFORM_ASSET_URLS_MODE=options TRANSFORM_ASSET_URLS_OPTIONS_KIND=createTransform TRANSFORM_ASSET_URLS_OPTIONS_CACHE=true TRANSFORM_ASSET_URLS_OPTIONS_WARMUP=false playwright test --project=chromium",
+    "test:e2e:options:createTransform:cache-false:warmup-true": "rm -rf dist; rm -rf port*.txt; TRANSFORM_ASSET_URLS_MODE=options TRANSFORM_ASSET_URLS_OPTIONS_KIND=createTransform TRANSFORM_ASSET_URLS_OPTIONS_CACHE=false TRANSFORM_ASSET_URLS_OPTIONS_WARMUP=true playwright test --project=chromium",
+    "test:e2e:options:createTransform:cache-false:warmup-false": "rm -rf dist; rm -rf port*.txt; TRANSFORM_ASSET_URLS_MODE=options TRANSFORM_ASSET_URLS_OPTIONS_KIND=createTransform TRANSFORM_ASSET_URLS_OPTIONS_CACHE=false TRANSFORM_ASSET_URLS_OPTIONS_WARMUP=false playwright test --project=chromium",
+    "test:e2e:options:matrix": "pnpm test:e2e:options:transform:cache-true:warmup-true && pnpm test:e2e:options:transform:cache-true:warmup-false && pnpm test:e2e:options:transform:cache-false:warmup-true && pnpm test:e2e:options:transform:cache-false:warmup-false && pnpm test:e2e:options:createTransform:cache-true:warmup-true && pnpm test:e2e:options:createTransform:cache-true:warmup-false && pnpm test:e2e:options:createTransform:cache-false:warmup-true && pnpm test:e2e:options:createTransform:cache-false:warmup-false",
+    "test:e2e": "pnpm test:e2e:string && pnpm test:e2e:function && pnpm test:e2e:options:matrix"
+  },
+  "dependencies": {
+    "@tanstack/react-router": "workspace:^",
+    "@tanstack/react-start": "workspace:^",
+    "express": "^5.1.0",
+    "react": "^19.0.0",
+    "react-dom": "^19.0.0"
+  },
+  "devDependencies": {
+    "@playwright/test": "^1.50.1",
+    "@tanstack/router-e2e-utils": "workspace:^",
+    "@types/node": "^22.10.2",
+    "@types/react": "^19.0.8",
+    "@types/react-dom": "^19.0.3",
+    "@vitejs/plugin-react": "^4.3.4",
+    "srvx": "^0.11.2",
+    "typescript": "^5.7.2",
+    "vite": "^7.3.1",
+    "vite-tsconfig-paths": "^5.1.4"
+  }
+}
diff --git a/e2e/react-start/transform-asset-urls/playwright.config.ts b/e2e/react-start/transform-asset-urls/playwright.config.ts
new file mode 100644
index 0000000000..53cc1b38df
--- /dev/null
+++ b/e2e/react-start/transform-asset-urls/playwright.config.ts
@@ -0,0 +1,63 @@
+import { defineConfig, devices } from '@playwright/test'
+import { getTestServerPort } from '@tanstack/router-e2e-utils'
+import packageJson from './package.json' with { type: 'json' }
+
+const APP_PORT = await getTestServerPort(packageJson.name)
+const CDN_PORT = await getTestServerPort(`${packageJson.name}_cdn`)
+
+const baseURL = `http://localhost:${APP_PORT}`
+const cdnOrigin = `http://localhost:${CDN_PORT}`
+const transformMode = process.env.TRANSFORM_ASSET_URLS_MODE || 'string'
+const optionsKind =
+  process.env.TRANSFORM_ASSET_URLS_OPTIONS_KIND || 'createTransform'
+const optionsCache = process.env.TRANSFORM_ASSET_URLS_OPTIONS_CACHE || 'true'
+const optionsWarmup = process.env.TRANSFORM_ASSET_URLS_OPTIONS_WARMUP || 'true'
+
+export default defineConfig({
+  testDir: './tests',
+  workers: 1,
+  reporter: [['line']],
+
+  use: {
+    baseURL,
+  },
+
+  webServer: [
+    {
+      // CDN server — serves built client assets on a separate port with CORS
+      command: `node tests/cdn-server.mjs`,
+      url: `http://localhost:${CDN_PORT}/health`,
+      reuseExistingServer: !process.env.CI,
+      stdout: 'pipe',
+      env: {
+        CDN_PORT: String(CDN_PORT),
+      },
+    },
+    {
+      // App server — builds the project then starts the srvx server
+      // with CDN_ORIGIN so that transformAssetUrls rewrites manifest URLs
+      command: `pnpm build && pnpm start`,
+      url: baseURL,
+      reuseExistingServer: !process.env.CI,
+      stdout: 'pipe',
+      env: {
+        PORT: String(APP_PORT),
+        CDN_ORIGIN: cdnOrigin,
+        TRANSFORM_ASSET_URLS_MODE: transformMode,
+        TRANSFORM_ASSET_URLS_OPTIONS_KIND: optionsKind,
+        TRANSFORM_ASSET_URLS_OPTIONS_CACHE: optionsCache,
+        TRANSFORM_ASSET_URLS_OPTIONS_WARMUP: optionsWarmup,
+      },
+      timeout: 120_000,
+    },
+  ],
+
+  projects: [
+    {
+      name: 'chromium',
+      use: {
+        ...devices['Desktop Chrome'],
+      },
+    },
+  ],
+})
diff --git a/e2e/react-start/transform-asset-urls/src/routeTree.gen.ts b/e2e/react-start/transform-asset-urls/src/routeTree.gen.ts
new file mode 100644
index 0000000000..421daf2790
--- /dev/null
+++ b/e2e/react-start/transform-asset-urls/src/routeTree.gen.ts
@@ -0,0 +1,86 @@
+/* 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 AboutRouteImport } from './routes/about'
+import { Route as IndexRouteImport } from './routes/index'
+
+const AboutRoute = AboutRouteImport.update({
+  id: '/about',
+  path: '/about',
+  getParentRoute: () => rootRouteImport,
+} as any)
+const IndexRoute = IndexRouteImport.update({
+  id: '/',
+  path: '/',
+  getParentRoute: () => rootRouteImport,
+} as any)
+
+export interface FileRoutesByFullPath {
+  '/': typeof IndexRoute
+  '/about': typeof AboutRoute
+}
+export interface FileRoutesByTo {
+  '/': typeof IndexRoute
+  '/about': typeof AboutRoute
+}
+export interface FileRoutesById {
+  __root__: typeof rootRouteImport
+  '/': typeof IndexRoute
+  '/about': typeof AboutRoute
+}
+export interface FileRouteTypes {
+  fileRoutesByFullPath: FileRoutesByFullPath
+  fullPaths: '/' | '/about'
+  fileRoutesByTo: FileRoutesByTo
+  to: '/' | '/about'
+  id: '__root__' | '/' | '/about'
+  fileRoutesById: FileRoutesById
+}
+export interface RootRouteChildren {
+  IndexRoute: typeof IndexRoute
+  AboutRoute: typeof AboutRoute
+}
+
+declare module '@tanstack/react-router' {
+  interface FileRoutesByPath {
+    '/about': {
+      id: '/about'
+      path: '/about'
+      fullPath: '/about'
+      preLoaderRoute: typeof AboutRouteImport
+      parentRoute: typeof rootRouteImport
+    }
+    '/': {
+      id: '/'
+      path: '/'
+      fullPath: '/'
+      preLoaderRoute: typeof IndexRouteImport
+      parentRoute: typeof rootRouteImport
+    }
+  }
+}
+
+const rootRouteChildren: RootRouteChildren = {
+  IndexRoute: IndexRoute,
+  AboutRoute: AboutRoute,
+}
+export const routeTree = rootRouteImport
+  ._addFileChildren(rootRouteChildren)
+  ._addFileTypes<FileRouteTypes>()
+
+import type { getRouter } from './router.tsx'
+import type { createStart } from '@tanstack/react-start'
+declare module '@tanstack/react-start' {
+  interface Register {
+    ssr: true
+    router: Awaited<ReturnType<typeof getRouter>>
+  }
+}
diff --git a/e2e/react-start/transform-asset-urls/src/router.tsx b/e2e/react-start/transform-asset-urls/src/router.tsx
new file mode 100644
index 0000000000..16fd65460d
--- /dev/null
+++ b/e2e/react-start/transform-asset-urls/src/router.tsx
@@ -0,0 +1,12 @@
+import { createRouter } from '@tanstack/react-router'
+import { routeTree } from './routeTree.gen'
+
+export function getRouter() {
+  const router = createRouter({
+    routeTree,
+    scrollRestoration: true,
+    defaultPreload: 'intent',
+  })
+
+  return router
+}
diff --git a/e2e/react-start/transform-asset-urls/src/routes/__root.tsx b/e2e/react-start/transform-asset-urls/src/routes/__root.tsx
new file mode 100644
index 0000000000..4d1f1321a1
--- /dev/null
+++ b/e2e/react-start/transform-asset-urls/src/routes/__root.tsx
@@ -0,0 +1,40 @@
+/// <reference types="vite/client" />
+import {
+  HeadContent,
+  Outlet,
+  Scripts,
+  createRootRoute,
+} from '@tanstack/react-router'
+
+import '~/styles/app.css'
+
+export const Route = createRootRoute({
+  head: () => ({
+    meta: [
+      {
+        charSet: 'utf-8',
+      },
+      {
+        name: 'viewport',
+        content: 'width=device-width, initial-scale=1',
+      },
+    ],
+  }),
+  component: RootComponent,
+})
+
+function RootComponent() {
+  return (
+    <html>
+      <head>
+        <HeadContent />
+      </head>
+      <body>
+        <div className="app-styled">
+          <Outlet />
+        </div>
+        <Scripts />
+      </body>
+    </html>
+  )
+}
diff --git a/e2e/react-start/transform-asset-urls/src/routes/about.module.css b/e2e/react-start/transform-asset-urls/src/routes/about.module.css
new file mode 100644
index 0000000000..2afc6c104e
--- /dev/null
+++ b/e2e/react-start/transform-asset-urls/src/routes/about.module.css
@@ -0,0 +1,14 @@
+.aboutCard {
+  background-color: #fff3c4;
+  border: 1px solid #e6d38b;
+  border-left: 6px solid #111;
+  padding: 12px 14px;
+}
+
+.title {
+  margin: 0 0 6px;
+}
+
+.content {
+  margin: 0;
+}
diff --git a/e2e/react-start/transform-asset-urls/src/routes/about.tsx b/e2e/react-start/transform-asset-urls/src/routes/about.tsx
new file mode 100644
index 0000000000..e7baeb4292
--- /dev/null
+++ b/e2e/react-start/transform-asset-urls/src/routes/about.tsx
@@ -0,0 +1,19 @@
+import { createFileRoute } from '@tanstack/react-router'
+import styles from './about.module.css'
+
+export const Route = createFileRoute('/about')({
+  component: About,
+})
+
+function About() {
+  return (
+    <div data-testid="about-card" className={styles.aboutCard}>
+      <h1 data-testid="about-heading" className={styles.title}>
+        About
+      </h1>
+      <p data-testid="about-content" className={styles.content}>
+        This route is loaded on client navigation.
+      </p>
+    </div>
+  )
+}
diff --git a/e2e/react-start/transform-asset-urls/src/routes/index.tsx b/e2e/react-start/transform-asset-urls/src/routes/index.tsx
new file mode 100644
index 0000000000..e7aa38b8d9
--- /dev/null
+++ b/e2e/react-start/transform-asset-urls/src/routes/index.tsx
@@ -0,0 +1,19 @@
+import { Link, createFileRoute } from '@tanstack/react-router'
+
+export const Route = createFileRoute('/')({
+  component: Home,
+})
+
+function Home() {
+  return (
+    <div>
+      <h1 data-testid="home-heading">Welcome Home</h1>
+      <p data-testid="home-content">
+        This page tests the transformAssetUrls feature.
+      </p>
+      <Link to="/about" data-testid="link-to-about">
+        About
+      </Link>
+    </div>
+  )
+}
diff --git a/e2e/react-start/transform-asset-urls/src/server.ts b/e2e/react-start/transform-asset-urls/src/server.ts
new file mode 100644
index 0000000000..1757f03596
--- /dev/null
+++ b/e2e/react-start/transform-asset-urls/src/server.ts
@@ -0,0 +1,56 @@
+import {
+  createStartHandler,
+  defaultStreamHandler,
+} from '@tanstack/react-start/server'
+import { createServerEntry } from '@tanstack/react-start/server-entry'
+
+const cdnOrigin = process.env.CDN_ORIGIN
+const transformMode = process.env.TRANSFORM_ASSET_URLS_MODE || 'string'
+const optionsKind =
+  process.env.TRANSFORM_ASSET_URLS_OPTIONS_KIND || 'createTransform'
+const optionsCache = process.env.TRANSFORM_ASSET_URLS_OPTIONS_CACHE || 'true'
+const optionsWarmup = process.env.TRANSFORM_ASSET_URLS_OPTIONS_WARMUP || 'true'
+
+const cache = optionsCache !== 'false'
+const warmup = optionsWarmup === 'true'
+
+console.log(
+  `[server-entry]: using custom server entry with transformAssetUrls (${transformMode}${transformMode === 'options' ? `:${optionsKind}` : ''})${cdnOrigin ? ` (CDN: ${cdnOrigin})` : ' (no CDN)'}`,
+)
+
+const handler = createStartHandler(
+  cdnOrigin
+    ? {
+        handler: defaultStreamHandler,
+        transformAssetUrls: (() => {
+          const cdn = cdnOrigin.replace(/\/+$/, '')
+
+          if (transformMode === 'function') {
+            return ({ url }: { url: string }) => `${cdn}${url}`
+          }
+
+          if (transformMode === 'options') {
+            if (optionsKind === 'transform') {
+              return {
+                transform: ({ url }: { url: string }) => `${cdn}${url}`,
+                cache,
+                warmup,
+              }
+            }
+
+            return {
+              createTransform: async () => {
+                return ({ url }: { url: string }) => `${cdn}${url}`
+              },
+              cache,
+              warmup,
+            }
+          }
+
+          return cdn
+        })(),
+      }
+    : defaultStreamHandler,
+)
+
+export default createServerEntry({ fetch: handler })
diff --git a/e2e/react-start/transform-asset-urls/src/styles/app.css b/e2e/react-start/transform-asset-urls/src/styles/app.css
new file mode 100644
index 0000000000..6963f5edf3
--- /dev/null
+++ b/e2e/react-start/transform-asset-urls/src/styles/app.css
@@ -0,0 +1,11 @@
+body {
+  font-family: sans-serif;
+  margin: 0;
+  padding: 0;
+}
+
+.app-styled {
+  color: #333;
+  background-color: #f0f0f0;
+  padding: 16px;
+}
diff --git a/e2e/react-start/transform-asset-urls/tests/cdn-server.mjs b/e2e/react-start/transform-asset-urls/tests/cdn-server.mjs
new file mode 100644
index 0000000000..8b06bf6d60
--- /dev/null
+++ b/e2e/react-start/transform-asset-urls/tests/cdn-server.mjs
@@ -0,0 +1,28 @@
+import express from 'express'
+import path from 'node:path'
+import { fileURLToPath } from 'node:url'
+
+const __dirname = path.dirname(fileURLToPath(import.meta.url))
+const port = process.env.CDN_PORT || 3002
+
+const app = express()
+
+// Health check endpoint for Playwright webServer readiness.
+// This should return 200 even before the client build exists.
+app.get('/health', (_req, res) => {
+  res.status(200).send('ok')
+})
+
+// Serve the built client assets with CORS headers to simulate a CDN
+app.use((req, res, next) => {
+  res.setHeader('Access-Control-Allow-Origin', '*')
+  res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS')
+  res.setHeader('Access-Control-Allow-Headers', '*')
+  next()
+})
+
+app.use(express.static(path.resolve(__dirname, '..', 'dist', 'client')))
+
+app.listen(port, () => {
+  console.info(`CDN Server: http://localhost:${port}`)
+})
diff --git a/e2e/react-start/transform-asset-urls/tests/transform-asset-urls.spec.ts b/e2e/react-start/transform-asset-urls/tests/transform-asset-urls.spec.ts
new file mode 100644
index 0000000000..5ab10da6f2
--- /dev/null
+++ b/e2e/react-start/transform-asset-urls/tests/transform-asset-urls.spec.ts
@@ -0,0 +1,225 @@
+import { expect, type Page } from '@playwright/test'
+import { test } from '@tanstack/router-e2e-utils'
+
+/**
+ * Helper: fetch the SSR HTML for the given path using Playwright's
+ * APIRequestContext (no navigation/interception needed).
+ */
+async function getSSRHtml(page: Page, path = '/') {
+  const response = await page.request.get(path, {
+    headers: {
+      Accept: 'text/html',
+    },
+  })
+
+  expect(response.ok()).toBeTruthy()
+  const contentType = response.headers()['content-type'] || ''
+  expect(contentType).toContain('text/html')
+
+  return response.text()
+}
+
+test.describe('transformAssetUrls with CDN prefix', () => {
+  test('test run mode is set (string|function|options)', async () => {
+    expect(process.env.TRANSFORM_ASSET_URLS_MODE).toMatch(
+      /^(string|function|options)$/,
+    )
+
+    if (process.env.TRANSFORM_ASSET_URLS_MODE === 'options') {
+      expect(process.env.TRANSFORM_ASSET_URLS_OPTIONS_KIND).toMatch(
+        /^(transform|createTransform)$/,
+      )
+
+      expect(process.env.TRANSFORM_ASSET_URLS_OPTIONS_CACHE).toMatch(
+        /^(true|false)$/,
+      )
+      expect(process.env.TRANSFORM_ASSET_URLS_OPTIONS_WARMUP).toMatch(
+        /^(true|false)$/,
+      )
+    }
+  })
+
+  test('SSR HTML contains CDN-prefixed modulepreload links', async ({
+    page,
+  }) => {
+    const html = await getSSRHtml(page)
+
+    // All modulepreload links should point to the CDN origin
+    const modulepreloads = html.match(/rel="modulepreload"[^>]*href="([^"]+)"/g)
+    expect(modulepreloads).toBeTruthy()
+    expect(modulepreloads!.length).toBeGreaterThan(0)
+
+    for (const match of modulepreloads!) {
+      const href = match.match(/href="([^"]+)"/)?.[1]
+      expect(href).toBeTruthy()
+      expect(href).toMatch(/^http:\/\/localhost:\d+\//)
+    }
+  })
+
+  test('SSR HTML contains CDN-prefixed stylesheet link', async ({ page }) => {
+    const html = await getSSRHtml(page)
+
+    // The emitted stylesheet link should be CDN-prefixed
+    const stylesheetLinks = html.match(/rel="stylesheet"[^>]*href="([^"]+)"/g)
+    expect(stylesheetLinks).toBeTruthy()
+
+    const firstStylesheetLink = stylesheetLinks![0]
+    expect(firstStylesheetLink).toBeTruthy()
+
+    const href = firstStylesheetLink!.match(/href="([^"]+)"/)?.[1]
+    expect(href).toBeTruthy()
+    expect(href).toMatch(/^http:\/\/localhost:\d+\//)
+    expect(href).toMatch(/\.css(\?|$)/)
+  })
+
+  test('SSR HTML for /about references CSS modules stylesheet and style applies', async ({
+    page,
+  }) => {
+    const html = await getSSRHtml(page, '/about')
+
+    // Ensure the /about route's CSS module chunk is referenced in SSR HTML.
+    // In production builds, Vite emits hashed assets like "about.<hash>.css".
+    const stylesheetHrefs = Array.from(
+      html.matchAll(/rel="stylesheet"[^>]*href="([^"]+)"/g),
+    ).map((m) => m[1])
+
+    expect(stylesheetHrefs.length).toBeGreaterThan(0)
+
+    const aboutCssHrefs = stylesheetHrefs.filter((href) => {
+      if (!/^http:\/\/localhost:\d+\//.test(href)) return false
+
+      let pathname = ''
+      try {
+        pathname = new URL(href).pathname
+      } catch {
+        return false
+      }
+
+      const filename = pathname.split('/').pop() || ''
+      return filename.startsWith('about') && /\.css$/.test(filename)
+    })
+
+    expect(aboutCssHrefs.length).toBeGreaterThan(0)
+
+    // Now load /about and verify the CSS module style is actually applied.
+    await page.goto('/about')
+    await expect(page.getByTestId('about-card')).toBeVisible()
+
+    const bgColor = await page
+      .getByTestId('about-card')
+      .evaluate((el) => getComputedStyle(el).backgroundColor)
+
+    // #fff3c4 = rgb(255, 243, 196)
+    expect(bgColor).toBe('rgb(255, 243, 196)')
+  })
+
+  test('SSR HTML contains CDN-prefixed client entry script', async ({
+    page,
+  }) => {
+    const html = await getSSRHtml(page)
+
+    // The client entry script should contain an import() with CDN-prefixed URL
+    // JSON.stringify produces double quotes; bundler optimisation may use single quotes
+    const clientEntryMatch = html.match(
+      /import\(["'](http:\/\/localhost:\d+\/[^"']+)["']\)/,
+    )
+    expect(clientEntryMatch).toBeTruthy()
+    expect(clientEntryMatch![1]).toMatch(/^http:\/\/localhost:\d+\//)
+  })
+
+  test('page renders correctly with CDN-served assets', async ({ page }) => {
+    await page.goto('/')
+
+    // Page content renders
+    await expect(page.getByTestId('home-heading')).toHaveText('Welcome Home')
+    await expect(page.getByTestId('home-content')).toContainText(
+      'transformAssetUrls',
+    )
+  })
+
+  test('CSS is applied correctly from CDN', async ({ page }) => {
+    await page.goto('/')
+    await expect(page.locator('.app-styled')).toBeVisible()
+
+    // Verify that the CSS from app.css is actually applied
+    // The .app-styled class sets background-color to #f0f0f0
+    const bgColor = await page
+      .locator('.app-styled')
+      .evaluate((el) => getComputedStyle(el).backgroundColor)
+
+    // #f0f0f0 = rgb(240, 240, 240)
+    expect(bgColor).toBe('rgb(240, 240, 240)')
+  })
+
+  test('browser fetches assets from CDN server', async ({ page }) => {
+    // Track network requests to verify JS/CSS assets are fetched from a
+    // different origin than the app server (i.e. the CDN)
+    const appOrigin = new URL(
+      test.info().project.use.baseURL || 'http://localhost:3000',
+    ).origin
+    const assetRequests: Array<{ url: string; fromCdn: boolean }> = []
+
+    page.on('request', (request) => {
+      const url = request.url()
+      // Look for JS/CSS asset requests
+      if (/\.(js|css)(\?|$)/.test(url)) {
+        const origin = new URL(url).origin
+        assetRequests.push({ url, fromCdn: origin !== appOrigin })
+      }
+    })
+
+    await page.goto('/')
+    await page.waitForLoadState('networkidle')
+
+    // Verify that at least some asset requests went to a non-app origin (the CDN)
+    const cdnRequests = assetRequests.filter((r) => r.fromCdn)
+    expect(cdnRequests.length).toBeGreaterThan(0)
+  })
+
+  test('client-side navigation to /about loads split chunk from CDN', async ({
+    page,
+  }) => {
+    const appOrigin = new URL(
+      test.info().project.use.baseURL || 'http://localhost:3000',
+    ).origin
+
+    await page.goto('/')
+    await page.waitForLoadState('networkidle')
+
+    // Start tracking network requests after initial page load so we only
+    // capture requests triggered by the client-side navigation
+    const navigationAssetRequests: Array<{
+      url: string
+      fromCdn: boolean
+    }> = []
+
+    page.on('request', (request) => {
+      const url = request.url()
+      if (/\.(js|css)(\?|$)/.test(url)) {
+        const origin = new URL(url).origin
+        navigationAssetRequests.push({ url, fromCdn: origin !== appOrigin })
+      }
+    })
+
+    await page.getByTestId('link-to-about').click()
+    await page.waitForURL('**/about')
+    await expect(page.getByTestId('about-heading')).toHaveText('About')
+
+    // Ensure CSS modules were loaded and applied after client navigation
+    await expect(page.getByTestId('about-card')).toBeVisible()
+    const bgColor = await page
+      .getByTestId('about-card')
+      .evaluate((el) => getComputedStyle(el).backgroundColor)
+    expect(bgColor).toBe('rgb(255, 243, 196)')
+
+    // With base: '', lazy-loaded route chunks should come from the CDN, not the app server.
+    // Filter to JS requests only (the route chunk import)
+    const jsRequests = navigationAssetRequests.filter((r) =>
+      /\.js(\?|$)/.test(r.url),
+    )
+    expect(jsRequests.length).toBeGreaterThan(0)
+
+    const cdnJsRequests = jsRequests.filter((r) => r.fromCdn)
+    expect(cdnJsRequests.length).toBeGreaterThan(0)
+  })
+})
diff --git a/e2e/react-start/transform-asset-urls/tsconfig.json b/e2e/react-start/transform-asset-urls/tsconfig.json
new file mode 100644
index 0000000000..3a9fb7cd71
--- /dev/null
+++ b/e2e/react-start/transform-asset-urls/tsconfig.json
@@ -0,0 +1,22 @@
+{
+  "include": ["**/*.ts", "**/*.tsx"],
+  "compilerOptions": {
+    "strict": true,
+    "esModuleInterop": true,
+    "jsx": "react-jsx",
+    "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/react-start/transform-asset-urls/vite.config.ts b/e2e/react-start/transform-asset-urls/vite.config.ts
new file mode 100644
index 0000000000..ca16b6425b
--- /dev/null
+++ b/e2e/react-start/transform-asset-urls/vite.config.ts
@@ -0,0 +1,18 @@
+import { defineConfig } from 'vite'
+import tsConfigPaths from 'vite-tsconfig-paths'
+import { tanstackStart } from '@tanstack/react-start/plugin/vite'
+import viteReact from '@vitejs/plugin-react'
+
+export default defineConfig({
+  base: '',
+  server: {
+    port: 3000,
+  },
+  plugins: [
+    tsConfigPaths({
+      projects: ['./tsconfig.json'],
+    }),
+    tanstackStart(),
+    viteReact(),
+  ],
+})
diff --git a/e2e/react-start/virtual-routes/package.json b/e2e/react-start/virtual-routes/package.json
index b8d0bdce0e..e7875b55a3 100644
--- a/e2e/react-start/virtual-routes/package.json
+++ b/e2e/react-start/virtual-routes/package.json
@@ -32,7 +32,7 @@
     "@types/react-dom": "^19.0.3",
     "@vitejs/plugin-react": "^4.3.4",
     "combinate": "^1.1.11",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite-tsconfig-paths": "^5.1.4"
diff --git a/e2e/react-start/website/package.json b/e2e/react-start/website/package.json
index e91a85b74c..8908a76464 100644
--- a/e2e/react-start/website/package.json
+++ b/e2e/react-start/website/package.json
@@ -29,7 +29,7 @@
     "@types/react": "^19.0.8",
     "@types/react-dom": "^19.0.3",
     "@vitejs/plugin-react": "^4.3.4",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite": "^7.3.1",
diff --git a/e2e/solid-start/basic-auth/package.json b/e2e/solid-start/basic-auth/package.json
index 910616c97f..546cec380d 100644
--- a/e2e/solid-start/basic-auth/package.json
+++ b/e2e/solid-start/basic-auth/package.json
@@ -31,7 +31,7 @@
     "@types/node": "^22.10.2",
     "dotenv": "^17.2.3",
     "prisma": "^7.0.0",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite-plugin-solid": "^2.11.10",
diff --git a/e2e/solid-start/basic-solid-query/package.json b/e2e/solid-start/basic-solid-query/package.json
index fa04c331f3..d3f5e42572 100644
--- a/e2e/solid-start/basic-solid-query/package.json
+++ b/e2e/solid-start/basic-solid-query/package.json
@@ -29,7 +29,7 @@
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/router-e2e-utils": "workspace:^",
     "@types/node": "^22.10.2",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite-plugin-solid": "^2.11.10",
diff --git a/e2e/solid-start/basic-tsr-config/package.json b/e2e/solid-start/basic-tsr-config/package.json
index 7071febba5..72aa2d6f6a 100644
--- a/e2e/solid-start/basic-tsr-config/package.json
+++ b/e2e/solid-start/basic-tsr-config/package.json
@@ -20,7 +20,7 @@
   "devDependencies": {
     "@tanstack/router-e2e-utils": "workspace:^",
     "@types/node": "^22.10.2",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "typescript": "^5.7.2",
     "vite-plugin-solid": "^2.11.10",
     "vite-tsconfig-paths": "^5.1.4"
diff --git a/e2e/solid-start/basic/package.json b/e2e/solid-start/basic/package.json
index a6563fdca6..749fcaa237 100644
--- a/e2e/solid-start/basic/package.json
+++ b/e2e/solid-start/basic/package.json
@@ -39,7 +39,7 @@
     "@types/js-cookie": "^3.0.6",
     "@types/node": "^22.10.2",
     "combinate": "^1.1.11",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite-plugin-solid": "^2.11.10",
diff --git a/e2e/solid-start/basic/tests/special-characters.spec.ts b/e2e/solid-start/basic/tests/special-characters.spec.ts
index 9549d491ce..6bbb240a84 100644
--- a/e2e/solid-start/basic/tests/special-characters.spec.ts
+++ b/e2e/solid-start/basic/tests/special-characters.spec.ts
@@ -122,10 +122,9 @@ test.describe('Unicode route rendering', () => {
 
       await expect(page.getByTestId('special-hash-heading')).toBeInViewport()
 
-      // TODO: this should work but seems to be a bug in reactivity on Solid Dynamic component. Still investigating.
-      // await expect(page.getByTestId('special-hash-link-1')).toContainClass(
-      //   'font-bold',
-      // )
+      await expect(page.getByTestId('special-hash-link-1')).toContainClass(
+        'font-bold',
+      )
 
       await expect(page.getByTestId('special-hash-link-2')).not.toContainClass(
         'font-bold',
diff --git a/e2e/solid-start/csp/package.json b/e2e/solid-start/csp/package.json
index f0c7d98c26..6ce20c0389 100644
--- a/e2e/solid-start/csp/package.json
+++ b/e2e/solid-start/csp/package.json
@@ -20,7 +20,7 @@
     "@playwright/test": "^1.50.1",
     "@tanstack/router-e2e-utils": "workspace:^",
     "@types/node": "^22.10.2",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "typescript": "^5.7.2",
     "vite-plugin-solid": "^2.11.10"
   }
diff --git a/e2e/solid-start/css-modules/package.json b/e2e/solid-start/css-modules/package.json
index f66ccb067f..348febba3f 100644
--- a/e2e/solid-start/css-modules/package.json
+++ b/e2e/solid-start/css-modules/package.json
@@ -23,7 +23,7 @@
     "@tanstack/router-e2e-utils": "workspace:*",
     "@types/node": "^22.10.2",
     "sass": "^1.97.2",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "typescript": "^5.7.2",
     "vite": "^7.3.1",
     "vite-plugin-solid": "^2.11.10",
diff --git a/e2e/solid-start/custom-basepath/package.json b/e2e/solid-start/custom-basepath/package.json
index 3f078c4142..1feac0e3ba 100644
--- a/e2e/solid-start/custom-basepath/package.json
+++ b/e2e/solid-start/custom-basepath/package.json
@@ -25,7 +25,7 @@
     "@types/express": "^5.0.3",
     "@types/node": "^22.10.2",
     "cross-env": "^10.0.0",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "tsx": "^4.20.3",
     "typescript": "^5.7.2",
diff --git a/e2e/solid-start/scroll-restoration/package.json b/e2e/solid-start/scroll-restoration/package.json
index bbc7654a5c..a386d7383f 100644
--- a/e2e/solid-start/scroll-restoration/package.json
+++ b/e2e/solid-start/scroll-restoration/package.json
@@ -28,7 +28,7 @@
     "@tanstack/router-e2e-utils": "workspace:^",
     "@types/node": "^22.10.2",
     "combinate": "^1.1.11",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite-plugin-solid": "^2.11.10",
diff --git a/e2e/solid-start/selective-ssr/package.json b/e2e/solid-start/selective-ssr/package.json
index bb0cb62baa..08b3f02f03 100644
--- a/e2e/solid-start/selective-ssr/package.json
+++ b/e2e/solid-start/selective-ssr/package.json
@@ -20,7 +20,7 @@
   "devDependencies": {
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/router-e2e-utils": "workspace:^",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite": "^7.3.1",
diff --git a/e2e/solid-start/serialization-adapters/package.json b/e2e/solid-start/serialization-adapters/package.json
index f3877e969c..55231ee35b 100644
--- a/e2e/solid-start/serialization-adapters/package.json
+++ b/e2e/solid-start/serialization-adapters/package.json
@@ -24,7 +24,7 @@
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/router-e2e-utils": "workspace:^",
     "@types/node": "^22.10.2",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite-plugin-solid": "^2.11.9"
diff --git a/e2e/solid-start/server-functions/package.json b/e2e/solid-start/server-functions/package.json
index a257dd1651..da1c7998f0 100644
--- a/e2e/solid-start/server-functions/package.json
+++ b/e2e/solid-start/server-functions/package.json
@@ -31,7 +31,7 @@
     "@types/js-cookie": "^3.0.6",
     "@types/node": "^22.10.2",
     "combinate": "^1.1.11",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite-plugin-solid": "^2.11.10",
diff --git a/e2e/solid-start/server-functions/src/routes/abort-signal/$method.tsx b/e2e/solid-start/server-functions/src/routes/abort-signal/$method.tsx
index 2c4edf359d..991385e8a0 100644
--- a/e2e/solid-start/server-functions/src/routes/abort-signal/$method.tsx
+++ b/e2e/solid-start/server-functions/src/routes/abort-signal/$method.tsx
@@ -1,5 +1,6 @@
 import { createFileRoute } from '@tanstack/solid-router'
-import { createServerFn } from '@tanstack/solid-start'
+import { createServerFn, createServerOnlyFn } from '@tanstack/solid-start'
+import { getRequest } from '@tanstack/solid-start/server'
 import * as Solid from 'solid-js'
 import z from 'zod'
 
@@ -10,7 +11,9 @@ export const Route = createFileRoute('/abort-signal/$method')({
   component: RouteComponent,
 })
 
-function serverFnImpl(signal: AbortSignal) {
+const serverFnImpl = createServerOnlyFn(async () => {
+  const request = getRequest()
+  const signal = request.signal
   console.log('server function started', { signal })
   return new Promise<string>((resolve, reject) => {
     if (signal.aborted) {
@@ -27,13 +30,11 @@ function serverFnImpl(signal: AbortSignal) {
     }
     signal.addEventListener('abort', onAbort, { once: true })
   })
-}
-const abortableServerFnGET = createServerFn().handler(async ({ signal }) =>
-  serverFnImpl(signal),
-)
+})
+const abortableServerFnGET = createServerFn().handler(serverFnImpl)
 
 const abortableServerFnPOST = createServerFn({ method: 'POST' }).handler(
-  async ({ signal }) => serverFnImpl(signal),
+  serverFnImpl,
 )
 
 function RouteComponent() {
diff --git a/e2e/solid-start/server-routes/package.json b/e2e/solid-start/server-routes/package.json
index ab34d73429..b98a9b35a6 100644
--- a/e2e/solid-start/server-routes/package.json
+++ b/e2e/solid-start/server-routes/package.json
@@ -31,7 +31,7 @@
     "@types/js-cookie": "^3.0.6",
     "@types/node": "^22.10.2",
     "combinate": "^1.1.11",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite-plugin-solid": "^2.11.10",
diff --git a/e2e/solid-start/virtual-routes/package.json b/e2e/solid-start/virtual-routes/package.json
index 214d1d5524..d9fafc304c 100644
--- a/e2e/solid-start/virtual-routes/package.json
+++ b/e2e/solid-start/virtual-routes/package.json
@@ -28,7 +28,7 @@
     "@tanstack/router-e2e-utils": "workspace:^",
     "@types/node": "^22.10.2",
     "combinate": "^1.1.11",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite-plugin-solid": "^2.11.10",
diff --git a/e2e/solid-start/website/package.json b/e2e/solid-start/website/package.json
index 9496c1553e..cd7b01ace4 100644
--- a/e2e/solid-start/website/package.json
+++ b/e2e/solid-start/website/package.json
@@ -26,7 +26,7 @@
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/router-e2e-utils": "workspace:^",
     "@types/node": "^22.10.2",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite-plugin-solid": "^2.11.10",
diff --git a/e2e/vue-start/basic-auth/package.json b/e2e/vue-start/basic-auth/package.json
index fcf4e937ff..4b536d56e4 100644
--- a/e2e/vue-start/basic-auth/package.json
+++ b/e2e/vue-start/basic-auth/package.json
@@ -31,7 +31,7 @@
     "@types/node": "^22.10.2",
     "dotenv": "^17.2.3",
     "prisma": "^7.0.0",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "@vitejs/plugin-vue": "^6.0.3",
diff --git a/e2e/vue-start/basic-tsr-config/package.json b/e2e/vue-start/basic-tsr-config/package.json
index 0242096ea6..f707d39ef9 100644
--- a/e2e/vue-start/basic-tsr-config/package.json
+++ b/e2e/vue-start/basic-tsr-config/package.json
@@ -20,7 +20,7 @@
   "devDependencies": {
     "@tanstack/router-e2e-utils": "workspace:^",
     "@types/node": "^22.10.2",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "typescript": "^5.7.2",
     "@vitejs/plugin-vue": "^6.0.3",
     "@vitejs/plugin-vue-jsx": "^5.1.2",
diff --git a/e2e/vue-start/basic-vue-query/package.json b/e2e/vue-start/basic-vue-query/package.json
index bcd9ca9652..d075ce6488 100644
--- a/e2e/vue-start/basic-vue-query/package.json
+++ b/e2e/vue-start/basic-vue-query/package.json
@@ -29,7 +29,7 @@
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/router-e2e-utils": "workspace:^",
     "@types/node": "^22.10.2",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "@vitejs/plugin-vue": "^6.0.3",
diff --git a/e2e/vue-start/basic/package.json b/e2e/vue-start/basic/package.json
index a25411f9c7..62e03a3389 100644
--- a/e2e/vue-start/basic/package.json
+++ b/e2e/vue-start/basic/package.json
@@ -41,7 +41,7 @@
     "@vitejs/plugin-vue": "^5.2.4",
     "@vitejs/plugin-vue-jsx": "^4.1.2",
     "combinate": "^1.1.11",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite-tsconfig-paths": "^5.1.4"
diff --git a/e2e/vue-start/css-modules/package.json b/e2e/vue-start/css-modules/package.json
index 00933d2f6a..63270632cc 100644
--- a/e2e/vue-start/css-modules/package.json
+++ b/e2e/vue-start/css-modules/package.json
@@ -24,7 +24,7 @@
     "@types/node": "^22.10.2",
     "@vitejs/plugin-vue-jsx": "^4.1.2",
     "sass": "^1.97.2",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "typescript": "^5.7.2",
     "vite": "^7.3.1",
     "vite-tsconfig-paths": "^5.1.4"
diff --git a/e2e/vue-start/custom-basepath/package.json b/e2e/vue-start/custom-basepath/package.json
index 22c7062867..9910391a93 100644
--- a/e2e/vue-start/custom-basepath/package.json
+++ b/e2e/vue-start/custom-basepath/package.json
@@ -25,7 +25,7 @@
     "@types/express": "^5.0.3",
     "@types/node": "^22.10.2",
     "cross-env": "^10.0.0",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "tsx": "^4.20.3",
     "typescript": "^5.7.2",
diff --git a/e2e/vue-start/scroll-restoration/package.json b/e2e/vue-start/scroll-restoration/package.json
index 6344dbec57..19ea7f65be 100644
--- a/e2e/vue-start/scroll-restoration/package.json
+++ b/e2e/vue-start/scroll-restoration/package.json
@@ -28,7 +28,7 @@
     "@tanstack/router-e2e-utils": "workspace:^",
     "@types/node": "^22.10.2",
     "combinate": "^1.1.11",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "@vitejs/plugin-vue": "^6.0.3",
diff --git a/e2e/vue-start/selective-ssr/package.json b/e2e/vue-start/selective-ssr/package.json
index 3d94ff9b27..ff082cc638 100644
--- a/e2e/vue-start/selective-ssr/package.json
+++ b/e2e/vue-start/selective-ssr/package.json
@@ -20,7 +20,7 @@
   "devDependencies": {
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/router-e2e-utils": "workspace:^",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite": "^7.3.1",
diff --git a/e2e/vue-start/serialization-adapters/package.json b/e2e/vue-start/serialization-adapters/package.json
index f07394302e..2be92888eb 100644
--- a/e2e/vue-start/serialization-adapters/package.json
+++ b/e2e/vue-start/serialization-adapters/package.json
@@ -21,7 +21,7 @@
   "devDependencies": {
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/router-e2e-utils": "workspace:^",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "vite": "^7.3.1",
diff --git a/e2e/vue-start/server-functions/package.json b/e2e/vue-start/server-functions/package.json
index 2c7c5c69f7..5f232aa8af 100644
--- a/e2e/vue-start/server-functions/package.json
+++ b/e2e/vue-start/server-functions/package.json
@@ -31,7 +31,7 @@
     "@types/js-cookie": "^3.0.6",
     "@types/node": "^22.10.2",
     "combinate": "^1.1.11",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "@vitejs/plugin-vue": "^6.0.3",
diff --git a/e2e/vue-start/server-functions/src/routes/abort-signal.tsx b/e2e/vue-start/server-functions/src/routes/abort-signal.tsx
index 2a3e08ae59..1fcf89a0b4 100644
--- a/e2e/vue-start/server-functions/src/routes/abort-signal.tsx
+++ b/e2e/vue-start/server-functions/src/routes/abort-signal.tsx
@@ -1,27 +1,27 @@
 import { createFileRoute } from '@tanstack/vue-router'
 import { createServerFn } from '@tanstack/vue-start'
+import { getRequest } from '@tanstack/vue-start/server'
 import { defineComponent, ref } from 'vue'
 
-const abortableServerFn = createServerFn().handler(
-  async ({ context, signal }) => {
-    console.log('server function started', { context, signal })
-    return new Promise<string>((resolve, reject) => {
-      if (signal.aborted) {
-        return reject(new Error('Aborted before start'))
-      }
-      const timerId = setTimeout(() => {
-        console.log('server function finished')
-        resolve('server function result')
-      }, 1000)
-      const onAbort = () => {
-        clearTimeout(timerId)
-        console.log('server function aborted')
-        reject(new Error('Aborted'))
-      }
-      signal.addEventListener('abort', onAbort, { once: true })
-    })
-  },
-)
+const abortableServerFn = createServerFn().handler(async ({ context }) => {
+  console.log('server function started', { context })
+  const signal = getRequest().signal
+  return new Promise<string>((resolve, reject) => {
+    if (signal.aborted) {
+      return reject(new Error('Aborted before start'))
+    }
+    const timerId = setTimeout(() => {
+      console.log('server function finished')
+      resolve('server function result')
+    }, 1000)
+    const onAbort = () => {
+      clearTimeout(timerId)
+      console.log('server function aborted')
+      reject(new Error('Aborted'))
+    }
+    signal.addEventListener('abort', onAbort, { once: true })
+  })
+})
 
 const RouteComponent = defineComponent({
   setup() {
diff --git a/e2e/vue-start/server-routes/package.json b/e2e/vue-start/server-routes/package.json
index 4c84f772cb..45a613a706 100644
--- a/e2e/vue-start/server-routes/package.json
+++ b/e2e/vue-start/server-routes/package.json
@@ -31,7 +31,7 @@
     "@types/js-cookie": "^3.0.6",
     "@types/node": "^22.10.2",
     "combinate": "^1.1.11",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "@vitejs/plugin-vue": "^6.0.3",
diff --git a/e2e/vue-start/virtual-routes/package.json b/e2e/vue-start/virtual-routes/package.json
index 61520fcfa7..8219236f68 100644
--- a/e2e/vue-start/virtual-routes/package.json
+++ b/e2e/vue-start/virtual-routes/package.json
@@ -28,7 +28,7 @@
     "@tanstack/router-e2e-utils": "workspace:^",
     "@types/node": "^22.10.2",
     "combinate": "^1.1.11",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "@vitejs/plugin-vue": "^6.0.3",
diff --git a/e2e/vue-start/website/package.json b/e2e/vue-start/website/package.json
index 011eecb685..da1a3eae12 100644
--- a/e2e/vue-start/website/package.json
+++ b/e2e/vue-start/website/package.json
@@ -26,7 +26,7 @@
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/router-e2e-utils": "workspace:^",
     "@types/node": "^22.10.2",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwindcss": "^4.1.18",
     "typescript": "^5.7.2",
     "@vitejs/plugin-vue": "^6.0.3",
diff --git a/examples/react/authenticated-routes-firebase/package.json b/examples/react/authenticated-routes-firebase/package.json
index 0730ceae92..2e495d2551 100644
--- a/examples/react/authenticated-routes-firebase/package.json
+++ b/examples/react/authenticated-routes-firebase/package.json
@@ -10,9 +10,9 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "firebase": "^11.4.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
diff --git a/examples/react/authenticated-routes/package.json b/examples/react/authenticated-routes/package.json
index d6cbdb87cb..3dbb358743 100644
--- a/examples/react/authenticated-routes/package.json
+++ b/examples/react/authenticated-routes/package.json
@@ -10,9 +10,9 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1",
diff --git a/examples/react/basic-default-search-params/package.json b/examples/react/basic-default-search-params/package.json
index c8f1bde3d2..8bcc5cea58 100644
--- a/examples/react/basic-default-search-params/package.json
+++ b/examples/react/basic-default-search-params/package.json
@@ -11,8 +11,8 @@
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/react-query": "^5.90.0",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1",
diff --git a/examples/react/basic-devtools-panel/package.json b/examples/react/basic-devtools-panel/package.json
index c4538e0b1c..a40d8e8aed 100644
--- a/examples/react/basic-devtools-panel/package.json
+++ b/examples/react/basic-devtools-panel/package.json
@@ -11,8 +11,8 @@
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/react-query-devtools": "^5.67.2",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1",
diff --git a/examples/react/basic-file-based/package.json b/examples/react/basic-file-based/package.json
index b6a002888a..79a111c08f 100644
--- a/examples/react/basic-file-based/package.json
+++ b/examples/react/basic-file-based/package.json
@@ -10,9 +10,9 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1",
diff --git a/examples/react/basic-non-nested-devtools/package.json b/examples/react/basic-non-nested-devtools/package.json
index 9a99e629b9..ee5db558a2 100644
--- a/examples/react/basic-non-nested-devtools/package.json
+++ b/examples/react/basic-non-nested-devtools/package.json
@@ -10,8 +10,8 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1",
diff --git a/examples/react/basic-react-query-file-based/package.json b/examples/react/basic-react-query-file-based/package.json
index ec8049249b..408c456280 100644
--- a/examples/react/basic-react-query-file-based/package.json
+++ b/examples/react/basic-react-query-file-based/package.json
@@ -12,9 +12,9 @@
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/react-query": "^5.90.0",
     "@tanstack/react-query-devtools": "^5.90.0",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1",
diff --git a/examples/react/basic-react-query/package.json b/examples/react/basic-react-query/package.json
index 2c7dedac29..549146e7c5 100644
--- a/examples/react/basic-react-query/package.json
+++ b/examples/react/basic-react-query/package.json
@@ -12,8 +12,8 @@
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/react-query": "^5.90.0",
     "@tanstack/react-query-devtools": "^5.90.0",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1",
diff --git a/examples/react/basic-ssr-file-based/package.json b/examples/react/basic-ssr-file-based/package.json
index e2bb84884a..7be4e67e36 100644
--- a/examples/react/basic-ssr-file-based/package.json
+++ b/examples/react/basic-ssr-file-based/package.json
@@ -11,8 +11,8 @@
     "debug": "node --inspect-brk server"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "compression": "^1.8.0",
     "express": "^4.21.2",
     "get-port": "^7.1.0",
@@ -21,7 +21,7 @@
     "react-dom": "^19.0.0"
   },
   "devDependencies": {
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "@types/express": "^4.17.23",
     "@types/react": "^19.0.8",
     "@types/react-dom": "^19.0.1",
diff --git a/examples/react/basic-ssr-streaming-file-based/package.json b/examples/react/basic-ssr-streaming-file-based/package.json
index 04a11eb1a9..9436f753a6 100644
--- a/examples/react/basic-ssr-streaming-file-based/package.json
+++ b/examples/react/basic-ssr-streaming-file-based/package.json
@@ -11,8 +11,8 @@
     "debug": "node --inspect-brk server"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "compression": "^1.8.0",
     "express": "^4.21.2",
     "get-port": "^7.1.0",
@@ -21,7 +21,7 @@
     "react-dom": "^19.0.0"
   },
   "devDependencies": {
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "@types/express": "^4.17.23",
     "@types/react": "^19.0.8",
     "@types/react-dom": "^19.0.1",
diff --git a/examples/react/basic-virtual-file-based/package.json b/examples/react/basic-virtual-file-based/package.json
index 5e6a59f3c5..9cf5c29d67 100644
--- a/examples/react/basic-virtual-file-based/package.json
+++ b/examples/react/basic-virtual-file-based/package.json
@@ -10,9 +10,9 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "@tanstack/virtual-file-routes": "^1.154.7",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
diff --git a/examples/react/basic-virtual-inside-file-based/package.json b/examples/react/basic-virtual-inside-file-based/package.json
index 52b96cb648..24ff6fdd31 100644
--- a/examples/react/basic-virtual-inside-file-based/package.json
+++ b/examples/react/basic-virtual-inside-file-based/package.json
@@ -10,9 +10,9 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "@tanstack/virtual-file-routes": "^1.154.7",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
diff --git a/examples/react/basic/package.json b/examples/react/basic/package.json
index eb5732dfd1..fafccd16be 100644
--- a/examples/react/basic/package.json
+++ b/examples/react/basic/package.json
@@ -10,8 +10,8 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1",
diff --git a/examples/react/deferred-data/package.json b/examples/react/deferred-data/package.json
index 1bfe74d51b..52dc684958 100644
--- a/examples/react/deferred-data/package.json
+++ b/examples/react/deferred-data/package.json
@@ -10,8 +10,8 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1",
diff --git a/examples/react/i18n-paraglide/package.json b/examples/react/i18n-paraglide/package.json
index 1e8d3d8581..89d38d23ac 100644
--- a/examples/react/i18n-paraglide/package.json
+++ b/examples/react/i18n-paraglide/package.json
@@ -11,8 +11,8 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "react": "^19.1.1",
     "react-dom": "^19.1.1",
     "tailwindcss": "^4.1.18"
diff --git a/examples/react/kitchen-sink-file-based/package.json b/examples/react/kitchen-sink-file-based/package.json
index 446236f2bc..a79d15b76b 100644
--- a/examples/react/kitchen-sink-file-based/package.json
+++ b/examples/react/kitchen-sink-file-based/package.json
@@ -10,9 +10,9 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "immer": "^10.1.1",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
diff --git a/examples/react/kitchen-sink-react-query-file-based/package.json b/examples/react/kitchen-sink-react-query-file-based/package.json
index 5a9e4df256..f1ed8b5ccc 100644
--- a/examples/react/kitchen-sink-react-query-file-based/package.json
+++ b/examples/react/kitchen-sink-react-query-file-based/package.json
@@ -12,9 +12,9 @@
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/react-query": "^5.90.0",
     "@tanstack/react-query-devtools": "^5.90.0",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "immer": "^10.1.1",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
diff --git a/examples/react/kitchen-sink-react-query/package.json b/examples/react/kitchen-sink-react-query/package.json
index 5bcbaea770..fb5123aca4 100644
--- a/examples/react/kitchen-sink-react-query/package.json
+++ b/examples/react/kitchen-sink-react-query/package.json
@@ -12,8 +12,8 @@
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/react-query": "^5.90.0",
     "@tanstack/react-query-devtools": "^5.90.0",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "immer": "^10.1.1",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
diff --git a/examples/react/kitchen-sink/package.json b/examples/react/kitchen-sink/package.json
index 609be68c47..08a4761456 100644
--- a/examples/react/kitchen-sink/package.json
+++ b/examples/react/kitchen-sink/package.json
@@ -10,8 +10,8 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "immer": "^10.1.1",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
diff --git a/examples/react/large-file-based/package.json b/examples/react/large-file-based/package.json
index 6e37f688b8..6d90a03f47 100644
--- a/examples/react/large-file-based/package.json
+++ b/examples/react/large-file-based/package.json
@@ -13,9 +13,9 @@
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/react-query": "^5.90.0",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1",
diff --git a/examples/react/location-masking/package.json b/examples/react/location-masking/package.json
index 2c5d181477..2a2191e0ec 100644
--- a/examples/react/location-masking/package.json
+++ b/examples/react/location-masking/package.json
@@ -12,8 +12,8 @@
     "@radix-ui/react-dialog": "^1.1.6",
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/react-query": "^5.90.0",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1",
diff --git a/examples/react/navigation-blocking/package.json b/examples/react/navigation-blocking/package.json
index c905745c03..0bcd5827a8 100644
--- a/examples/react/navigation-blocking/package.json
+++ b/examples/react/navigation-blocking/package.json
@@ -11,8 +11,8 @@
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/react-query": "^5.90.0",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1",
diff --git a/examples/react/quickstart-esbuild-file-based/package.json b/examples/react/quickstart-esbuild-file-based/package.json
index 8adb74ac84..4a09509441 100644
--- a/examples/react/quickstart-esbuild-file-based/package.json
+++ b/examples/react/quickstart-esbuild-file-based/package.json
@@ -9,9 +9,9 @@
     "start": "dev"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1",
diff --git a/examples/react/quickstart-file-based/package.json b/examples/react/quickstart-file-based/package.json
index a37111edf9..eae97e21cf 100644
--- a/examples/react/quickstart-file-based/package.json
+++ b/examples/react/quickstart-file-based/package.json
@@ -10,9 +10,9 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1",
diff --git a/examples/react/quickstart-rspack-file-based/package.json b/examples/react/quickstart-rspack-file-based/package.json
index 739eba3583..98006869b3 100644
--- a/examples/react/quickstart-rspack-file-based/package.json
+++ b/examples/react/quickstart-rspack-file-based/package.json
@@ -9,8 +9,8 @@
   },
   "dependencies": {
     "@tailwindcss/postcss": "^4.1.18",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "postcss": "^8.5.1",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
@@ -19,7 +19,7 @@
   "devDependencies": {
     "@rsbuild/core": "^1.2.4",
     "@rsbuild/plugin-react": "^1.1.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "@types/react": "^19.0.8",
     "@types/react-dom": "^19.0.3",
     "typescript": "^5.6.2"
diff --git a/examples/react/quickstart-webpack-file-based/package.json b/examples/react/quickstart-webpack-file-based/package.json
index 139e13ac2c..9b0b74da43 100644
--- a/examples/react/quickstart-webpack-file-based/package.json
+++ b/examples/react/quickstart-webpack-file-based/package.json
@@ -7,14 +7,14 @@
     "build": "webpack build && tsc --noEmit"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0"
   },
   "devDependencies": {
     "@swc/core": "^1.10.15",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "@types/react": "^19.0.8",
     "@types/react-dom": "^19.0.3",
     "html-webpack-plugin": "^5.6.3",
diff --git a/examples/react/quickstart/package.json b/examples/react/quickstart/package.json
index d945bd2321..b2f3316249 100644
--- a/examples/react/quickstart/package.json
+++ b/examples/react/quickstart/package.json
@@ -10,8 +10,8 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "tailwindcss": "^4.1.18"
diff --git a/examples/react/router-monorepo-react-query/package.json b/examples/react/router-monorepo-react-query/package.json
index 7877e366f7..c1365e326d 100644
--- a/examples/react/router-monorepo-react-query/package.json
+++ b/examples/react/router-monorepo-react-query/package.json
@@ -12,9 +12,9 @@
   "dependencies": {
     "@tanstack/react-query": "^5.90.0",
     "@tanstack/react-query-devtools": "^5.90.0",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1"
diff --git a/examples/react/router-monorepo-react-query/packages/app/package.json b/examples/react/router-monorepo-react-query/packages/app/package.json
index 3fdb837e31..9ae3b0eca2 100644
--- a/examples/react/router-monorepo-react-query/packages/app/package.json
+++ b/examples/react/router-monorepo-react-query/packages/app/package.json
@@ -16,7 +16,7 @@
     "react-dom": "^19.0.0"
   },
   "devDependencies": {
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "@types/react": "^19.0.8",
     "@types/react-dom": "^19.0.3",
     "@vitejs/plugin-react": "^4.3.4",
diff --git a/examples/react/router-monorepo-react-query/packages/router/package.json b/examples/react/router-monorepo-react-query/packages/router/package.json
index 16eaa9a800..3f187ab0af 100644
--- a/examples/react/router-monorepo-react-query/packages/router/package.json
+++ b/examples/react/router-monorepo-react-query/packages/router/package.json
@@ -10,8 +10,8 @@
   "dependencies": {
     "@tanstack/history": "^1.154.14",
     "@tanstack/react-query": "^5.90.0",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "@router-mono-react-query/post-query": "workspace:*",
     "redaxios": "^0.5.1",
     "zod": "^3.24.2",
diff --git a/examples/react/router-monorepo-simple-lazy/package.json b/examples/react/router-monorepo-simple-lazy/package.json
index 2d2563b36b..2329debfac 100644
--- a/examples/react/router-monorepo-simple-lazy/package.json
+++ b/examples/react/router-monorepo-simple-lazy/package.json
@@ -8,9 +8,9 @@
     "dev": "pnpm router build && pnpm post-feature build && pnpm app dev"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1"
diff --git a/examples/react/router-monorepo-simple-lazy/packages/app/package.json b/examples/react/router-monorepo-simple-lazy/packages/app/package.json
index e0f3d5b37c..ccd08723f9 100644
--- a/examples/react/router-monorepo-simple-lazy/packages/app/package.json
+++ b/examples/react/router-monorepo-simple-lazy/packages/app/package.json
@@ -15,7 +15,7 @@
     "react-dom": "^19.0.0"
   },
   "devDependencies": {
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "@types/react": "^19.0.8",
     "@types/react-dom": "^19.0.3",
     "@vitejs/plugin-react": "^4.3.4",
diff --git a/examples/react/router-monorepo-simple-lazy/packages/router/package.json b/examples/react/router-monorepo-simple-lazy/packages/router/package.json
index e8cf45d420..abbf510229 100644
--- a/examples/react/router-monorepo-simple-lazy/packages/router/package.json
+++ b/examples/react/router-monorepo-simple-lazy/packages/router/package.json
@@ -9,8 +9,8 @@
   "types": "./dist/index.d.ts",
   "dependencies": {
     "@tanstack/history": "^1.154.14",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "redaxios": "^0.5.1",
     "zod": "^3.24.2",
     "react": "^19.0.0",
diff --git a/examples/react/router-monorepo-simple/package.json b/examples/react/router-monorepo-simple/package.json
index 6a547b9ed9..b31bdda4fa 100644
--- a/examples/react/router-monorepo-simple/package.json
+++ b/examples/react/router-monorepo-simple/package.json
@@ -8,9 +8,9 @@
     "dev": "pnpm router build && pnpm post-feature build && pnpm app dev"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1"
diff --git a/examples/react/router-monorepo-simple/packages/app/package.json b/examples/react/router-monorepo-simple/packages/app/package.json
index 34809d2840..940c4e32ce 100644
--- a/examples/react/router-monorepo-simple/packages/app/package.json
+++ b/examples/react/router-monorepo-simple/packages/app/package.json
@@ -15,7 +15,7 @@
     "react-dom": "^19.0.0"
   },
   "devDependencies": {
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "@types/react": "^19.0.8",
     "@types/react-dom": "^19.0.3",
     "@vitejs/plugin-react": "^4.3.4",
diff --git a/examples/react/router-monorepo-simple/packages/router/package.json b/examples/react/router-monorepo-simple/packages/router/package.json
index ce9301cc32..764d532fcf 100644
--- a/examples/react/router-monorepo-simple/packages/router/package.json
+++ b/examples/react/router-monorepo-simple/packages/router/package.json
@@ -9,8 +9,8 @@
   "types": "./dist/index.d.ts",
   "dependencies": {
     "@tanstack/history": "^1.154.14",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "redaxios": "^0.5.1",
     "zod": "^3.24.2",
     "react": "^19.0.0",
diff --git a/examples/react/scroll-restoration/package.json b/examples/react/scroll-restoration/package.json
index c31ad479ee..a152a5cd67 100644
--- a/examples/react/scroll-restoration/package.json
+++ b/examples/react/scroll-restoration/package.json
@@ -10,8 +10,8 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "@tanstack/react-virtual": "^3.13.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
diff --git a/examples/react/search-validator-adapters/package.json b/examples/react/search-validator-adapters/package.json
index 3e5e5b8e7c..963c9c49da 100644
--- a/examples/react/search-validator-adapters/package.json
+++ b/examples/react/search-validator-adapters/package.json
@@ -11,13 +11,13 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/arktype-adapter": "^1.158.0",
+    "@tanstack/arktype-adapter": "^1.160.0",
     "@tanstack/react-query": "^5.90.0",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
-    "@tanstack/valibot-adapter": "^1.158.0",
-    "@tanstack/zod-adapter": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
+    "@tanstack/valibot-adapter": "^1.160.0",
+    "@tanstack/zod-adapter": "^1.160.0",
     "arktype": "^2.1.7",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
diff --git a/examples/react/start-bare/package.json b/examples/react/start-bare/package.json
index b4df5a159d..45bed38665 100644
--- a/examples/react/start-bare/package.json
+++ b/examples/react/start-bare/package.json
@@ -10,9 +10,9 @@
     "start": "pnpx srvx --prod -s ../client dist/server/server.js"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/react-start": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/react-start": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "zod": "^3.24.2"
diff --git a/examples/react/start-basic-auth/package.json b/examples/react/start-basic-auth/package.json
index f4df0c4ecc..9358364210 100644
--- a/examples/react/start-basic-auth/package.json
+++ b/examples/react/start-basic-auth/package.json
@@ -14,9 +14,9 @@
     "@libsql/client": "^0.15.15",
     "@prisma/adapter-libsql": "^7.0.0",
     "@prisma/client": "^7.0.0",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/react-start": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/react-start": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1",
diff --git a/examples/react/start-basic-authjs/package.json b/examples/react/start-basic-authjs/package.json
index 5f4f17d1df..ff77780dfa 100644
--- a/examples/react/start-basic-authjs/package.json
+++ b/examples/react/start-basic-authjs/package.json
@@ -11,9 +11,9 @@
   },
   "dependencies": {
     "@auth/core": "^0.41.1",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/react-start": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/react-start": "^1.160.0",
     "start-authjs": "^1.0.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
diff --git a/examples/react/start-basic-cloudflare/package.json b/examples/react/start-basic-cloudflare/package.json
index d27bfa077e..3967c6185d 100644
--- a/examples/react/start-basic-cloudflare/package.json
+++ b/examples/react/start-basic-cloudflare/package.json
@@ -12,9 +12,9 @@
     "postinstall": "npm run cf-typegen"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/react-start": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/react-start": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0"
   },
diff --git a/examples/react/start-basic-react-query/package.json b/examples/react/start-basic-react-query/package.json
index e4382be0a1..7565e08bf9 100644
--- a/examples/react/start-basic-react-query/package.json
+++ b/examples/react/start-basic-react-query/package.json
@@ -12,10 +12,10 @@
   "dependencies": {
     "@tanstack/react-query": "^5.90.0",
     "@tanstack/react-query-devtools": "^5.90.0",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/react-router-ssr-query": "^1.158.0",
-    "@tanstack/react-start": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/react-router-ssr-query": "^1.160.0",
+    "@tanstack/react-start": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1",
diff --git a/examples/react/start-basic-rsc/package.json b/examples/react/start-basic-rsc/package.json
index b7c9032db6..3db1a9f696 100644
--- a/examples/react/start-basic-rsc/package.json
+++ b/examples/react/start-basic-rsc/package.json
@@ -10,9 +10,9 @@
   },
   "dependencies": {
     "@babel/plugin-syntax-typescript": "^7.25.9",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/react-start": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/react-start": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1",
diff --git a/examples/react/start-basic-static/package.json b/examples/react/start-basic-static/package.json
index bf8da1556a..b13fb18b7d 100644
--- a/examples/react/start-basic-static/package.json
+++ b/examples/react/start-basic-static/package.json
@@ -10,10 +10,10 @@
     "start": "pnpx srvx --prod -s ../client dist/server/server.js"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/react-start": "^1.158.0",
-    "@tanstack/start-static-server-functions": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/react-start": "^1.160.0",
+    "@tanstack/start-static-server-functions": "^1.160.0",
     "@vitejs/plugin-react": "^5.1.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
diff --git a/examples/react/start-basic/package.json b/examples/react/start-basic/package.json
index ffd903b301..1b057e2a6e 100644
--- a/examples/react/start-basic/package.json
+++ b/examples/react/start-basic/package.json
@@ -10,9 +10,9 @@
     "start": "node .output/server/index.mjs"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/react-start": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/react-start": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "tailwind-merge": "^2.6.0",
diff --git a/examples/react/start-bun/package.json b/examples/react/start-bun/package.json
index 6f445507e4..b2a1632bef 100644
--- a/examples/react/start-bun/package.json
+++ b/examples/react/start-bun/package.json
@@ -15,11 +15,11 @@
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/react-devtools": "^0.7.0",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/react-router-ssr-query": "^1.158.0",
-    "@tanstack/react-start": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/react-router-ssr-query": "^1.160.0",
+    "@tanstack/react-start": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "react": "^19.1.1",
     "react-dom": "^19.1.1",
     "tailwindcss": "^4.1.18",
diff --git a/examples/react/start-clerk-basic/package.json b/examples/react/start-clerk-basic/package.json
index 7e6bc9156a..8b7b533d5e 100644
--- a/examples/react/start-clerk-basic/package.json
+++ b/examples/react/start-clerk-basic/package.json
@@ -11,14 +11,14 @@
   },
   "dependencies": {
     "@clerk/tanstack-react-start": "^0.27.14",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/react-start": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/react-start": "^1.160.0",
     "@vitejs/plugin-react": "^4.3.4",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tailwind-merge": "^2.6.0"
   },
   "devDependencies": {
diff --git a/examples/react/start-convex-trellaux/package.json b/examples/react/start-convex-trellaux/package.json
index 7a969caca7..37df6a20f3 100644
--- a/examples/react/start-convex-trellaux/package.json
+++ b/examples/react/start-convex-trellaux/package.json
@@ -15,10 +15,10 @@
     "@convex-dev/react-query": "0.0.0-alpha.8",
     "@tanstack/react-query": "^5.90.0",
     "@tanstack/react-query-devtools": "^5.90.0",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/react-router-ssr-query": "^1.158.0",
-    "@tanstack/react-start": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/react-router-ssr-query": "^1.160.0",
+    "@tanstack/react-start": "^1.160.0",
     "concurrently": "^8.2.2",
     "convex": "^1.19.0",
     "ky": "^1.7.4",
diff --git a/examples/react/start-counter/package.json b/examples/react/start-counter/package.json
index 70269d8f8e..5c8c49c21e 100644
--- a/examples/react/start-counter/package.json
+++ b/examples/react/start-counter/package.json
@@ -10,9 +10,9 @@
     "start": "pnpx srvx --prod -s ../client dist/server/server.js"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/react-start": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/react-start": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0"
   },
diff --git a/examples/react/start-i18n-paraglide/package.json b/examples/react/start-i18n-paraglide/package.json
index b1131759b6..62b388cd5e 100644
--- a/examples/react/start-i18n-paraglide/package.json
+++ b/examples/react/start-i18n-paraglide/package.json
@@ -10,9 +10,9 @@
   },
   "dependencies": {
     "@tanstack/react-devtools": "^0.7.0",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/react-start": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/react-start": "^1.160.0",
     "react": "^19.1.1",
     "react-dom": "^19.1.1"
   },
diff --git a/examples/react/start-large/package.json b/examples/react/start-large/package.json
index 28c2704ac1..d89aae7061 100644
--- a/examples/react/start-large/package.json
+++ b/examples/react/start-large/package.json
@@ -13,9 +13,9 @@
   },
   "dependencies": {
     "@tanstack/react-query": "^5.90.0",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/react-start": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/react-start": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1",
diff --git a/examples/react/start-material-ui/package.json b/examples/react/start-material-ui/package.json
index 7ffdaad0d2..0c58e130d2 100644
--- a/examples/react/start-material-ui/package.json
+++ b/examples/react/start-material-ui/package.json
@@ -15,9 +15,9 @@
     "@emotion/styled": "11.14.0",
     "@fontsource-variable/roboto": "5.2.5",
     "@mui/material": "6.4.7",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-start": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-start": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "zod": "^3.24.2"
diff --git a/examples/react/start-streaming-data-from-server-functions/package.json b/examples/react/start-streaming-data-from-server-functions/package.json
index c4ac49ab90..f8521616fd 100644
--- a/examples/react/start-streaming-data-from-server-functions/package.json
+++ b/examples/react/start-streaming-data-from-server-functions/package.json
@@ -10,9 +10,9 @@
     "start": "pnpx srvx --prod -s ../client dist/server/server.js"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/react-start": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/react-start": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "zod": "^3.24.2"
diff --git a/examples/react/start-supabase-basic/package.json b/examples/react/start-supabase-basic/package.json
index 006451707f..c3ef12a901 100644
--- a/examples/react/start-supabase-basic/package.json
+++ b/examples/react/start-supabase-basic/package.json
@@ -15,9 +15,9 @@
   "dependencies": {
     "@supabase/ssr": "^0.5.2",
     "@supabase/supabase-js": "^2.48.1",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/react-start": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/react-start": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1"
diff --git a/examples/react/start-tailwind-v4/package.json b/examples/react/start-tailwind-v4/package.json
index d9a45e598f..8d303a4c4a 100644
--- a/examples/react/start-tailwind-v4/package.json
+++ b/examples/react/start-tailwind-v4/package.json
@@ -10,9 +10,9 @@
     "start": "node .output/server/index.mjs"
   },
   "dependencies": {
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/react-start": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/react-start": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "tailwind-merge": "^2.6.0",
diff --git a/examples/react/start-trellaux/package.json b/examples/react/start-trellaux/package.json
index ecac61acaf..522d9f50a7 100644
--- a/examples/react/start-trellaux/package.json
+++ b/examples/react/start-trellaux/package.json
@@ -12,10 +12,10 @@
   "dependencies": {
     "@tanstack/react-query": "^5.90.0",
     "@tanstack/react-query-devtools": "^5.90.0",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/react-router-ssr-query": "^1.158.0",
-    "@tanstack/react-start": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/react-router-ssr-query": "^1.160.0",
+    "@tanstack/react-start": "^1.160.0",
     "ky": "^1.7.4",
     "msw": "^2.7.0",
     "react": "^19.0.0",
diff --git a/examples/react/start-workos/package.json b/examples/react/start-workos/package.json
index a9a33c55c7..5a3859c3b4 100644
--- a/examples/react/start-workos/package.json
+++ b/examples/react/start-workos/package.json
@@ -13,13 +13,11 @@
   "author": "",
   "license": "MIT",
   "dependencies": {
-    "@radix-ui/themes": "^3.2.1",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/react-start": "^1.158.0",
-    "@workos-inc/node": "^7.45.0",
-    "iron-session": "^8.0.4",
-    "jose": "^6.0.10",
+    "@radix-ui/themes": "^3.3.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/react-start": "^1.160.0",
+    "@workos/authkit-tanstack-react-start": "^0.5.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0"
   },
diff --git a/examples/react/start-workos/src/app.css b/examples/react/start-workos/src/app.css
new file mode 100644
index 0000000000..e544efd1a3
--- /dev/null
+++ b/examples/react/start-workos/src/app.css
@@ -0,0 +1 @@
+@import '@radix-ui/themes/styles.css';
diff --git a/examples/react/start-workos/src/authkit/serverFunctions.ts b/examples/react/start-workos/src/authkit/serverFunctions.ts
deleted file mode 100644
index 07d5909f8b..0000000000
--- a/examples/react/start-workos/src/authkit/serverFunctions.ts
+++ /dev/null
@@ -1,45 +0,0 @@
-import { createServerFn } from '@tanstack/react-start';
-import { deleteCookie } from '@tanstack/react-start/server';
-import { getConfig } from './ssr/config';
-import { terminateSession, withAuth } from './ssr/session';
-import { getWorkOS } from './ssr/workos';
-import type { GetAuthURLOptions, NoUserInfo, UserInfo } from './ssr/interfaces';
-
-export const getAuthorizationUrl = createServerFn({ method: 'GET' })
-  .inputValidator((options?: GetAuthURLOptions) => options)
-  .handler(({ data: options = {} }) => {
-    const { returnPathname, screenHint, redirectUri } = options;
-
-    return getWorkOS().userManagement.getAuthorizationUrl({
-      provider: 'authkit',
-      clientId: getConfig('clientId'),
-      redirectUri: redirectUri || getConfig('redirectUri'),
-      state: returnPathname ? btoa(JSON.stringify({ returnPathname })) : undefined,
-      screenHint,
-    });
-  });
-
-export const getSignInUrl = createServerFn({ method: 'GET' })
-  .inputValidator((data?: string) => data)
-  .handler(async ({ data: returnPathname }) => {
-    return await getAuthorizationUrl({ data: { returnPathname, screenHint: 'sign-in' } });
-  });
-
-export const getSignUpUrl = createServerFn({ method: 'GET' })
-  .inputValidator((data?: string) => data)
-  .handler(async ({ data: returnPathname }) => {
-    return getAuthorizationUrl({ data: { returnPathname, screenHint: 'sign-up' } });
-  });
-
-export const signOut = createServerFn({ method: 'POST' })
-  .inputValidator((data?: string) => data)
-  .handler(async ({ data: returnTo }) => {
-    const cookieName = getConfig('cookieName') || 'wos_session';
-    deleteCookie(cookieName);
-    await terminateSession({ returnTo });
-  });
-
-export const getAuth = createServerFn({ method: 'GET' }).handler(async (): Promise<UserInfo | NoUserInfo> => {
-  const auth = await withAuth();
-  return auth;
-});
diff --git a/examples/react/start-workos/src/authkit/ssr/config.ts b/examples/react/start-workos/src/authkit/ssr/config.ts
deleted file mode 100644
index e815e54cea..0000000000
--- a/examples/react/start-workos/src/authkit/ssr/config.ts
+++ /dev/null
@@ -1,162 +0,0 @@
-import { lazy } from './utils.js';
-import type { AuthKitConfig } from './interfaces.js';
-
-type ValueSource = Record<string, any> | ((key: string) => any);
-
-/**
- * Default environment variable source that uses process.env
- */
-const defaultSource: ValueSource = (key: string): string | undefined => {
-  try {
-    return process.env[key];
-  } catch {
-    return undefined;
-  }
-};
-
-/**
- * Configuration class for AuthKit.
- * This class is used to manage configuration values and provide defaults.
- * It also provides a way to get configuration values from environment variables.
- * @internal
- */
-export class Configuration {
-  private config: Partial<AuthKitConfig> = {
-    cookieName: 'wos-session',
-    apiHttps: true,
-    // Defaults to 400 days, the maximum allowed by Chrome
-    // It's fine to have a long cookie expiry date as the access/refresh tokens
-    // act as the actual time-limited aspects of the session.
-    cookieMaxAge: 60 * 60 * 24 * 400,
-    apiHostname: 'api.workos.com',
-  };
-
-  private valueSource: ValueSource = defaultSource;
-
-  private readonly requiredKeys: Array<keyof AuthKitConfig> = ['clientId', 'apiKey', 'redirectUri', 'cookiePassword'];
-
-  /**
-   * Convert a camelCase string to an uppercase, underscore-separated environment variable name.
-   * @param str The string to convert
-   * @returns The environment variable name
-   */
-  protected getEnvironmentVariableName(str: string) {
-    return `WORKOS_${str.replace(/([a-z])([A-Z])/g, '$1_$2').toUpperCase()}`;
-  }
-
-  private updateConfig(config: Partial<AuthKitConfig>): void {
-    this.config = { ...this.config, ...config };
-  }
-
-  setValueSource(source: ValueSource): void {
-    this.valueSource = source;
-  }
-
-  configure(configOrSource: Partial<AuthKitConfig> | ValueSource, source?: ValueSource): void {
-    if (typeof configOrSource === 'function') {
-      this.setValueSource(configOrSource);
-    } else if (typeof configOrSource === 'object' && !source) {
-      this.updateConfig(configOrSource);
-    } else if (typeof configOrSource === 'object' && source) {
-      this.updateConfig(configOrSource);
-      this.setValueSource(source);
-    }
-
-    // Validate the cookiePassword if provided
-    if (this.config.cookiePassword && this.config.cookiePassword.length < 32) {
-      throw new Error('cookiePassword must be at least 32 characters long');
-    }
-  }
-
-  getValue<T extends keyof AuthKitConfig>(key: T): AuthKitConfig[T] {
-    // First check environment variables
-    const envKey = this.getEnvironmentVariableName(key);
-    let envValue: AuthKitConfig[T] | undefined = undefined;
-
-    const { valueSource, config } = this;
-    if (typeof valueSource === 'function') {
-      envValue = valueSource(envKey);
-    } else {
-      envValue = valueSource[envKey];
-    }
-
-    // If environment variable exists, use it
-    if (envValue != null) {
-      // Convert string values to appropriate types
-      if (key === 'apiHttps' && typeof envValue === 'string') {
-        return (envValue === 'true') as AuthKitConfig[T];
-      }
-
-      if ((key === 'apiPort' || key === 'cookieMaxAge') && typeof envValue === 'string') {
-        const num = parseInt(envValue, 10);
-        return (isNaN(num) ? undefined : num) as AuthKitConfig[T];
-      }
-
-      return envValue as AuthKitConfig[T];
-    }
-
-    // Then check programmatically provided config
-    if (key in config && config[key] != undefined) {
-      return config[key] as AuthKitConfig[T];
-    }
-
-    if (this.requiredKeys.includes(key)) {
-      throw new Error(`Missing required configuration value for ${key} (${envKey}).`);
-    }
-
-    return undefined as AuthKitConfig[T];
-  }
-}
-
-// lazy-instantiate the Configuration instance
-const getConfigurationInstance = lazy(() => new Configuration());
-
-/**
- * Configure AuthKit with a custom value source.
- * @param source The source of configuration values
- *
- * @example
- * configure(key => Deno.env.get(key));
- */
-export function configure(source: ValueSource): void;
-/**
- * Configure AuthKit with custom values.
- * @param config The configuration values
- *
- * @example
- * configure({
- *    clientId: 'your-client-id',
- *    redirectUri: 'https://your-app.com/auth/callback',
- *    apiKey: 'your-api-key',
- *    cookiePassword: 'your-cookie-password',
- *  });
- */
-export function configure(config: Partial<AuthKitConfig>): void;
-/**
- * Configure AuthKit with custom values and a custom value source.
- * @param config The configuration values
- * @param source The source of configuration values
- *
- * @example
- * configure({
- *   clientId: 'your-client-id',
- * }, env);
- */
-export function configure(config: Partial<AuthKitConfig>, source: ValueSource): void;
-export function configure(configOrSource: Partial<AuthKitConfig> | ValueSource, source?: ValueSource): void {
-  const config = getConfigurationInstance();
-  config.configure(configOrSource, source);
-}
-
-/**
- * Get a configuration value by key.
- * This function will first check environment variables, then programmatically provided config,
- * and finally fall back to defaults for optional settings.
- * If a required setting is missing, an error will be thrown.
- * @param key The configuration key
- * @returns The configuration value
- */
-export function getConfig<T extends keyof AuthKitConfig>(key: T): AuthKitConfig[T] {
-  const config = getConfigurationInstance();
-  return config.getValue(key);
-}
diff --git a/examples/react/start-workos/src/authkit/ssr/interfaces.ts b/examples/react/start-workos/src/authkit/ssr/interfaces.ts
deleted file mode 100644
index bd17a17d56..0000000000
--- a/examples/react/start-workos/src/authkit/ssr/interfaces.ts
+++ /dev/null
@@ -1,137 +0,0 @@
-import type { Impersonator, User } from '@workos-inc/node';
-
-export interface GetAuthURLOptions {
-  redirectUri?: string;
-  screenHint?: 'sign-up' | 'sign-in';
-  returnPathname?: string;
-}
-
-export interface CookieOptions {
-  path: '/';
-  httpOnly: true;
-  secure: boolean;
-  sameSite: 'lax' | 'strict' | 'none';
-  maxAge: number;
-  domain: string | undefined;
-}
-
-export interface UserInfo {
-  user: User;
-  sessionId: string;
-  organizationId?: string;
-  role?: string;
-  permissions?: Array<string>;
-  entitlements?: Array<string>;
-  impersonator?: Impersonator;
-  accessToken: string;
-}
-export interface NoUserInfo {
-  user: null;
-  sessionId?: undefined;
-  organizationId?: undefined;
-  role?: undefined;
-  permissions?: undefined;
-  entitlements?: undefined;
-  impersonator?: undefined;
-  accessToken?: undefined;
-}
-
-export interface AuthkitOptions {
-  debug?: boolean;
-  redirectUri?: string;
-  screenHint?: 'sign-up' | 'sign-in';
-}
-
-export interface AuthkitResponse {
-  session: UserInfo | NoUserInfo;
-  headers: Headers;
-  authorizationUrl?: string;
-}
-
-/**
- * AuthKit Session
- */
-export interface Session {
-  /**
-   * The session access token
-   */
-  accessToken: string;
-  /**
-   * The session refresh token - used to refresh the access token
-   */
-  refreshToken: string;
-  /**
-   * The logged-in user
-   */
-  user: User;
-  /**
-   * The impersonator user, if any
-   */
-  impersonator?: Impersonator;
-}
-
-/**
- * AuthKit Configuration Options
- */
-export interface AuthKitConfig {
-  /**
-   * The WorkOS Client ID
-   * Equivalent to the WORKOS_CLIENT_ID environment variable
-   */
-  clientId: string;
-
-  /**
-   * The WorkOS API Key
-   * Equivalent to the WORKOS_API_KEY environment variable
-   */
-  apiKey: string;
-
-  /**
-   * The redirect URI for the authentication callback
-   * Equivalent to the WORKOS_REDIRECT_URI environment variable
-   */
-  redirectUri: string;
-
-  /**
-   * The password used to encrypt the session cookie
-   * Equivalent to the WORKOS_COOKIE_PASSWORD environment variable
-   * Must be at least 32 characters long
-   */
-  cookiePassword: string;
-
-  /**
-   * The hostname of the API to use
-   * Equivalent to the WORKOS_API_HOSTNAME environment variable
-   */
-  apiHostname?: string;
-
-  /**
-   * Whether to use HTTPS for API requests
-   * Equivalent to the WORKOS_API_HTTPS environment variable
-   */
-  apiHttps: boolean;
-
-  /**
-   * The port to use for the API
-   * Equivalent to the WORKOS_API_PORT environment variable
-   */
-  apiPort?: number;
-
-  /**
-   * The maximum age of the session cookie in seconds
-   * Equivalent to the WORKOS_COOKIE_MAX_AGE environment variable
-   */
-  cookieMaxAge: number;
-
-  /**
-   * The name of the session cookie
-   * Equivalent to the WORKOS_COOKIE_NAME environment variable
-   * Defaults to "wos-session"
-   */
-  cookieName: string;
-
-  /**
-   * The domain for the session cookie
-   */
-  cookieDomain?: string;
-}
diff --git a/examples/react/start-workos/src/authkit/ssr/session.ts b/examples/react/start-workos/src/authkit/ssr/session.ts
deleted file mode 100644
index 1c58b6736d..0000000000
--- a/examples/react/start-workos/src/authkit/ssr/session.ts
+++ /dev/null
@@ -1,268 +0,0 @@
-import { redirect } from '@tanstack/react-router';
-import { getCookie, setCookie } from '@tanstack/react-start/server';
-import { sealData, unsealData } from 'iron-session';
-import { createRemoteJWKSet, decodeJwt, jwtVerify } from 'jose';
-import { getConfig } from './config';
-import { lazy } from './utils';
-import { getWorkOS } from './workos';
-import type { AccessToken, AuthenticationResponse } from '@workos-inc/node';
-import type { AuthkitOptions, AuthkitResponse, CookieOptions, GetAuthURLOptions, Session } from './interfaces';
-
-const sessionHeaderName = 'x-workos-session';
-const middlewareHeaderName = 'x-workos-middleware';
-
-export function getAuthorizationUrl(options: GetAuthURLOptions = {}) {
-  const { returnPathname, screenHint, redirectUri } = options;
-
-  return getWorkOS().userManagement.getAuthorizationUrl({
-    provider: 'authkit',
-    clientId: getConfig('clientId'),
-    redirectUri: redirectUri || getConfig('redirectUri'),
-    state: returnPathname ? btoa(JSON.stringify({ returnPathname })) : undefined,
-    screenHint,
-  });
-}
-
-export function serializeCookie(name: string, value: string, options: Partial<CookieOptions> = {}): string {
-  const {
-    path = '/',
-    maxAge = getConfig('cookieMaxAge'),
-    secure = options.sameSite === 'none' ? true : getConfig('redirectUri').startsWith('https:'),
-    sameSite = 'lax',
-    domain = getConfig('cookieDomain'),
-  } = options;
-
-  let cookie = `${name}=${encodeURIComponent(value)}; Path=${path}; sameSite=${sameSite}; HttpOnly`;
-  cookie += `; Max-Age=${maxAge}`;
-  if (!maxAge) cookie += `; Expires=${new Date(0).toUTCString()}`;
-  if (secure) cookie += '; Secure';
-  if (domain) cookie += `; Domain=${domain}`;
-
-  return cookie;
-}
-
-export async function decryptSession(encryptedSession: string): Promise<Session> {
-  const cookiePassword = getConfig('cookiePassword');
-  return unsealData<Session>(encryptedSession, {
-    password: cookiePassword,
-  });
-}
-
-export async function encryptSession(session: Session) {
-  return sealData(session, {
-    password: getConfig('cookiePassword'),
-    ttl: 0,
-  });
-}
-
-export async function withAuth() {
-  const session = await getSessionFromCookie();
-
-  if (!session?.user) {
-    return { user: null };
-  }
-
-  const {
-    sid: sessionId,
-    org_id: organizationId,
-    role,
-    permissions,
-    entitlements,
-  } = decodeJwt<AccessToken>(session.accessToken);
-
-  return {
-    sessionId,
-    user: session.user,
-    organizationId,
-    role,
-    permissions,
-    entitlements,
-    impersonator: session.impersonator,
-    accessToken: session.accessToken,
-  };
-}
-
-export async function getSessionFromCookie() {
-  const cookieName = getConfig('cookieName') || 'wos-session';
-  const cookie = getCookie(cookieName);
-
-  if (cookie) {
-    return decryptSession(cookie);
-  }
-}
-
-export async function saveSession(sessionOrResponse: Session | AuthenticationResponse): Promise<void> {
-  const cookieName = getConfig('cookieName') || 'wos-session';
-  const encryptedSession = await encryptSession(sessionOrResponse);
-  setCookie(cookieName, encryptedSession);
-}
-
-// JWKS call only happens once and the result is cached. The lazy function ensures that
-// the JWK set is only created when it's needed, and not before.
-const JWKS = lazy(() => createRemoteJWKSet(new URL(getWorkOS().userManagement.getJwksUrl(getConfig('clientId')))));
-
-async function verifyAccessToken(accessToken: string): Promise<boolean> {
-  try {
-    await jwtVerify(accessToken, JWKS());
-    return true;
-  } catch {
-    return false;
-  }
-}
-
-function getReturnPathname(url: string): string {
-  const newUrl = new URL(url);
-
-  return `${newUrl.pathname}${newUrl.searchParams.size > 0 ? '?' + newUrl.searchParams.toString() : ''}`;
-}
-
-export async function updateSession(
-  request: Request,
-  options: AuthkitOptions = { debug: false },
-): Promise<AuthkitResponse> {
-  const session = await getSessionFromCookie();
-
-  const newRequestHeaders = new Headers();
-
-  // Record that the request was routed through the middleware so we can check later for DX purposes
-  newRequestHeaders.set(middlewareHeaderName, 'true');
-
-  // We store the current request url in a custom header, so we can always have access to it
-  // This is because on hard navigations we don't have access to `next-url` but need to get the current
-  // `pathname` to be able to return the users where they came from before sign-in
-  newRequestHeaders.set('x-url', request.url);
-
-  if (options.redirectUri) {
-    // Store the redirect URI in a custom header, so we always have access to it and so that subsequent
-    // calls to `getAuthorizationUrl` will use the same redirect URI
-    newRequestHeaders.set('x-redirect-uri', options.redirectUri);
-  }
-
-  newRequestHeaders.delete(sessionHeaderName);
-
-  if (!session) {
-    if (options.debug) {
-      console.log('No session found from cookie');
-    }
-
-    return {
-      session: { user: null },
-      headers: newRequestHeaders,
-      authorizationUrl: getAuthorizationUrl({
-        returnPathname: getReturnPathname(request.url),
-        redirectUri: options.redirectUri || getConfig('redirectUri'),
-        screenHint: options.screenHint,
-      }),
-    };
-  }
-
-  const hasValidSession = await verifyAccessToken(session.accessToken);
-
-  const cookieName = getConfig('cookieName') || 'wos-session';
-
-  if (hasValidSession) {
-    newRequestHeaders.set(sessionHeaderName, getCookie(cookieName)!);
-
-    const {
-      sid: sessionId,
-      org_id: organizationId,
-      role,
-      permissions,
-      entitlements,
-    } = decodeJwt<AccessToken>(session.accessToken);
-
-    return {
-      session: {
-        sessionId,
-        user: session.user,
-        organizationId,
-        role,
-        permissions,
-        entitlements,
-        impersonator: session.impersonator,
-        accessToken: session.accessToken,
-      },
-      headers: newRequestHeaders,
-    };
-  }
-
-  try {
-    if (options.debug) {
-      // istanbul ignore next
-      console.log(
-        `Session invalid. ${session.accessToken ? `Refreshing access token that ends in ${session.accessToken.slice(-10)}` : 'Access token missing.'}`,
-      );
-    }
-
-    const { org_id: organizationIdFromAccessToken } = decodeJwt<AccessToken>(session.accessToken);
-
-    const { accessToken, refreshToken, user, impersonator } =
-      await getWorkOS().userManagement.authenticateWithRefreshToken({
-        clientId: getConfig('clientId'),
-        refreshToken: session.refreshToken,
-        organizationId: organizationIdFromAccessToken,
-      });
-
-    if (options.debug) {
-      console.log('Session successfully refreshed');
-    }
-    // Encrypt session with new access and refresh tokens
-    const encryptedSession = await encryptSession({
-      accessToken,
-      refreshToken,
-      user,
-      impersonator,
-    });
-
-    newRequestHeaders.append('Set-Cookie', serializeCookie(cookieName, encryptedSession));
-    newRequestHeaders.set(sessionHeaderName, encryptedSession);
-
-    const {
-      sid: sessionId,
-      org_id: organizationId,
-      role,
-      permissions,
-      entitlements,
-    } = decodeJwt<AccessToken>(accessToken);
-
-    return {
-      session: {
-        sessionId,
-        user,
-        organizationId,
-        role,
-        permissions,
-        entitlements,
-        impersonator,
-        accessToken,
-      },
-      headers: newRequestHeaders,
-    };
-  } catch (e) {
-    if (options.debug) {
-      console.log('Failed to refresh. Deleting cookie.', e);
-    }
-
-    // When we need to delete a cookie, return it as a header as you can't delete cookies from edge middleware
-    const deleteCookie = serializeCookie(cookieName, '', { maxAge: 0 });
-    newRequestHeaders.append('Set-Cookie', deleteCookie);
-
-    return {
-      session: { user: null },
-      headers: newRequestHeaders,
-      authorizationUrl: getAuthorizationUrl({
-        returnPathname: getReturnPathname(request.url),
-      }),
-    };
-  }
-}
-
-export async function terminateSession({ returnTo }: { returnTo?: string } = {}) {
-  const { sessionId } = await withAuth();
-  if (sessionId) {
-    const href = getWorkOS().userManagement.getLogoutUrl({ sessionId, returnTo });
-    return redirect({ href, throw: true, reloadDocument: true });
-  }
-
-  return redirect({ to: returnTo ?? '/', throw: true, reloadDocument: true });
-}
diff --git a/examples/react/start-workos/src/authkit/ssr/utils.ts b/examples/react/start-workos/src/authkit/ssr/utils.ts
deleted file mode 100644
index 73b807cb56..0000000000
--- a/examples/react/start-workos/src/authkit/ssr/utils.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- * Returns a function that can only be called once.
- * Subsequent calls will return the result of the first call.
- * This is useful for lazy initialization.
- * @param fn - The function to be called once.
- * @returns A function that can only be called once.
- */
-export function lazy<T>(fn: () => T): () => T {
-  let called = false;
-  let result: T;
-  return () => {
-    if (!called) {
-      result = fn();
-      called = true;
-    }
-    return result;
-  };
-}
diff --git a/examples/react/start-workos/src/authkit/ssr/workos.ts b/examples/react/start-workos/src/authkit/ssr/workos.ts
deleted file mode 100644
index b310799210..0000000000
--- a/examples/react/start-workos/src/authkit/ssr/workos.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { WorkOS } from '@workos-inc/node';
-import { getConfig } from './config';
-import { lazy } from './utils';
-
-/**
- * Create a WorkOS instance with the provided API key and optional settings.
- */
-export function createWorkOSInstance() {
-  // Get required API key from config
-  const apiKey = getConfig('apiKey');
-
-  // Get optional settings
-  const apiHostname = getConfig('apiHostname');
-  const apiHttps = getConfig('apiHttps');
-  const apiPort = getConfig('apiPort');
-
-  const options = {
-    apiHostname,
-    https: apiHttps,
-    port: apiPort,
-  };
-
-  // Initialize the WorkOS client with config values
-  const workos = new WorkOS(apiKey, options);
-
-  return workos;
-}
-
-/**
- * Create a WorkOS instance with the provided API key and optional settings.
- * This function is lazy loaded to avoid loading the WorkOS SDK when it's not needed.
- */
-export const getWorkOS = lazy(createWorkOSInstance);
diff --git a/examples/react/start-workos/src/components/sign-in-button.tsx b/examples/react/start-workos/src/components/sign-in-button.tsx
index 93da26b40c..ba03fa02f0 100644
--- a/examples/react/start-workos/src/components/sign-in-button.tsx
+++ b/examples/react/start-workos/src/components/sign-in-button.tsx
@@ -1,13 +1,15 @@
 import { Button, Flex } from '@radix-ui/themes';
 import { Link } from '@tanstack/react-router';
-import type { User } from '@workos-inc/node';
+import type { User } from '@workos/authkit-tanstack-react-start';
 
 export default function SignInButton({ large, user, url }: { large?: boolean; user: User | null; url: string }) {
   if (user) {
     return (
       <Flex gap="3">
         <Button asChild size={large ? '3' : '2'}>
-          <Link to="/logout">Sign Out</Link>
+          <Link to="/logout" reloadDocument>
+            Sign Out
+          </Link>
         </Button>
       </Flex>
     );
diff --git a/examples/react/start-workos/src/routeTree.gen.ts b/examples/react/start-workos/src/routeTree.gen.ts
index 8e275a0f1b..49009fc848 100644
--- a/examples/react/start-workos/src/routeTree.gen.ts
+++ b/examples/react/start-workos/src/routeTree.gen.ts
@@ -10,6 +10,7 @@
 
 import { Route as rootRouteImport } from './routes/__root'
 import { Route as LogoutRouteImport } from './routes/logout'
+import { Route as ClientRouteImport } from './routes/client'
 import { Route as AuthenticatedRouteImport } from './routes/_authenticated'
 import { Route as IndexRouteImport } from './routes/index'
 import { Route as AuthenticatedAccountRouteImport } from './routes/_authenticated/account'
@@ -20,6 +21,11 @@ const LogoutRoute = LogoutRouteImport.update({
   path: '/logout',
   getParentRoute: () => rootRouteImport,
 } as any)
+const ClientRoute = ClientRouteImport.update({
+  id: '/client',
+  path: '/client',
+  getParentRoute: () => rootRouteImport,
+} as any)
 const AuthenticatedRoute = AuthenticatedRouteImport.update({
   id: '/_authenticated',
   getParentRoute: () => rootRouteImport,
@@ -42,12 +48,14 @@ const ApiAuthCallbackRoute = ApiAuthCallbackRouteImport.update({
 
 export interface FileRoutesByFullPath {
   '/': typeof IndexRoute
+  '/client': typeof ClientRoute
   '/logout': typeof LogoutRoute
   '/account': typeof AuthenticatedAccountRoute
   '/api/auth/callback': typeof ApiAuthCallbackRoute
 }
 export interface FileRoutesByTo {
   '/': typeof IndexRoute
+  '/client': typeof ClientRoute
   '/logout': typeof LogoutRoute
   '/account': typeof AuthenticatedAccountRoute
   '/api/auth/callback': typeof ApiAuthCallbackRoute
@@ -56,19 +64,21 @@ export interface FileRoutesById {
   __root__: typeof rootRouteImport
   '/': typeof IndexRoute
   '/_authenticated': typeof AuthenticatedRouteWithChildren
+  '/client': typeof ClientRoute
   '/logout': typeof LogoutRoute
   '/_authenticated/account': typeof AuthenticatedAccountRoute
   '/api/auth/callback': typeof ApiAuthCallbackRoute
 }
 export interface FileRouteTypes {
   fileRoutesByFullPath: FileRoutesByFullPath
-  fullPaths: '/' | '/logout' | '/account' | '/api/auth/callback'
+  fullPaths: '/' | '/client' | '/logout' | '/account' | '/api/auth/callback'
   fileRoutesByTo: FileRoutesByTo
-  to: '/' | '/logout' | '/account' | '/api/auth/callback'
+  to: '/' | '/client' | '/logout' | '/account' | '/api/auth/callback'
   id:
     | '__root__'
     | '/'
     | '/_authenticated'
+    | '/client'
     | '/logout'
     | '/_authenticated/account'
     | '/api/auth/callback'
@@ -77,6 +87,7 @@ export interface FileRouteTypes {
 export interface RootRouteChildren {
   IndexRoute: typeof IndexRoute
   AuthenticatedRoute: typeof AuthenticatedRouteWithChildren
+  ClientRoute: typeof ClientRoute
   LogoutRoute: typeof LogoutRoute
   ApiAuthCallbackRoute: typeof ApiAuthCallbackRoute
 }
@@ -90,10 +101,17 @@ declare module '@tanstack/react-router' {
       preLoaderRoute: typeof LogoutRouteImport
       parentRoute: typeof rootRouteImport
     }
+    '/client': {
+      id: '/client'
+      path: '/client'
+      fullPath: '/client'
+      preLoaderRoute: typeof ClientRouteImport
+      parentRoute: typeof rootRouteImport
+    }
     '/_authenticated': {
       id: '/_authenticated'
       path: ''
-      fullPath: ''
+      fullPath: '/'
       preLoaderRoute: typeof AuthenticatedRouteImport
       parentRoute: typeof rootRouteImport
     }
@@ -136,6 +154,7 @@ const AuthenticatedRouteWithChildren = AuthenticatedRoute._addFileChildren(
 const rootRouteChildren: RootRouteChildren = {
   IndexRoute: IndexRoute,
   AuthenticatedRoute: AuthenticatedRouteWithChildren,
+  ClientRoute: ClientRoute,
   LogoutRoute: LogoutRoute,
   ApiAuthCallbackRoute: ApiAuthCallbackRoute,
 }
@@ -144,10 +163,11 @@ export const routeTree = rootRouteImport
   ._addFileTypes<FileRouteTypes>()
 
 import type { getRouter } from './router.tsx'
-import type { createStart } from '@tanstack/react-start'
+import type { startInstance } from './start.ts'
 declare module '@tanstack/react-start' {
   interface Register {
     ssr: true
     router: Awaited<ReturnType<typeof getRouter>>
+    config: Awaited<ReturnType<typeof startInstance.getOptions>>
   }
 }
diff --git a/examples/react/start-workos/src/routes/__root.tsx b/examples/react/start-workos/src/routes/__root.tsx
index 8cdf0bd5bc..1f0c66c9ff 100644
--- a/examples/react/start-workos/src/routes/__root.tsx
+++ b/examples/react/start-workos/src/routes/__root.tsx
@@ -1,19 +1,15 @@
 import { Box, Button, Card, Container, Flex, Theme } from '@radix-ui/themes';
-import '@radix-ui/themes/styles.css';
 import { HeadContent, Link, Outlet, Scripts, createRootRoute } from '@tanstack/react-router';
 import { TanStackRouterDevtools } from '@tanstack/react-router-devtools';
 import { Suspense } from 'react';
-import { getAuth, getSignInUrl } from '../authkit/serverFunctions';
+import { getSignInUrl } from '@workos/authkit-tanstack-react-start';
+import { AuthKitProvider, getAuthAction } from '@workos/authkit-tanstack-react-start/client';
 import Footer from '../components/footer';
 import SignInButton from '../components/sign-in-button';
+import appCssUrl from '../app.css?url';
 import type { ReactNode } from 'react';
 
 export const Route = createRootRoute({
-  beforeLoad: async () => {
-    const { user } = await getAuth();
-
-    return { user };
-  },
   head: () => ({
     meta: [
       {
@@ -27,12 +23,15 @@ export const Route = createRootRoute({
         title: 'AuthKit Example in TanStack Start',
       },
     ],
+    links: [{ rel: 'stylesheet', href: appCssUrl }],
   }),
-  loader: async ({ context }) => {
-    const { user } = context;
+  loader: async () => {
+    // getAuthAction() returns auth state without accessToken, safe for client
+    // Pass to AuthKitProvider as initialAuth to avoid loading flicker
+    const auth = await getAuthAction();
     const url = await getSignInUrl();
     return {
-      user,
+      auth,
       url,
     };
   },
@@ -41,53 +40,59 @@ export const Route = createRootRoute({
 });
 
 function RootComponent() {
-  const { user, url } = Route.useLoaderData();
+  const { auth, url } = Route.useLoaderData();
   return (
     <RootDocument>
-      <Theme accentColor="iris" panelBackground="solid" style={{ backgroundColor: 'var(--gray-1)' }}>
-        <Container style={{ backgroundColor: 'var(--gray-1)' }}>
-          <Flex direction="column" gap="5" p="5" height="100vh">
-            <Box asChild flexGrow="1">
-              <Card size="4">
-                <Flex direction="column" height="100%">
-                  <Flex asChild justify="between">
-                    <header>
-                      <Flex gap="4">
-                        <Button asChild variant="soft">
-                          <Link to="/">Home</Link>
-                        </Button>
+      <AuthKitProvider initialAuth={auth}>
+        <Theme accentColor="iris" panelBackground="solid" style={{ backgroundColor: 'var(--gray-1)' }}>
+          <Container style={{ backgroundColor: 'var(--gray-1)' }}>
+            <Flex direction="column" gap="5" p="5" height="100vh">
+              <Box asChild flexGrow="1">
+                <Card size="4">
+                  <Flex direction="column" height="100%">
+                    <Flex asChild justify="between">
+                      <header>
+                        <Flex gap="4">
+                          <Button asChild variant="soft">
+                            <Link to="/">Home</Link>
+                          </Button>
 
-                        <Button asChild variant="soft">
-                          <Link to="/account">Account</Link>
-                        </Button>
-                      </Flex>
+                          <Button asChild variant="soft">
+                            <Link to="/account">Account</Link>
+                          </Button>
 
-                      <Suspense fallback={<div>Loading...</div>}>
-                        <SignInButton user={user} url={url} />
-                      </Suspense>
-                    </header>
-                  </Flex>
+                          <Button asChild variant="soft">
+                            <Link to="/client">Client Demo</Link>
+                          </Button>
+                        </Flex>
+
+                        <Suspense fallback={<div>Loading...</div>}>
+                          <SignInButton user={auth.user} url={url} />
+                        </Suspense>
+                      </header>
+                    </Flex>
 
-                  <Flex flexGrow="1" align="center" justify="center">
-                    <main>
-                      <Outlet />
-                    </main>
+                    <Flex flexGrow="1" align="center" justify="center">
+                      <main>
+                        <Outlet />
+                      </main>
+                    </Flex>
                   </Flex>
-                </Flex>
-              </Card>
-            </Box>
-            <Footer />
-          </Flex>
-        </Container>
-      </Theme>
-      <TanStackRouterDevtools position="bottom-right" />
+                </Card>
+              </Box>
+              <Footer />
+            </Flex>
+          </Container>
+        </Theme>
+        <TanStackRouterDevtools position="bottom-right" />
+      </AuthKitProvider>
     </RootDocument>
   );
 }
 
 function RootDocument({ children }: Readonly<{ children: ReactNode }>) {
   return (
-    <html>
+    <html lang="en">
       <head>
         <HeadContent />
       </head>
diff --git a/examples/react/start-workos/src/routes/_authenticated.tsx b/examples/react/start-workos/src/routes/_authenticated.tsx
index 20be3d7f1b..d5de60b4fe 100644
--- a/examples/react/start-workos/src/routes/_authenticated.tsx
+++ b/examples/react/start-workos/src/routes/_authenticated.tsx
@@ -1,11 +1,13 @@
-import { redirect, createFileRoute } from '@tanstack/react-router';
-import { getSignInUrl } from '../authkit/serverFunctions';
+import { createFileRoute, redirect } from '@tanstack/react-router';
+import { getAuth, getSignInUrl } from '@workos/authkit-tanstack-react-start';
 
 export const Route = createFileRoute('/_authenticated')({
-  beforeLoad: async ({ context, location }) => {
-    if (!context.user) {
+  loader: async ({ location }) => {
+    // Loader runs on server (even during client-side navigation via RPC)
+    const { user } = await getAuth();
+    if (!user) {
       const path = location.pathname;
-      const href = await getSignInUrl({ data: path });
+      const href = await getSignInUrl({ data: { returnPathname: path } });
       throw redirect({ href });
     }
   },
diff --git a/examples/react/start-workos/src/routes/_authenticated/account.tsx b/examples/react/start-workos/src/routes/_authenticated/account.tsx
index 5c8b688f92..734daf19da 100644
--- a/examples/react/start-workos/src/routes/_authenticated/account.tsx
+++ b/examples/react/start-workos/src/routes/_authenticated/account.tsx
@@ -1,27 +1,25 @@
 import { createFileRoute } from '@tanstack/react-router';
 import { Box, Flex, Heading, Text, TextField } from '@radix-ui/themes';
-import {} from '@tanstack/react-router';
-import { getAuth } from '../../authkit/serverFunctions';
+import { getAuth } from '@workos/authkit-tanstack-react-start';
 
 export const Route = createFileRoute('/_authenticated/account')({
   component: RouteComponent,
-  loader: async ({ context }) => {
-    const { user } = context;
-    const { role, permissions } = await getAuth();
+  loader: async () => {
+    const auth = await getAuth();
 
     const userFields: Array<[label: string, value: string | undefined]> = [
-      ['First name', user?.firstName ?? ''],
-      ['Last name', user?.lastName ?? ''],
-      ['Email', user?.email],
-      ['Id', user?.id],
+      ['First name', auth.user?.firstName ?? ''],
+      ['Last name', auth.user?.lastName ?? ''],
+      ['Email', auth.user?.email],
+      ['Id', auth.user?.id],
     ];
 
-    if (role) {
-      userFields.push(['Role', role]);
+    if (auth.user && 'role' in auth && auth.role) {
+      userFields.push(['Role', auth.role]);
     }
 
-    if (permissions) {
-      userFields.push(['Permissions', permissions.join(', ')]);
+    if (auth.user && 'permissions' in auth && auth.permissions) {
+      userFields.push(['Permissions', auth.permissions.join(', ')]);
     }
 
     return userFields;
diff --git a/examples/react/start-workos/src/routes/api/auth/callback.tsx b/examples/react/start-workos/src/routes/api/auth/callback.tsx
index 8ba493b7dc..c4cda1ed02 100644
--- a/examples/react/start-workos/src/routes/api/auth/callback.tsx
+++ b/examples/react/start-workos/src/routes/api/auth/callback.tsx
@@ -1,94 +1,10 @@
 import { createFileRoute } from '@tanstack/react-router';
-import { getConfig } from '../../../authkit/ssr/config';
-import { saveSession } from '../../../authkit/ssr/session';
-import { getWorkOS } from '../../../authkit/ssr/workos';
+import { handleCallbackRoute } from '@workos/authkit-tanstack-react-start';
 
 export const Route = createFileRoute('/api/auth/callback')({
   server: {
     handlers: {
-      GET: async ({ request }) => {
-        const url = new URL(request.url);
-        const code = url.searchParams.get('code');
-        const state = url.searchParams.get('state');
-        let returnPathname = state && state !== 'null' ? JSON.parse(atob(state)).returnPathname : null;
-
-        if (code) {
-          try {
-            // Use the code returned to us by AuthKit and authenticate the user with WorkOS
-            const { accessToken, refreshToken, user, impersonator } =
-              await getWorkOS().userManagement.authenticateWithCode({
-                clientId: getConfig('clientId'),
-                code,
-              });
-
-            // If baseURL is provided, use it instead of request.nextUrl
-            // This is useful if the app is being run in a container like docker where
-            // the hostname can be different from the one in the request
-            const url = new URL(request.url);
-
-            // Cleanup params
-            url.searchParams.delete('code');
-            url.searchParams.delete('state');
-
-            // Redirect to the requested path and store the session
-            returnPathname = returnPathname ?? '/';
-
-            // Extract the search params if they are present
-            if (returnPathname.includes('?')) {
-              const newUrl = new URL(returnPathname, 'https://example.com');
-              url.pathname = newUrl.pathname;
-
-              for (const [key, value] of newUrl.searchParams) {
-                url.searchParams.append(key, value);
-              }
-            } else {
-              url.pathname = returnPathname;
-            }
-
-            const response = redirectWithFallback(url.toString());
-
-            if (!accessToken || !refreshToken) throw new Error('response is missing tokens');
-
-            await saveSession({ accessToken, refreshToken, user, impersonator });
-
-            return response;
-          } catch (error) {
-            const errorRes = {
-              error: error instanceof Error ? error.message : String(error),
-            };
-
-            console.error(errorRes);
-
-            return errorResponse();
-          }
-        }
-
-        return errorResponse();
-
-        function errorResponse() {
-          return errorResponseWithFallback({
-            error: {
-              message: 'Something went wrong',
-              description:
-                "Couldn't sign in. If you are not sure what happened, please contact your organization admin.",
-            },
-          });
-        }
-      },
+      GET: handleCallbackRoute(),
     },
   },
 });
-
-function redirectWithFallback(redirectUri: string, headers?: Headers) {
-  const newHeaders = headers ? new Headers(headers) : new Headers();
-  newHeaders.set('Location', redirectUri);
-
-  return new Response(null, { status: 307, headers: newHeaders });
-}
-
-function errorResponseWithFallback(errorBody: { error: { message: string; description: string } }) {
-  return new Response(JSON.stringify(errorBody), {
-    status: 500,
-    headers: { 'Content-Type': 'application/json' },
-  });
-}
diff --git a/examples/react/start-workos/src/routes/client.tsx b/examples/react/start-workos/src/routes/client.tsx
new file mode 100644
index 0000000000..9f785915c2
--- /dev/null
+++ b/examples/react/start-workos/src/routes/client.tsx
@@ -0,0 +1,349 @@
+import { Link, createFileRoute } from '@tanstack/react-router';
+import { Badge, Box, Button, Callout, Code, Flex, Heading, Text, TextField } from '@radix-ui/themes';
+import { useAccessToken, useAuth } from '@workos/authkit-tanstack-react-start/client';
+import { useState } from 'react';
+
+export const Route = createFileRoute('/client')({
+  component: RouteComponent,
+});
+
+function RouteComponent() {
+  const {
+    user,
+    loading,
+    sessionId,
+    organizationId,
+    role,
+    roles,
+    permissions,
+    entitlements,
+    featureFlags,
+    impersonator,
+    signOut,
+    switchToOrganization,
+  } = useAuth();
+  const { accessToken, loading: tokenLoading, error: tokenError, refresh, getAccessToken } = useAccessToken();
+
+  const handleRefreshToken = async () => {
+    try {
+      await refresh();
+    } catch (err) {
+      console.error('Token refresh failed:', err);
+    }
+  };
+
+  const handleGetFreshToken = async () => {
+    try {
+      const token = await getAccessToken();
+      console.log('Fresh token:', token);
+    } catch (err) {
+      console.error('Get fresh token failed:', err);
+    }
+  };
+
+  const handleClientSignOut = async () => {
+    console.log('🧪 Testing client-side signOut() from useAuth()...');
+    try {
+      await signOut({ returnTo: '/' });
+      console.log('✅ signOut() completed');
+    } catch (err) {
+      console.error('❌ signOut() failed:', err);
+    }
+  };
+
+  const [orgIdInput, setOrgIdInput] = useState('');
+  const [switchOrgResult, setSwitchOrgResult] = useState<string | null>(null);
+
+  const handleSwitchOrg = async () => {
+    if (!orgIdInput.trim()) {
+      setSwitchOrgResult('Please enter an organization ID');
+      return;
+    }
+
+    console.log(`🔄 Switching to organization: ${orgIdInput}...`);
+    setSwitchOrgResult(null);
+
+    try {
+      const result = await switchToOrganization(orgIdInput.trim());
+      if (result && 'error' in result) {
+        console.error('❌ Switch failed:', result.error);
+        setSwitchOrgResult(`Error: ${result.error}`);
+      } else {
+        console.log('✅ Successfully switched organizations');
+        setSwitchOrgResult('✅ Success! Check updated claims above.');
+      }
+    } catch (err) {
+      const message = err instanceof Error ? err.message : String(err);
+      console.error('❌ Switch error:', message);
+      setSwitchOrgResult(`Error: ${message}`);
+    }
+  };
+
+  if (loading) {
+    return (
+      <Flex direction="column" gap="2" align="center">
+        <Heading size="8">Loading...</Heading>
+      </Flex>
+    );
+  }
+
+  if (!user) {
+    return (
+      <Flex direction="column" gap="4" align="center" maxWidth="600px">
+        <Heading size="8" align="center">
+          Client-Side Hooks Demo
+        </Heading>
+        <Text size="5" align="center" color="gray">
+          This page demonstrates the client-side hooks from <Code>@workos/authkit-tanstack-start/client</Code>
+        </Text>
+        <Callout.Root>
+          <Callout.Text>ℹ️ Please sign in to see the client-side hooks in action.</Callout.Text>
+        </Callout.Root>
+      </Flex>
+    );
+  }
+
+  return (
+    <Flex direction="column" gap="5" maxWidth="800px">
+      <Flex direction="column" gap="2" mb="2">
+        <Heading size="8" align="center">
+          Client-Side Hooks Demo
+        </Heading>
+        <Text size="5" align="center" color="gray">
+          Using <Code>useAuth()</Code> and <Code>useAccessToken()</Code>
+        </Text>
+      </Flex>
+
+      <Callout.Root>
+        <Callout.Text>
+          ℹ️ This page uses client-side React hooks to access authentication data. Unlike server-side loaders, these
+          hooks work in client components and automatically update when auth state changes.
+        </Callout.Text>
+      </Callout.Root>
+
+      <Flex direction="column" gap="3">
+        <Heading size="5">useAuth() Hook</Heading>
+        <Flex direction="column" gap="2">
+          <Flex align="center" gap="2">
+            <Text weight="bold" style={{ width: 150 }}>
+              User ID:
+            </Text>
+            <TextField.Root value={user.id} readOnly style={{ flexGrow: 1 }} />
+          </Flex>
+          <Flex align="center" gap="2">
+            <Text weight="bold" style={{ width: 150 }}>
+              Email:
+            </Text>
+            <TextField.Root value={user.email} readOnly style={{ flexGrow: 1 }} />
+          </Flex>
+          <Flex align="center" gap="2">
+            <Text weight="bold" style={{ width: 150 }}>
+              First Name:
+            </Text>
+            <TextField.Root value={user.firstName || ''} readOnly style={{ flexGrow: 1 }} />
+          </Flex>
+          <Flex align="center" gap="2">
+            <Text weight="bold" style={{ width: 150 }}>
+              Last Name:
+            </Text>
+            <TextField.Root value={user.lastName || ''} readOnly style={{ flexGrow: 1 }} />
+          </Flex>
+          <Flex align="center" gap="2">
+            <Text weight="bold" style={{ width: 150 }}>
+              Session ID:
+            </Text>
+            <TextField.Root value={sessionId || ''} readOnly style={{ flexGrow: 1 }} />
+          </Flex>
+          {organizationId && (
+            <Flex align="center" gap="2">
+              <Text weight="bold" style={{ width: 150 }}>
+                Organization ID:
+              </Text>
+              <TextField.Root value={organizationId} readOnly style={{ flexGrow: 1 }} />
+            </Flex>
+          )}
+          {role && (
+            <Flex align="center" gap="2">
+              <Text weight="bold" style={{ width: 150 }}>
+                Role:
+              </Text>
+              <TextField.Root value={role} readOnly style={{ flexGrow: 1 }} />
+            </Flex>
+          )}
+          {roles && roles.length > 0 && (
+            <Flex align="center" gap="2">
+              <Text weight="bold" style={{ width: 150 }}>
+                Roles:
+              </Text>
+              <Flex gap="2" wrap="wrap" style={{ flexGrow: 1 }}>
+                {roles.map((r) => (
+                  <Badge key={r}>{r}</Badge>
+                ))}
+              </Flex>
+            </Flex>
+          )}
+          {permissions && permissions.length > 0 && (
+            <Flex align="center" gap="2">
+              <Text weight="bold" style={{ width: 150 }}>
+                Permissions:
+              </Text>
+              <Flex gap="2" wrap="wrap" style={{ flexGrow: 1 }}>
+                {permissions.map((p) => (
+                  <Badge key={p} color="blue">
+                    {p}
+                  </Badge>
+                ))}
+              </Flex>
+            </Flex>
+          )}
+          {entitlements && entitlements.length > 0 && (
+            <Flex align="center" gap="2">
+              <Text weight="bold" style={{ width: 150 }}>
+                Entitlements:
+              </Text>
+              <Flex gap="2" wrap="wrap" style={{ flexGrow: 1 }}>
+                {entitlements.map((e) => (
+                  <Badge key={e} color="green">
+                    {e}
+                  </Badge>
+                ))}
+              </Flex>
+            </Flex>
+          )}
+          {featureFlags && featureFlags.length > 0 && (
+            <Flex align="center" gap="2">
+              <Text weight="bold" style={{ width: 150 }}>
+                Feature Flags:
+              </Text>
+              <Flex gap="2" wrap="wrap" style={{ flexGrow: 1 }}>
+                {featureFlags.map((f) => (
+                  <Badge key={f} color="purple">
+                    {f}
+                  </Badge>
+                ))}
+              </Flex>
+            </Flex>
+          )}
+          {impersonator && (
+            <Flex align="center" gap="2">
+              <Text weight="bold" style={{ width: 150 }}>
+                Impersonator:
+              </Text>
+              <TextField.Root value={impersonator.email} readOnly style={{ flexGrow: 1 }} />
+            </Flex>
+          )}
+        </Flex>
+      </Flex>
+
+      <Flex direction="column" gap="3">
+        <Heading size="5">useAccessToken() Hook</Heading>
+        <Flex direction="column" gap="2">
+          <Flex align="center" gap="2">
+            <Text weight="bold" style={{ width: 150 }}>
+              Token Status:
+            </Text>
+            <Badge color={tokenLoading ? 'yellow' : accessToken ? 'green' : 'gray'}>
+              {tokenLoading ? 'Loading' : accessToken ? 'Available' : 'None'}
+            </Badge>
+          </Flex>
+          {tokenError && (
+            <Flex align="center" gap="2">
+              <Text weight="bold" style={{ width: 150 }}>
+                Error:
+              </Text>
+              <Badge color="red">{tokenError.message}</Badge>
+            </Flex>
+          )}
+          {accessToken && (
+            <Flex align="center" gap="2">
+              <Text weight="bold" style={{ width: 150 }}>
+                Access Token:
+              </Text>
+              <Box style={{ flexGrow: 1, maxWidth: '100%', overflow: 'hidden' }}>
+                <Code size="2" style={{ wordBreak: 'break-all', display: 'block' }}>
+                  ...{accessToken.slice(-20)}
+                </Code>
+              </Box>
+            </Flex>
+          )}
+          <Flex gap="2" mt="2">
+            <Button onClick={handleRefreshToken} disabled={tokenLoading}>
+              Refresh Token
+            </Button>
+            <Button onClick={handleGetFreshToken} disabled={tokenLoading} variant="soft">
+              Get Fresh Token (Console)
+            </Button>
+          </Flex>
+        </Flex>
+      </Flex>
+
+      <Flex direction="column" gap="3">
+        <Heading size="5">Organization Management</Heading>
+        <Text size="2" color="gray">
+          Switch to a different organization. Requires multi-organization setup in WorkOS.
+        </Text>
+        <Callout.Root>
+          <Callout.Text>
+            <strong>Setup required:</strong> This feature requires your WorkOS user to be a member of multiple
+            organizations. Create organizations in the WorkOS dashboard and add your user to them.
+          </Callout.Text>
+        </Callout.Root>
+        <Flex direction="column" gap="2">
+          <Flex align="center" gap="2">
+            <Text weight="bold" style={{ width: 150 }}>
+              Current Org:
+            </Text>
+            <Badge color={organizationId ? 'green' : 'gray'} size="2">
+              {organizationId || 'None'}
+            </Badge>
+          </Flex>
+          <Flex align="center" gap="2">
+            <Text weight="bold" style={{ width: 150 }}>
+              Switch to Org:
+            </Text>
+            <TextField.Root
+              placeholder="org_..."
+              value={orgIdInput}
+              onChange={(e) => setOrgIdInput(e.target.value)}
+              style={{ flexGrow: 1 }}
+            />
+            <Button onClick={handleSwitchOrg} disabled={!orgIdInput.trim()}>
+              Switch
+            </Button>
+          </Flex>
+          {switchOrgResult && (
+            <Callout.Root color={switchOrgResult.startsWith('✅') ? 'green' : 'red'}>
+              <Callout.Text>{switchOrgResult}</Callout.Text>
+            </Callout.Root>
+          )}
+        </Flex>
+      </Flex>
+
+      <Flex direction="column" gap="3">
+        <Heading size="5">Sign Out Methods</Heading>
+        <Text size="2" color="gray">
+          Test different sign out approaches. Check the browser console for logs.
+        </Text>
+        <Flex gap="2" wrap="wrap">
+          <Button onClick={handleClientSignOut} color="red">
+            Sign Out (Client-Side useAuth)
+          </Button>
+          <Button asChild color="red" variant="soft">
+            <Link to="/logout" reloadDocument>
+              Sign Out (Route Loader)
+            </Link>
+          </Button>
+        </Flex>
+        <Callout.Root color="blue">
+          <Callout.Text>
+            <strong>Client-Side useAuth:</strong> Calls <Code>signOut()</Code> from the provider context. This tests the
+            redirect handling logic we just fixed.
+            <br />
+            <strong>Route Loader:</strong> Uses the <Code>/logout</Code> route which calls the server function directly
+            in a loader.
+          </Callout.Text>
+        </Callout.Root>
+      </Flex>
+    </Flex>
+  );
+}
diff --git a/examples/react/start-workos/src/routes/index.tsx b/examples/react/start-workos/src/routes/index.tsx
index 6f2c64415b..c69922a124 100644
--- a/examples/react/start-workos/src/routes/index.tsx
+++ b/examples/react/start-workos/src/routes/index.tsx
@@ -1,12 +1,12 @@
 import { Button, Flex, Heading, Text } from '@radix-ui/themes';
 import { Link, createFileRoute } from '@tanstack/react-router';
-import { getSignInUrl } from '../authkit/serverFunctions';
+import { getAuth, getSignInUrl } from '@workos/authkit-tanstack-react-start';
 import SignInButton from '../components/sign-in-button';
 
 export const Route = createFileRoute('/')({
   component: Home,
-  loader: async ({ context }) => {
-    const { user } = context;
+  loader: async () => {
+    const { user } = await getAuth();
     const url = await getSignInUrl();
     return { user, url };
   },
@@ -21,7 +21,7 @@ function Home() {
         <>
           <Heading size="8">Welcome back{user?.firstName && `, ${user?.firstName}`}</Heading>
           <Text size="5" color="gray">
-            You are now authenticated into the application
+            You are now authenticated into the TanStack Start application
           </Text>
           <Flex align="center" gap="3" mt="4">
             <Button asChild size="3" variant="soft">
diff --git a/examples/react/start-workos/src/routes/logout.tsx b/examples/react/start-workos/src/routes/logout.tsx
index 401d6cbc99..323e18f669 100644
--- a/examples/react/start-workos/src/routes/logout.tsx
+++ b/examples/react/start-workos/src/routes/logout.tsx
@@ -1,5 +1,5 @@
 import { createFileRoute } from '@tanstack/react-router';
-import { signOut } from '../authkit/serverFunctions';
+import { signOut } from '@workos/authkit-tanstack-react-start';
 
 export const Route = createFileRoute('/logout')({
   preload: false,
diff --git a/examples/react/start-workos/src/start.ts b/examples/react/start-workos/src/start.ts
new file mode 100644
index 0000000000..8ebcc0a641
--- /dev/null
+++ b/examples/react/start-workos/src/start.ts
@@ -0,0 +1,13 @@
+import { createStart } from '@tanstack/react-start';
+import { authkitMiddleware } from '@workos/authkit-tanstack-react-start';
+
+/**
+ * Configure TanStack Start with AuthKit middleware.
+ * The middleware runs on every server request and provides auth context.
+ */
+export const startInstance = createStart(() => {
+  return {
+    // Run AuthKit middleware on every request
+    requestMiddleware: [authkitMiddleware()],
+  };
+});
diff --git a/examples/react/start-workos/src/vite-env.d.ts b/examples/react/start-workos/src/vite-env.d.ts
new file mode 100644
index 0000000000..7a5f88a292
--- /dev/null
+++ b/examples/react/start-workos/src/vite-env.d.ts
@@ -0,0 +1,6 @@
+/// <reference types="vite/client" />
+
+declare module '*.css?url' {
+  const url: string;
+  export default url;
+}
diff --git a/examples/react/start-workos/vite.config.ts b/examples/react/start-workos/vite.config.ts
index fce3baa54d..81ac548d05 100644
--- a/examples/react/start-workos/vite.config.ts
+++ b/examples/react/start-workos/vite.config.ts
@@ -14,4 +14,7 @@ export default defineConfig({
     tanstackStart(),
     viteReact(),
   ],
+  ssr: {
+    noExternal: ['@radix-ui/themes'],
+  },
 });
diff --git a/examples/react/view-transitions/package.json b/examples/react/view-transitions/package.json
index dde1c6596a..fa76bc651b 100644
--- a/examples/react/view-transitions/package.json
+++ b/examples/react/view-transitions/package.json
@@ -10,9 +10,9 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
     "redaxios": "^0.5.1",
diff --git a/examples/react/with-framer-motion/package.json b/examples/react/with-framer-motion/package.json
index 0af49484b2..dc84a2c60a 100644
--- a/examples/react/with-framer-motion/package.json
+++ b/examples/react/with-framer-motion/package.json
@@ -10,8 +10,8 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
     "framer-motion": "^11.18.2",
     "react": "^19.0.0",
     "react-dom": "^19.0.0",
diff --git a/examples/react/with-trpc-react-query/package.json b/examples/react/with-trpc-react-query/package.json
index f6281d4b1f..10d539d1c6 100644
--- a/examples/react/with-trpc-react-query/package.json
+++ b/examples/react/with-trpc-react-query/package.json
@@ -13,9 +13,9 @@
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/react-query": "^5.90.0",
     "@tanstack/react-query-devtools": "^5.90.0",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "@trpc/client": "^11.4.3",
     "@trpc/server": "^11.4.3",
     "@trpc/tanstack-react-query": "^11.4.3",
diff --git a/examples/react/with-trpc/package.json b/examples/react/with-trpc/package.json
index 5046bd4f57..494014216b 100644
--- a/examples/react/with-trpc/package.json
+++ b/examples/react/with-trpc/package.json
@@ -11,9 +11,9 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/react-router": "^1.158.0",
-    "@tanstack/react-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/react-router": "^1.160.0",
+    "@tanstack/react-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "@trpc/client": "^11.4.3",
     "@trpc/server": "^11.4.3",
     "express": "^4.21.2",
diff --git a/examples/solid/authenticated-routes-firebase/package.json b/examples/solid/authenticated-routes-firebase/package.json
index e650686b2e..8bab620dca 100644
--- a/examples/solid/authenticated-routes-firebase/package.json
+++ b/examples/solid/authenticated-routes-firebase/package.json
@@ -10,9 +10,9 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "firebase": "^11.4.0",
     "solid-js": "^1.9.10",
     "redaxios": "^0.5.1",
diff --git a/examples/solid/authenticated-routes/package.json b/examples/solid/authenticated-routes/package.json
index 8f34e98560..ef8b4b9561 100644
--- a/examples/solid/authenticated-routes/package.json
+++ b/examples/solid/authenticated-routes/package.json
@@ -10,9 +10,9 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "solid-js": "^1.9.10",
     "redaxios": "^0.5.1",
     "tailwindcss": "^4.1.18",
diff --git a/examples/solid/basic-default-search-params/package.json b/examples/solid/basic-default-search-params/package.json
index 4a933ae55f..004a7ddd21 100644
--- a/examples/solid/basic-default-search-params/package.json
+++ b/examples/solid/basic-default-search-params/package.json
@@ -11,8 +11,8 @@
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/solid-query": "^5.90.9",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "solid-js": "^1.9.10",
     "redaxios": "^0.5.1",
     "tailwindcss": "^4.1.18",
diff --git a/examples/solid/basic-devtools-panel/package.json b/examples/solid/basic-devtools-panel/package.json
index 81d22f492f..30520dc7ca 100644
--- a/examples/solid/basic-devtools-panel/package.json
+++ b/examples/solid/basic-devtools-panel/package.json
@@ -10,8 +10,8 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "redaxios": "^0.5.1",
     "solid-js": "^1.9.10",
     "tailwindcss": "^4.1.18"
diff --git a/examples/solid/basic-file-based/package.json b/examples/solid/basic-file-based/package.json
index f0ce9c01de..776a64af86 100644
--- a/examples/solid/basic-file-based/package.json
+++ b/examples/solid/basic-file-based/package.json
@@ -10,15 +10,15 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "redaxios": "^0.5.1",
     "solid-js": "^1.9.10",
     "tailwindcss": "^4.1.18",
     "zod": "^3.24.2"
   },
   "devDependencies": {
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "typescript": "^5.7.2",
     "vite": "^7.3.1",
     "vite-plugin-solid": "^2.11.10"
diff --git a/examples/solid/basic-non-nested-devtools/package.json b/examples/solid/basic-non-nested-devtools/package.json
index f77f235fea..c44be719e3 100644
--- a/examples/solid/basic-non-nested-devtools/package.json
+++ b/examples/solid/basic-non-nested-devtools/package.json
@@ -10,8 +10,8 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "redaxios": "^0.5.1",
     "solid-js": "^1.9.10",
     "tailwindcss": "^4.1.18"
diff --git a/examples/solid/basic-solid-query-file-based/package.json b/examples/solid/basic-solid-query-file-based/package.json
index 95a1031669..3d355c12a5 100644
--- a/examples/solid/basic-solid-query-file-based/package.json
+++ b/examples/solid/basic-solid-query-file-based/package.json
@@ -13,15 +13,15 @@
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/solid-query": "^5.90.9",
     "@tanstack/solid-query-devtools": "^5.90.0",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "redaxios": "^0.5.1",
     "solid-js": "^1.9.10",
     "tailwindcss": "^4.1.18",
     "zod": "^3.24.2"
   },
   "devDependencies": {
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "typescript": "^5.7.2",
     "vite": "^7.3.1",
     "vite-plugin-solid": "^2.11.10"
diff --git a/examples/solid/basic-solid-query/package.json b/examples/solid/basic-solid-query/package.json
index b7b46b0130..b85c102818 100644
--- a/examples/solid/basic-solid-query/package.json
+++ b/examples/solid/basic-solid-query/package.json
@@ -12,14 +12,14 @@
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/solid-query": "^5.90.9",
     "@tanstack/solid-query-devtools": "^5.90.0",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "redaxios": "^0.5.1",
     "solid-js": "^1.9.10",
     "tailwindcss": "^4.1.18"
   },
   "devDependencies": {
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "typescript": "^5.7.2",
     "vite": "^7.3.1",
     "vite-plugin-solid": "^2.11.10"
diff --git a/examples/solid/basic-ssr-file-based/package.json b/examples/solid/basic-ssr-file-based/package.json
index 4f448056ba..22154d314b 100644
--- a/examples/solid/basic-ssr-file-based/package.json
+++ b/examples/solid/basic-ssr-file-based/package.json
@@ -11,8 +11,8 @@
     "debug": "node --inspect-brk server"
   },
   "dependencies": {
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "compression": "^1.8.0",
     "express": "^4.21.2",
     "get-port": "^7.1.0",
@@ -20,7 +20,7 @@
     "solid-js": "^1.9.10"
   },
   "devDependencies": {
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "@types/express": "^4.17.23",
     "vite-plugin-solid": "^2.11.10",
     "typescript": "^5.8.3",
diff --git a/examples/solid/basic-ssr-streaming-file-based/package.json b/examples/solid/basic-ssr-streaming-file-based/package.json
index 84f56cb2da..12bc9d50c2 100644
--- a/examples/solid/basic-ssr-streaming-file-based/package.json
+++ b/examples/solid/basic-ssr-streaming-file-based/package.json
@@ -12,8 +12,8 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "compression": "^1.8.0",
     "express": "^4.21.2",
     "get-port": "^7.1.0",
@@ -24,7 +24,7 @@
     "zod": "^3.24.2"
   },
   "devDependencies": {
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "@types/express": "^4.17.23",
     "typescript": "^5.7.2",
     "vite": "^7.3.1",
diff --git a/examples/solid/basic-virtual-file-based/package.json b/examples/solid/basic-virtual-file-based/package.json
index ed712e65d4..066b5a1c68 100644
--- a/examples/solid/basic-virtual-file-based/package.json
+++ b/examples/solid/basic-virtual-file-based/package.json
@@ -10,9 +10,9 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "@tanstack/virtual-file-routes": "^1.154.7",
     "solid-js": "^1.9.10",
     "redaxios": "^0.5.1",
diff --git a/examples/solid/basic-virtual-inside-file-based/package.json b/examples/solid/basic-virtual-inside-file-based/package.json
index 5860b1cb57..0a9daa867a 100644
--- a/examples/solid/basic-virtual-inside-file-based/package.json
+++ b/examples/solid/basic-virtual-inside-file-based/package.json
@@ -10,9 +10,9 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "@tanstack/virtual-file-routes": "^1.154.7",
     "solid-js": "^1.9.10",
     "redaxios": "^0.5.1",
diff --git a/examples/solid/basic/package.json b/examples/solid/basic/package.json
index e038721e33..558f6b293e 100644
--- a/examples/solid/basic/package.json
+++ b/examples/solid/basic/package.json
@@ -10,8 +10,8 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "redaxios": "^0.5.1",
     "solid-js": "^1.9.10",
     "tailwindcss": "^4.1.18"
diff --git a/examples/solid/deferred-data/package.json b/examples/solid/deferred-data/package.json
index a0c2111cf7..570e948b23 100644
--- a/examples/solid/deferred-data/package.json
+++ b/examples/solid/deferred-data/package.json
@@ -10,8 +10,8 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "solid-js": "^1.9.10",
     "redaxios": "^0.5.1",
     "tailwindcss": "^4.1.18",
diff --git a/examples/solid/i18n-paraglide/package.json b/examples/solid/i18n-paraglide/package.json
index bd3783e4ce..12d291deee 100644
--- a/examples/solid/i18n-paraglide/package.json
+++ b/examples/solid/i18n-paraglide/package.json
@@ -11,8 +11,8 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "solid-js": "^1.9.10",
     "tailwindcss": "^4.1.18"
   },
diff --git a/examples/solid/kitchen-sink-file-based/package.json b/examples/solid/kitchen-sink-file-based/package.json
index 56e5c7d32b..d3f4dca4f4 100644
--- a/examples/solid/kitchen-sink-file-based/package.json
+++ b/examples/solid/kitchen-sink-file-based/package.json
@@ -10,8 +10,8 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "immer": "^10.1.1",
     "redaxios": "^0.5.1",
     "solid-js": "^1.9.10",
@@ -19,7 +19,7 @@
     "zod": "^3.24.2"
   },
   "devDependencies": {
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "typescript": "^5.7.2",
     "vite": "^7.3.1",
     "vite-plugin-solid": "^2.11.10"
diff --git a/examples/solid/kitchen-sink-solid-query-file-based/package.json b/examples/solid/kitchen-sink-solid-query-file-based/package.json
index f2569c7d69..e53c55aeee 100644
--- a/examples/solid/kitchen-sink-solid-query-file-based/package.json
+++ b/examples/solid/kitchen-sink-solid-query-file-based/package.json
@@ -10,11 +10,11 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "@tanstack/solid-query": "^5.90.9",
     "@tanstack/solid-query-devtools": "^5.90.0",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "immer": "^10.1.1",
     "redaxios": "^0.5.1",
     "solid-js": "^1.9.10",
diff --git a/examples/solid/kitchen-sink-solid-query/package.json b/examples/solid/kitchen-sink-solid-query/package.json
index ac052f6a0b..19eaa11d7f 100644
--- a/examples/solid/kitchen-sink-solid-query/package.json
+++ b/examples/solid/kitchen-sink-solid-query/package.json
@@ -12,8 +12,8 @@
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/solid-query": "^5.90.9",
     "@tanstack/solid-query-devtools": "^5.90.0",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "immer": "^10.1.1",
     "redaxios": "^0.5.1",
     "solid-js": "^1.9.10",
diff --git a/examples/solid/kitchen-sink/package.json b/examples/solid/kitchen-sink/package.json
index 5e25ef6635..e3033a3d02 100644
--- a/examples/solid/kitchen-sink/package.json
+++ b/examples/solid/kitchen-sink/package.json
@@ -10,8 +10,8 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "immer": "^10.1.1",
     "solid-js": "^1.9.10",
     "redaxios": "^0.5.1",
diff --git a/examples/solid/large-file-based/package.json b/examples/solid/large-file-based/package.json
index ffe2c6b4ae..349562414a 100644
--- a/examples/solid/large-file-based/package.json
+++ b/examples/solid/large-file-based/package.json
@@ -13,9 +13,9 @@
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/solid-query": "^5.90.9",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "solid-js": "^1.9.10",
     "redaxios": "^0.5.1",
     "tailwindcss": "^4.1.18",
diff --git a/examples/solid/location-masking/package.json b/examples/solid/location-masking/package.json
index 67f807e798..74a2eca0c9 100644
--- a/examples/solid/location-masking/package.json
+++ b/examples/solid/location-masking/package.json
@@ -11,8 +11,8 @@
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/solid-query": "^5.90.9",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "solid-js": "^1.9.10",
     "redaxios": "^0.5.1",
     "tailwindcss": "^4.1.18"
diff --git a/examples/solid/navigation-blocking/package.json b/examples/solid/navigation-blocking/package.json
index 9434744a3e..82fcd69208 100644
--- a/examples/solid/navigation-blocking/package.json
+++ b/examples/solid/navigation-blocking/package.json
@@ -11,8 +11,8 @@
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/solid-query": "^5.90.9",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "solid-js": "^1.9.10",
     "redaxios": "^0.5.1",
     "tailwindcss": "^4.1.18"
diff --git a/examples/solid/quickstart-esbuild-file-based/package.json b/examples/solid/quickstart-esbuild-file-based/package.json
index b18c89a635..93a1b18cdb 100644
--- a/examples/solid/quickstart-esbuild-file-based/package.json
+++ b/examples/solid/quickstart-esbuild-file-based/package.json
@@ -9,9 +9,9 @@
     "start": "dev"
   },
   "dependencies": {
-    "@tanstack/router-plugin": "^1.158.0",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/router-plugin": "^1.160.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "redaxios": "^0.5.1",
     "solid-js": "^1.9.10",
     "tailwindcss": "^4.1.18",
diff --git a/examples/solid/quickstart-file-based/package.json b/examples/solid/quickstart-file-based/package.json
index 00a5ff4638..9c8d615ecd 100644
--- a/examples/solid/quickstart-file-based/package.json
+++ b/examples/solid/quickstart-file-based/package.json
@@ -10,15 +10,15 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "redaxios": "^0.5.1",
     "solid-js": "^1.9.10",
     "tailwindcss": "^4.1.18",
     "zod": "^3.24.2"
   },
   "devDependencies": {
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "typescript": "^5.7.2",
     "vite": "^7.3.1",
     "vite-plugin-solid": "^2.11.10"
diff --git a/examples/solid/quickstart-rspack-file-based/package.json b/examples/solid/quickstart-rspack-file-based/package.json
index 9dbb90f14e..07ca80b87e 100644
--- a/examples/solid/quickstart-rspack-file-based/package.json
+++ b/examples/solid/quickstart-rspack-file-based/package.json
@@ -9,8 +9,8 @@
   },
   "dependencies": {
     "@tailwindcss/postcss": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "postcss": "^8.5.1",
     "solid-js": "^1.9.10",
     "tailwindcss": "^4.1.18"
@@ -19,7 +19,7 @@
     "@rsbuild/core": "^1.2.4",
     "@rsbuild/plugin-babel": "^1.0.6",
     "@rsbuild/plugin-solid": "^1.0.6",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "typescript": "^5.6.2"
   }
 }
diff --git a/examples/solid/quickstart-webpack-file-based/package.json b/examples/solid/quickstart-webpack-file-based/package.json
index 538d7c8b43..a7cd5db146 100644
--- a/examples/solid/quickstart-webpack-file-based/package.json
+++ b/examples/solid/quickstart-webpack-file-based/package.json
@@ -7,15 +7,15 @@
     "build": "webpack build && tsc --noEmit"
   },
   "dependencies": {
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "solid-js": "^1.9.10",
     "tailwindcss": "^4.1.18"
   },
   "devDependencies": {
     "@babel/core": "^7.28.5",
     "@babel/preset-typescript": "^7.27.1",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "babel-loader": "^10.0.0",
     "babel-preset-solid": "^1.9.10",
     "css-loader": "^7.1.2",
diff --git a/examples/solid/quickstart/package.json b/examples/solid/quickstart/package.json
index 1f5ccbcdd6..eac7f0b9b2 100644
--- a/examples/solid/quickstart/package.json
+++ b/examples/solid/quickstart/package.json
@@ -10,8 +10,8 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "solid-js": "^1.9.10",
     "tailwindcss": "^4.1.18"
   },
diff --git a/examples/solid/router-monorepo-simple-lazy/package.json b/examples/solid/router-monorepo-simple-lazy/package.json
index 98be114b46..06971a61b5 100644
--- a/examples/solid/router-monorepo-simple-lazy/package.json
+++ b/examples/solid/router-monorepo-simple-lazy/package.json
@@ -8,9 +8,9 @@
     "dev": "pnpm router build && pnpm post-feature build && pnpm app dev"
   },
   "dependencies": {
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "solid-js": "^1.9.10",
     "redaxios": "^0.5.1"
   },
diff --git a/examples/solid/router-monorepo-simple-lazy/packages/app/package.json b/examples/solid/router-monorepo-simple-lazy/packages/app/package.json
index f7ce1ba863..4759d078fe 100644
--- a/examples/solid/router-monorepo-simple-lazy/packages/app/package.json
+++ b/examples/solid/router-monorepo-simple-lazy/packages/app/package.json
@@ -19,7 +19,7 @@
     "@types/react-dom": "^19.0.3",
     "@vitejs/plugin-react": "^4.3.4",
     "typescript": "^5.7.2",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "tailwindcss": "4.1.18",
     "vite": "^7.3.1",
     "vite-plugin-dts": "^4.5.4",
diff --git a/examples/solid/router-monorepo-simple-lazy/packages/router/package.json b/examples/solid/router-monorepo-simple-lazy/packages/router/package.json
index a45277cdf2..54c662ff65 100644
--- a/examples/solid/router-monorepo-simple-lazy/packages/router/package.json
+++ b/examples/solid/router-monorepo-simple-lazy/packages/router/package.json
@@ -9,8 +9,8 @@
   "types": "./dist/index.d.ts",
   "dependencies": {
     "@tanstack/history": "^1.154.14",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "redaxios": "^0.5.1",
     "zod": "^3.24.2",
     "solid-js": "^1.9.10"
diff --git a/examples/solid/router-monorepo-simple/package.json b/examples/solid/router-monorepo-simple/package.json
index bec71a6090..e0d5405f94 100644
--- a/examples/solid/router-monorepo-simple/package.json
+++ b/examples/solid/router-monorepo-simple/package.json
@@ -8,9 +8,9 @@
     "dev": "pnpm router build && pnpm post-feature build && pnpm app dev"
   },
   "dependencies": {
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "solid-js": "^1.9.10",
     "redaxios": "^0.5.1"
   },
diff --git a/examples/solid/router-monorepo-simple/packages/app/package.json b/examples/solid/router-monorepo-simple/packages/app/package.json
index cd1187d1f9..4600aea7be 100644
--- a/examples/solid/router-monorepo-simple/packages/app/package.json
+++ b/examples/solid/router-monorepo-simple/packages/app/package.json
@@ -16,7 +16,7 @@
   "devDependencies": {
     "vite-plugin-solid": "^2.11.10",
     "typescript": "^5.7.2",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "vite": "^7.3.1",
     "tailwindcss": "4.1.18",
     "vite-plugin-dts": "^4.5.4",
diff --git a/examples/solid/router-monorepo-simple/packages/router/package.json b/examples/solid/router-monorepo-simple/packages/router/package.json
index 76fe35842c..24326f74a6 100644
--- a/examples/solid/router-monorepo-simple/packages/router/package.json
+++ b/examples/solid/router-monorepo-simple/packages/router/package.json
@@ -9,8 +9,8 @@
   "types": "./dist/index.d.ts",
   "dependencies": {
     "@tanstack/history": "^1.154.14",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "redaxios": "^0.5.1",
     "zod": "^3.24.2",
     "solid-js": "^1.9.10"
diff --git a/examples/solid/router-monorepo-solid-query/package.json b/examples/solid/router-monorepo-solid-query/package.json
index 340685080d..0d003e2631 100644
--- a/examples/solid/router-monorepo-solid-query/package.json
+++ b/examples/solid/router-monorepo-solid-query/package.json
@@ -12,9 +12,9 @@
   "dependencies": {
     "@tanstack/solid-query": "^5.90.9",
     "@tanstack/solid-query-devtools": "^5.90.0",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "solid-js": "^1.9.10",
     "redaxios": "^0.5.1"
   },
diff --git a/examples/solid/router-monorepo-solid-query/packages/app/package.json b/examples/solid/router-monorepo-solid-query/packages/app/package.json
index 78421d735e..672aa123d1 100644
--- a/examples/solid/router-monorepo-solid-query/packages/app/package.json
+++ b/examples/solid/router-monorepo-solid-query/packages/app/package.json
@@ -17,7 +17,7 @@
   "devDependencies": {
     "vite-plugin-solid": "^2.11.10",
     "typescript": "^5.7.2",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "tailwindcss": "4.1.18",
     "vite": "^7.3.1",
     "vite-plugin-dts": "^4.5.4",
diff --git a/examples/solid/router-monorepo-solid-query/packages/router/package.json b/examples/solid/router-monorepo-solid-query/packages/router/package.json
index 5aa81a9c90..a5593f5079 100644
--- a/examples/solid/router-monorepo-solid-query/packages/router/package.json
+++ b/examples/solid/router-monorepo-solid-query/packages/router/package.json
@@ -10,8 +10,8 @@
   "dependencies": {
     "@tanstack/history": "^1.154.14",
     "@tanstack/solid-query": "^5.90.9",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "@router-solid-mono-solid-query/post-query": "workspace:*",
     "redaxios": "^0.5.1",
     "zod": "^3.24.2",
diff --git a/examples/solid/scroll-restoration/package.json b/examples/solid/scroll-restoration/package.json
index 93625055fd..98c0745dac 100644
--- a/examples/solid/scroll-restoration/package.json
+++ b/examples/solid/scroll-restoration/package.json
@@ -10,8 +10,8 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "@tanstack/solid-virtual": "^3.13.0",
     "solid-js": "^1.9.10",
     "tailwindcss": "^4.1.18"
diff --git a/examples/solid/search-validator-adapters/package.json b/examples/solid/search-validator-adapters/package.json
index 346c357c7b..037bc45ce7 100644
--- a/examples/solid/search-validator-adapters/package.json
+++ b/examples/solid/search-validator-adapters/package.json
@@ -11,13 +11,13 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/arktype-adapter": "^1.158.0",
+    "@tanstack/arktype-adapter": "^1.160.0",
     "@tanstack/solid-query": "^5.90.9",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
-    "@tanstack/valibot-adapter": "^1.158.0",
-    "@tanstack/zod-adapter": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
+    "@tanstack/valibot-adapter": "^1.160.0",
+    "@tanstack/zod-adapter": "^1.160.0",
     "arktype": "^2.1.7",
     "solid-js": "^1.9.10",
     "tailwindcss": "^4.1.18",
diff --git a/examples/solid/start-basic-auth/package.json b/examples/solid/start-basic-auth/package.json
index 9f6b0a455a..eb537209ec 100644
--- a/examples/solid/start-basic-auth/package.json
+++ b/examples/solid/start-basic-auth/package.json
@@ -14,9 +14,9 @@
     "@libsql/client": "^0.15.15",
     "@prisma/adapter-libsql": "^7.0.0",
     "@prisma/client": "^7.0.0",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/solid-start": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/solid-start": "^1.160.0",
     "redaxios": "^0.5.1",
     "solid-js": "^1.9.10",
     "tailwind-merge": "^2.6.0"
diff --git a/examples/solid/start-basic-authjs/package.json b/examples/solid/start-basic-authjs/package.json
index 76dddb5249..004370b570 100644
--- a/examples/solid/start-basic-authjs/package.json
+++ b/examples/solid/start-basic-authjs/package.json
@@ -11,9 +11,9 @@
   },
   "dependencies": {
     "@auth/core": "^0.41.1",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/solid-start": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/solid-start": "^1.160.0",
     "start-authjs": "^1.0.0",
     "solid-js": "^1.9.10",
     "tailwind-merge": "^2.6.0"
diff --git a/examples/solid/start-basic-cloudflare/package.json b/examples/solid/start-basic-cloudflare/package.json
index a3eea23778..8c87d8152a 100644
--- a/examples/solid/start-basic-cloudflare/package.json
+++ b/examples/solid/start-basic-cloudflare/package.json
@@ -12,9 +12,9 @@
     "postinstall": "npm run cf-typegen"
   },
   "dependencies": {
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/solid-start": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/solid-start": "^1.160.0",
     "solid-js": "^1.9.10"
   },
   "devDependencies": {
diff --git a/examples/solid/start-basic-netlify/package.json b/examples/solid/start-basic-netlify/package.json
index 7b861200fa..ffc6b97e6c 100644
--- a/examples/solid/start-basic-netlify/package.json
+++ b/examples/solid/start-basic-netlify/package.json
@@ -9,9 +9,9 @@
     "preview": "vite preview"
   },
   "dependencies": {
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/solid-start": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/solid-start": "^1.160.0",
     "solid-js": "^1.9.10"
   },
   "devDependencies": {
diff --git a/examples/solid/start-basic-nitro/package.json b/examples/solid/start-basic-nitro/package.json
index f694d167e8..408c1f4262 100644
--- a/examples/solid/start-basic-nitro/package.json
+++ b/examples/solid/start-basic-nitro/package.json
@@ -9,9 +9,9 @@
     "preview": "vite preview"
   },
   "dependencies": {
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/solid-start": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/solid-start": "^1.160.0",
     "solid-js": "^1.9.10"
   },
   "devDependencies": {
diff --git a/examples/solid/start-basic-solid-query/package.json b/examples/solid/start-basic-solid-query/package.json
index cb013892a5..2b98d4d80a 100644
--- a/examples/solid/start-basic-solid-query/package.json
+++ b/examples/solid/start-basic-solid-query/package.json
@@ -12,10 +12,10 @@
   "dependencies": {
     "@tanstack/solid-query": "^5.90.9",
     "@tanstack/solid-query-devtools": "^5.90.0",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/solid-router-ssr-query": "^1.158.0",
-    "@tanstack/solid-start": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/solid-router-ssr-query": "^1.160.0",
+    "@tanstack/solid-start": "^1.160.0",
     "redaxios": "^0.5.1",
     "solid-js": "^1.9.10",
     "tailwind-merge": "^2.6.0"
diff --git a/examples/solid/start-basic-static/package.json b/examples/solid/start-basic-static/package.json
index cb8d8b3359..1d4b551a2b 100644
--- a/examples/solid/start-basic-static/package.json
+++ b/examples/solid/start-basic-static/package.json
@@ -10,10 +10,10 @@
     "start": "pnpx srvx --prod -s ../client dist/server/server.js"
   },
   "dependencies": {
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/solid-start": "^1.158.0",
-    "@tanstack/start-static-server-functions": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/solid-start": "^1.160.0",
+    "@tanstack/start-static-server-functions": "^1.160.0",
     "solid-js": "^1.9.10",
     "redaxios": "^0.5.1",
     "tailwind-merge": "^2.6.0"
diff --git a/examples/solid/start-basic/package.json b/examples/solid/start-basic/package.json
index f6bfe0cdd0..5d30b47123 100644
--- a/examples/solid/start-basic/package.json
+++ b/examples/solid/start-basic/package.json
@@ -10,9 +10,9 @@
     "start": "node .output/server/index.mjs"
   },
   "dependencies": {
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/solid-start": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/solid-start": "^1.160.0",
     "redaxios": "^0.5.1",
     "solid-js": "^1.9.10",
     "tailwind-merge": "^2.6.0"
diff --git a/examples/solid/start-bun/package.json b/examples/solid/start-bun/package.json
index d10bac24d1..b37a1a6510 100644
--- a/examples/solid/start-bun/package.json
+++ b/examples/solid/start-bun/package.json
@@ -15,11 +15,11 @@
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
     "@tanstack/solid-devtools": "^0.7.0",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/solid-router-ssr-query": "^1.158.0",
-    "@tanstack/solid-start": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/solid-router-ssr-query": "^1.160.0",
+    "@tanstack/solid-start": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "solid-js": "^1.9.10",
     "tailwindcss": "^4.1.18",
     "vite-tsconfig-paths": "^5.1.4"
diff --git a/examples/solid/start-convex-better-auth/package.json b/examples/solid/start-convex-better-auth/package.json
index e746964def..02753cadb1 100644
--- a/examples/solid/start-convex-better-auth/package.json
+++ b/examples/solid/start-convex-better-auth/package.json
@@ -13,9 +13,9 @@
   "dependencies": {
     "@convex-dev/better-auth": "^0.9.7",
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/solid-start": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/solid-start": "^1.160.0",
     "better-auth": "^1.3.27",
     "clsx": "^2.1.1",
     "convex": "^1.28.2",
diff --git a/examples/solid/start-counter/package.json b/examples/solid/start-counter/package.json
index 7ff7ab9f66..03bf6b85e0 100644
--- a/examples/solid/start-counter/package.json
+++ b/examples/solid/start-counter/package.json
@@ -10,9 +10,9 @@
     "start": "pnpx srvx --prod -s ../client dist/server/server.js"
   },
   "dependencies": {
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/solid-start": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/solid-start": "^1.160.0",
     "solid-js": "^1.9.10",
     "redaxios": "^0.5.1",
     "tailwind-merge": "^2.6.0",
diff --git a/examples/solid/start-i18n-paraglide/package.json b/examples/solid/start-i18n-paraglide/package.json
index 2c9fd26926..d805eb6b71 100644
--- a/examples/solid/start-i18n-paraglide/package.json
+++ b/examples/solid/start-i18n-paraglide/package.json
@@ -10,9 +10,9 @@
   },
   "dependencies": {
     "@tanstack/solid-devtools": "^0.7.0",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/solid-start": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/solid-start": "^1.160.0",
     "solid-js": "^1.9.10"
   },
   "devDependencies": {
diff --git a/examples/solid/start-large/package.json b/examples/solid/start-large/package.json
index f44511dd88..73e289fef6 100644
--- a/examples/solid/start-large/package.json
+++ b/examples/solid/start-large/package.json
@@ -13,9 +13,9 @@
   },
   "dependencies": {
     "@tanstack/solid-query": "^5.90.9",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/solid-start": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/solid-start": "^1.160.0",
     "solid-js": "^1.9.10",
     "redaxios": "^0.5.1",
     "tailwind-merge": "^2.6.0",
diff --git a/examples/solid/start-streaming-data-from-server-functions/package.json b/examples/solid/start-streaming-data-from-server-functions/package.json
index 43e3825053..e613d9fd51 100644
--- a/examples/solid/start-streaming-data-from-server-functions/package.json
+++ b/examples/solid/start-streaming-data-from-server-functions/package.json
@@ -10,9 +10,9 @@
     "start": "pnpx srvx --prod -s ../client dist/server/server.js"
   },
   "dependencies": {
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/solid-start": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/solid-start": "^1.160.0",
     "solid-js": "^1.9.10",
     "zod": "^3.24.2"
   },
diff --git a/examples/solid/start-supabase-basic/package.json b/examples/solid/start-supabase-basic/package.json
index 25c4a2b2c5..a977f5a427 100644
--- a/examples/solid/start-supabase-basic/package.json
+++ b/examples/solid/start-supabase-basic/package.json
@@ -14,9 +14,9 @@
   "dependencies": {
     "@supabase/ssr": "^0.5.2",
     "@supabase/supabase-js": "^2.48.1",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/solid-start": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/solid-start": "^1.160.0",
     "solid-js": "^1.9.9",
     "redaxios": "^0.5.1"
   },
diff --git a/examples/solid/start-tailwind-v4/package.json b/examples/solid/start-tailwind-v4/package.json
index bef09d5c6e..b07e24e62f 100644
--- a/examples/solid/start-tailwind-v4/package.json
+++ b/examples/solid/start-tailwind-v4/package.json
@@ -10,9 +10,9 @@
     "start": "node .output/server/index.mjs"
   },
   "dependencies": {
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/solid-start": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/solid-start": "^1.160.0",
     "solid-js": "^1.9.10",
     "tailwind-merge": "^2.6.0",
     "zod": "^3.24.2"
diff --git a/examples/solid/view-transitions/package.json b/examples/solid/view-transitions/package.json
index 9267d28409..de96db62cf 100644
--- a/examples/solid/view-transitions/package.json
+++ b/examples/solid/view-transitions/package.json
@@ -10,9 +10,9 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "solid-js": "^1.9.10",
     "redaxios": "^0.5.1",
     "tailwindcss": "^4.1.18",
diff --git a/examples/solid/with-framer-motion/package.json b/examples/solid/with-framer-motion/package.json
index a9a696632f..51cbb1fbdb 100644
--- a/examples/solid/with-framer-motion/package.json
+++ b/examples/solid/with-framer-motion/package.json
@@ -10,8 +10,8 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
     "redaxios": "^0.5.1",
     "solid-js": "^1.9.10",
     "solid-motionone": "^1.0.4",
diff --git a/examples/solid/with-trpc/package.json b/examples/solid/with-trpc/package.json
index 0af4751855..747f62aefb 100644
--- a/examples/solid/with-trpc/package.json
+++ b/examples/solid/with-trpc/package.json
@@ -11,9 +11,9 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/solid-router": "^1.158.0",
-    "@tanstack/solid-router-devtools": "^1.158.0",
-    "@tanstack/router-plugin": "^1.158.0",
+    "@tanstack/solid-router": "^1.160.0",
+    "@tanstack/solid-router-devtools": "^1.160.0",
+    "@tanstack/router-plugin": "^1.160.0",
     "@trpc/client": "^11.4.3",
     "@trpc/server": "^11.4.3",
     "express": "^4.21.2",
diff --git a/examples/vue/basic-file-based-jsx/package.json b/examples/vue/basic-file-based-jsx/package.json
index fe10ae2736..7095c51ed7 100644
--- a/examples/vue/basic-file-based-jsx/package.json
+++ b/examples/vue/basic-file-based-jsx/package.json
@@ -10,10 +10,10 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/router-plugin": "^1.158.0",
-    "@tanstack/vue-router": "^1.158.0",
-    "@tanstack/vue-router-devtools": "^1.158.0",
-    "@tanstack/zod-adapter": "^1.158.0",
+    "@tanstack/router-plugin": "^1.160.0",
+    "@tanstack/vue-router": "^1.160.0",
+    "@tanstack/vue-router-devtools": "^1.160.0",
+    "@tanstack/zod-adapter": "^1.160.0",
     "redaxios": "^0.5.1",
     "tailwindcss": "^4.1.18",
     "vue": "^3.5.16",
diff --git a/examples/vue/basic-file-based-sfc/package.json b/examples/vue/basic-file-based-sfc/package.json
index 9c434dcc69..ca9e404685 100644
--- a/examples/vue/basic-file-based-sfc/package.json
+++ b/examples/vue/basic-file-based-sfc/package.json
@@ -10,10 +10,10 @@
   },
   "dependencies": {
     "@tailwindcss/vite": "^4.1.18",
-    "@tanstack/router-plugin": "^1.158.0",
-    "@tanstack/vue-router": "^1.158.0",
-    "@tanstack/vue-router-devtools": "^1.158.0",
-    "@tanstack/zod-adapter": "^1.158.0",
+    "@tanstack/router-plugin": "^1.160.0",
+    "@tanstack/vue-router": "^1.160.0",
+    "@tanstack/vue-router-devtools": "^1.160.0",
+    "@tanstack/zod-adapter": "^1.160.0",
     "redaxios": "^0.5.1",
     "tailwindcss": "^4.1.18",
     "vue": "^3.5.16",
diff --git a/examples/vue/basic/package.json b/examples/vue/basic/package.json
index 385d8f6d01..1fd6e585b7 100644
--- a/examples/vue/basic/package.json
+++ b/examples/vue/basic/package.json
@@ -9,8 +9,8 @@
     "start": "vite"
   },
   "dependencies": {
-    "@tanstack/vue-router": "^1.158.0",
-    "@tanstack/vue-router-devtools": "^1.158.0",
+    "@tanstack/vue-router": "^1.160.0",
+    "@tanstack/vue-router-devtools": "^1.160.0",
     "redaxios": "^0.5.1",
     "vue": "^3.5.13",
     "tailwindcss": "4.1.18"
diff --git a/package.json b/package.json
index 7325283b5e..c6679b70f8 100644
--- a/package.json
+++ b/package.json
@@ -29,7 +29,10 @@
     "set-ts-version": "node scripts/set-ts-version.js",
     "labeler-generate": "node scripts/generate-labeler-config.ts",
     "cleanup-empty-packages": "node scripts/cleanup-empty-packages.mjs",
-    "test:docs": "node scripts/verify-links.ts"
+    "test:docs": "node scripts/verify-links.ts",
+    "vite-ecosystem-ci:build": "nx run-many --targets=build --projects=@tanstack/router-plugin,@tanstack/start-plugin-core,@tanstack/react-start,@tanstack/react-start-client,@tanstack/react-start-server",
+    "vite-ecosystem-ci:before-test": "pnpm exec playwright install chromium",
+    "vite-ecosystem-ci:test": "nx run-many --targets=test:unit --projects=@tanstack/router-plugin,@tanstack/start-plugin-core,@tanstack/react-start-client && nx run-many --target=test:e2e --projects=tanstack-router-e2e-react-basic-file-based,tanstack-router-e2e-react-basic-file-based-code-splitting,tanstack-react-start-e2e-basic"
   },
   "nx": {
     "includedScripts": [
diff --git a/packages/arktype-adapter/package.json b/packages/arktype-adapter/package.json
index 5669460d36..427ec0ab55 100644
--- a/packages/arktype-adapter/package.json
+++ b/packages/arktype-adapter/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/arktype-adapter",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/react-router-devtools/package.json b/packages/react-router-devtools/package.json
index e350337a1e..db1bc6905b 100644
--- a/packages/react-router-devtools/package.json
+++ b/packages/react-router-devtools/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/react-router-devtools",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/react-router-ssr-query/README.md b/packages/react-router-ssr-query/README.md
index 1cc3471e0a..0a19fd3b81 100644
--- a/packages/react-router-ssr-query/README.md
+++ b/packages/react-router-ssr-query/README.md
@@ -2,7 +2,7 @@
 
 # TanStack React Router
 
-![TanStack Router Header](https://github.com/tanstack/router/raw/main/media/header_router.png)
+![TanStack Router Header](https://raw.githubusercontent.com/TanStack/router/main/media/header_router.png)
 
 🤖 Type-safe router w/ built-in caching & URL state management for React!
 
@@ -16,9 +16,9 @@
   <img alt="" src="https://badgen.net/bundlephobia/minzip/@tanstack/react-router" />
 </a><a href="#badge">
     <img alt="semantic-release" src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg">
-  </a><a href="https://github.com/tanstack/router/discussions">
+  </a><a href="https://github.com/TanStack/router/discussions">
   <img alt="Join the discussion on Github" src="https://img.shields.io/badge/Github%20Discussions%20%26%20Support-Chat%20now!-blue" />
-</a><a href="https://bestofjs.org/projects/router"><img alt="Best of JS" src="https://img.shields.io/endpoint?url=https://bestofjs-serverless.now.sh/api/project-badge?fullName=tanstack%2Frouter%26since=daily" /></a><a href="https://github.com/tanstack/router" target="\_parent">
+</a><a href="https://bestofjs.org/projects/router"><img alt="Best of JS" src="https://img.shields.io/endpoint?url=https://bestofjs-serverless.now.sh/api/project-badge?fullName=tanstack%2Frouter%26since=daily" /></a><a href="https://github.com/TanStack/router" target="\_parent">
   <img alt="" src="https://img.shields.io/github/stars/tanstack/router.svg?style=social&label=Star" />
 </a><a href="https://twitter.com/tan_stack" target="\_parent">
   <img alt="" src="https://img.shields.io/twitter/follow/tan_stack.svg?style=social&label=Follow @TanStack" />
@@ -26,6 +26,6 @@
   <img alt="" src="https://img.shields.io/twitter/follow/tannerlinsley.svg?style=social&label=Follow @TannerLinsley" />
 </a>
 
-Enjoy this library? Try the entire [TanStack](https://tanstack.com)! [React Query](https://github.com/tannerlinsley/react-query), [React Table](https://github.com/tanstack/react-table), [React Charts](https://github.com/tannerlinsley/react-charts), [React Virtual](https://github.com/tannerlinsley/react-virtual)
+Enjoy this library? Try the entire [TanStack](https://tanstack.com)! [React Query](https://github.com/TanStack/query), [React Table](https://github.com/TanStack/table), [React Charts](https://github.com/TanStack/react-charts), [React Virtual](https://github.com/TanStack/virtual)
 
 ## Visit [tanstack.com/router](https://tanstack.com/router) for docs, guides, API and more!
diff --git a/packages/react-router-ssr-query/package.json b/packages/react-router-ssr-query/package.json
index 2057ddab35..1aa80a7f5d 100644
--- a/packages/react-router-ssr-query/package.json
+++ b/packages/react-router-ssr-query/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/react-router-ssr-query",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/react-router/README.md b/packages/react-router/README.md
index 1cc3471e0a..0a19fd3b81 100644
--- a/packages/react-router/README.md
+++ b/packages/react-router/README.md
@@ -2,7 +2,7 @@
 
 # TanStack React Router
 
-![TanStack Router Header](https://github.com/tanstack/router/raw/main/media/header_router.png)
+![TanStack Router Header](https://raw.githubusercontent.com/TanStack/router/main/media/header_router.png)
 
 🤖 Type-safe router w/ built-in caching & URL state management for React!
 
@@ -16,9 +16,9 @@
   <img alt="" src="https://badgen.net/bundlephobia/minzip/@tanstack/react-router" />
 </a><a href="#badge">
     <img alt="semantic-release" src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg">
-  </a><a href="https://github.com/tanstack/router/discussions">
+  </a><a href="https://github.com/TanStack/router/discussions">
   <img alt="Join the discussion on Github" src="https://img.shields.io/badge/Github%20Discussions%20%26%20Support-Chat%20now!-blue" />
-</a><a href="https://bestofjs.org/projects/router"><img alt="Best of JS" src="https://img.shields.io/endpoint?url=https://bestofjs-serverless.now.sh/api/project-badge?fullName=tanstack%2Frouter%26since=daily" /></a><a href="https://github.com/tanstack/router" target="\_parent">
+</a><a href="https://bestofjs.org/projects/router"><img alt="Best of JS" src="https://img.shields.io/endpoint?url=https://bestofjs-serverless.now.sh/api/project-badge?fullName=tanstack%2Frouter%26since=daily" /></a><a href="https://github.com/TanStack/router" target="\_parent">
   <img alt="" src="https://img.shields.io/github/stars/tanstack/router.svg?style=social&label=Star" />
 </a><a href="https://twitter.com/tan_stack" target="\_parent">
   <img alt="" src="https://img.shields.io/twitter/follow/tan_stack.svg?style=social&label=Follow @TanStack" />
@@ -26,6 +26,6 @@
   <img alt="" src="https://img.shields.io/twitter/follow/tannerlinsley.svg?style=social&label=Follow @TannerLinsley" />
 </a>
 
-Enjoy this library? Try the entire [TanStack](https://tanstack.com)! [React Query](https://github.com/tannerlinsley/react-query), [React Table](https://github.com/tanstack/react-table), [React Charts](https://github.com/tannerlinsley/react-charts), [React Virtual](https://github.com/tannerlinsley/react-virtual)
+Enjoy this library? Try the entire [TanStack](https://tanstack.com)! [React Query](https://github.com/TanStack/query), [React Table](https://github.com/TanStack/table), [React Charts](https://github.com/TanStack/react-charts), [React Virtual](https://github.com/TanStack/virtual)
 
 ## Visit [tanstack.com/router](https://tanstack.com/router) for docs, guides, API and more!
diff --git a/packages/react-router/package.json b/packages/react-router/package.json
index e726ccf8b8..fc516c16b5 100644
--- a/packages/react-router/package.json
+++ b/packages/react-router/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/react-router",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/react-router/src/Asset.tsx b/packages/react-router/src/Asset.tsx
index 7a81b87f17..032b160656 100644
--- a/packages/react-router/src/Asset.tsx
+++ b/packages/react-router/src/Asset.tsx
@@ -49,8 +49,15 @@ function Script({
   children?: string
 }) {
   const router = useRouter()
+  const dataScript =
+    typeof attrs?.type === 'string' &&
+    attrs.type !== '' &&
+    attrs.type !== 'text/javascript' &&
+    attrs.type !== 'module'
 
   React.useEffect(() => {
+    if (dataScript) return
+
     if (attrs?.src) {
       const normSrc = (() => {
         try {
@@ -142,10 +149,20 @@ function Script({
     }
 
     return undefined
-  }, [attrs, children])
+  }, [attrs, children, dataScript])
 
   if (!(isServer ?? router.isServer)) {
-    const { src, ...rest } = attrs || {}
+    if (dataScript && typeof children === 'string') {
+      return (
+        <script
+          {...attrs}
+          suppressHydrationWarning
+          dangerouslySetInnerHTML={{ __html: children }}
+        />
+      )
+    }
+
+    const { src: _src, async: _async, defer: _defer, ...rest } = attrs || {}
     // render an empty script on the client just to avoid hydration errors
     return (
       <script
diff --git a/packages/react-router/src/index.tsx b/packages/react-router/src/index.tsx
index 3ed13c09c9..4fab2178e4 100644
--- a/packages/react-router/src/index.tsx
+++ b/packages/react-router/src/index.tsx
@@ -243,7 +243,12 @@ export { useMatch } from './useMatch'
 export { useLoaderDeps } from './useLoaderDeps'
 export { useLoaderData } from './useLoaderData'
 
-export { redirect, isRedirect, createRouterConfig } from '@tanstack/router-core'
+export {
+  redirect,
+  isRedirect,
+  createRouterConfig,
+  DEFAULT_PROTOCOL_ALLOWLIST,
+} from '@tanstack/router-core'
 
 export {
   RouteApi,
diff --git a/packages/react-router/src/link.tsx b/packages/react-router/src/link.tsx
index 2fb69f8b52..60088cd1cb 100644
--- a/packages/react-router/src/link.tsx
+++ b/packages/react-router/src/link.tsx
@@ -118,7 +118,7 @@ export function useLinkProps<
     ) {
       try {
         new URL(to)
-        if (isDangerousProtocol(to)) {
+        if (isDangerousProtocol(to, router.protocolAllowlist)) {
           if (process.env.NODE_ENV !== 'production') {
             console.warn(`Blocked Link with dangerous protocol: ${to}`)
           }
@@ -170,7 +170,7 @@ export function useLinkProps<
 
     const externalLink = (() => {
       if (hrefOption?.external) {
-        if (isDangerousProtocol(hrefOption.href)) {
+        if (isDangerousProtocol(hrefOption.href, router.protocolAllowlist)) {
           if (process.env.NODE_ENV !== 'production') {
             console.warn(
               `Blocked Link with dangerous protocol: ${hrefOption.href}`,
@@ -187,7 +187,7 @@ export function useLinkProps<
       if (typeof to === 'string' && to.indexOf(':') > -1) {
         try {
           new URL(to)
-          if (isDangerousProtocol(to)) {
+          if (isDangerousProtocol(to, router.protocolAllowlist)) {
             if (process.env.NODE_ENV !== 'production') {
               console.warn(`Blocked Link with dangerous protocol: ${to}`)
             }
@@ -438,7 +438,7 @@ export function useLinkProps<
   const externalLink = React.useMemo(() => {
     if (hrefOption?.external) {
       // Block dangerous protocols for external links
-      if (isDangerousProtocol(hrefOption.href)) {
+      if (isDangerousProtocol(hrefOption.href, router.protocolAllowlist)) {
         if (process.env.NODE_ENV !== 'production') {
           console.warn(
             `Blocked Link with dangerous protocol: ${hrefOption.href}`,
@@ -453,8 +453,8 @@ export function useLinkProps<
     if (typeof to !== 'string' || to.indexOf(':') === -1) return undefined
     try {
       new URL(to as any)
-      // Block dangerous protocols like javascript:, data:, vbscript:
-      if (isDangerousProtocol(to)) {
+      // Block dangerous protocols like javascript:, blob:, data:
+      if (isDangerousProtocol(to, router.protocolAllowlist)) {
         if (process.env.NODE_ENV !== 'production') {
           console.warn(`Blocked Link with dangerous protocol: ${to}`)
         }
@@ -463,7 +463,7 @@ export function useLinkProps<
       return to
     } catch {}
     return undefined
-  }, [to, hrefOption])
+  }, [to, hrefOption, router.protocolAllowlist])
 
   // eslint-disable-next-line react-hooks/rules-of-hooks
   const isActive = useRouterState({
diff --git a/packages/react-router/tests/Scripts.test.tsx b/packages/react-router/tests/Scripts.test.tsx
index 315b3e528e..e930b1dc1f 100644
--- a/packages/react-router/tests/Scripts.test.tsx
+++ b/packages/react-router/tests/Scripts.test.tsx
@@ -124,6 +124,114 @@ describe('ssr scripts', () => {
   })
 })
 
+describe('scripts with async/defer attributes', () => {
+  test('server renders scripts with async/defer attributes in output', async () => {
+    const rootRoute = createRootRoute({
+      scripts: () => [
+        {
+          src: 'script.js',
+          async: true,
+        },
+        {
+          src: 'script2.js',
+          defer: true,
+        },
+      ],
+      component: () => {
+        return (
+          <div>
+            <div data-testid="server-root">root</div>
+            <Outlet />
+            <Scripts />
+          </div>
+        )
+      },
+    })
+
+    const indexRoute = createRoute({
+      path: '/',
+      getParentRoute: () => rootRoute,
+      component: () => {
+        return <div data-testid="server-index">index</div>
+      },
+    })
+
+    const router = createRouter({
+      history: createMemoryHistory({
+        initialEntries: ['/'],
+      }),
+      routeTree: rootRoute.addChildren([indexRoute]),
+      isServer: true,
+    })
+
+    await router.load()
+
+    // Use ReactDOMServer.renderToString to test actual server output
+    const html = ReactDOMServer.renderToString(
+      <RouterProvider router={router} />,
+    )
+
+    expect(html).toMatch(/<script[^>]*src="script\.js"[^>]*async=""/)
+    expect(html).toMatch(/<script[^>]*src="script2\.js"[^>]*defer=""/)
+  })
+
+  test('client renders scripts without async/defer on placeholder', async () => {
+    const rootRoute = createRootRoute({
+      scripts: () => [
+        {
+          src: 'script.js',
+          async: true,
+          crossOrigin: 'anonymous',
+        },
+      ],
+      component: () => {
+        return (
+          <div>
+            <div data-testid="async-root">root</div>
+            <Outlet />
+            <Scripts />
+          </div>
+        )
+      },
+    })
+
+    const indexRoute = createRoute({
+      path: '/',
+      getParentRoute: () => rootRoute,
+      component: () => {
+        return <div data-testid="async-index">index</div>
+      },
+    })
+
+    const router = createRouter({
+      history: createMemoryHistory({
+        initialEntries: ['/'],
+      }),
+      routeTree: rootRoute.addChildren([indexRoute]),
+      isServer: false, // Client-side rendering
+    })
+
+    await router.load()
+
+    const { container } = await act(() =>
+      render(<RouterProvider router={router} />),
+    )
+
+    expect(await screen.findByTestId('async-root')).toBeInTheDocument()
+
+    const script = container.querySelector('script')
+    expect(script).toBeTruthy()
+
+    // async and defer should NOT be on the client placeholder
+    expect(script?.hasAttribute('async')).toBe(false)
+    expect(script?.hasAttribute('defer')).toBe(false)
+
+    expect(script?.getAttribute('crossorigin')).toBe('anonymous')
+
+    expect(script?.hasAttribute('src')).toBe(false)
+  })
+})
+
 describe('ssr HeadContent', () => {
   test('derives title, dedupes meta, and allows non-loader HeadContent', async () => {
     const rootRoute = createRootRoute({
@@ -221,3 +329,351 @@ describe('ssr HeadContent', () => {
     )
   })
 })
+
+describe('data script rendering', () => {
+  test('data script renders content on server (SSR)', async () => {
+    const jsonLd = JSON.stringify({
+      '@context': 'https://schema.org',
+      '@type': 'Article',
+      headline: 'Test Article',
+    })
+
+    const rootRoute = createRootRoute({
+      scripts: () => [
+        {
+          type: 'application/ld+json',
+          children: jsonLd,
+        },
+      ],
+      component: () => {
+        return (
+          <div>
+            <div data-testid="ssr-root">root</div>
+            <Outlet />
+            <Scripts />
+          </div>
+        )
+      },
+    })
+
+    const indexRoute = createRoute({
+      path: '/',
+      getParentRoute: () => rootRoute,
+    })
+
+    const router = createRouter({
+      history: createMemoryHistory({
+        initialEntries: ['/'],
+      }),
+      routeTree: rootRoute.addChildren([indexRoute]),
+      isServer: true,
+    })
+
+    await router.load()
+
+    const html = ReactDOMServer.renderToString(
+      <RouterProvider router={router} />,
+    )
+
+    expect(html).toContain('application/ld+json')
+    expect(html).toContain(jsonLd)
+  })
+
+  test('data script preserves content on client', async () => {
+    const jsonLd = JSON.stringify({
+      '@context': 'https://schema.org',
+      '@type': 'WebSite',
+      name: 'Test',
+    })
+
+    const rootRoute = createRootRoute({
+      scripts: () => [
+        {
+          type: 'application/ld+json',
+          children: jsonLd,
+        },
+      ],
+      component: () => {
+        return (
+          <div>
+            <div data-testid="data-client-root">root</div>
+            <Outlet />
+            <Scripts />
+          </div>
+        )
+      },
+    })
+
+    const indexRoute = createRoute({
+      path: '/',
+      getParentRoute: () => rootRoute,
+    })
+
+    const router = createRouter({
+      history: createMemoryHistory({
+        initialEntries: ['/'],
+      }),
+      routeTree: rootRoute.addChildren([indexRoute]),
+    })
+
+    await router.load()
+
+    const { container } = await act(() =>
+      render(<RouterProvider router={router} />),
+    )
+
+    const rootEl = container.querySelector('[data-testid="data-client-root"]')
+    expect(rootEl).not.toBeNull()
+
+    const scriptEl = container.querySelector(
+      'script[type="application/ld+json"]',
+    )
+    expect(scriptEl).not.toBeNull()
+    expect(scriptEl!.innerHTML).toBe(jsonLd)
+  })
+
+  test('executable script still renders empty on client', async () => {
+    const rootRoute = createRootRoute({
+      scripts: () => [
+        {
+          children: 'console.log("hello")',
+        },
+      ],
+      component: () => {
+        return (
+          <div>
+            <div data-testid="exec-root">root</div>
+            <Outlet />
+            <Scripts />
+          </div>
+        )
+      },
+    })
+
+    const indexRoute = createRoute({
+      path: '/',
+      getParentRoute: () => rootRoute,
+    })
+
+    const router = createRouter({
+      history: createMemoryHistory({
+        initialEntries: ['/'],
+      }),
+      routeTree: rootRoute.addChildren([indexRoute]),
+    })
+
+    await router.load()
+
+    const { container } = await act(() =>
+      render(<RouterProvider router={router} />),
+    )
+
+    const rootEl = container.querySelector('[data-testid="exec-root"]')
+    expect(rootEl).not.toBeNull()
+
+    const scripts = container.querySelectorAll('script:not([type])')
+    const inlineScript = Array.from(scripts).find((s) => !s.hasAttribute('src'))
+    expect(inlineScript).not.toBeNull()
+    // Executable scripts should render empty (content applied via useEffect)
+    expect(inlineScript!.innerHTML).toBe('')
+  })
+
+  test('module script still renders empty on client', async () => {
+    const rootRoute = createRootRoute({
+      scripts: () => [
+        {
+          type: 'module',
+          children: 'import { foo } from "./foo.js"',
+        },
+      ],
+      component: () => {
+        return (
+          <div>
+            <div data-testid="module-root">root</div>
+            <Outlet />
+            <Scripts />
+          </div>
+        )
+      },
+    })
+
+    const indexRoute = createRoute({
+      path: '/',
+      getParentRoute: () => rootRoute,
+    })
+
+    const router = createRouter({
+      history: createMemoryHistory({
+        initialEntries: ['/'],
+      }),
+      routeTree: rootRoute.addChildren([indexRoute]),
+    })
+
+    await router.load()
+
+    const { container } = await act(() =>
+      render(<RouterProvider router={router} />),
+    )
+
+    const rootEl = container.querySelector('[data-testid="module-root"]')
+    expect(rootEl).not.toBeNull()
+
+    const moduleScript = container.querySelector('script[type="module"]')
+    expect(moduleScript).not.toBeNull()
+    // Module scripts should render empty (content applied via useEffect)
+    expect(moduleScript!.innerHTML).toBe('')
+  })
+
+  test('application/json data script preserves content', async () => {
+    const jsonData = JSON.stringify({ config: { theme: 'dark' } })
+
+    const rootRoute = createRootRoute({
+      scripts: () => [
+        {
+          type: 'application/json',
+          children: jsonData,
+        },
+      ],
+      component: () => {
+        return (
+          <div>
+            <div data-testid="json-root">root</div>
+            <Outlet />
+            <Scripts />
+          </div>
+        )
+      },
+    })
+
+    const indexRoute = createRoute({
+      path: '/',
+      getParentRoute: () => rootRoute,
+    })
+
+    const router = createRouter({
+      history: createMemoryHistory({
+        initialEntries: ['/'],
+      }),
+      routeTree: rootRoute.addChildren([indexRoute]),
+    })
+
+    await router.load()
+
+    const { container } = await act(() =>
+      render(<RouterProvider router={router} />),
+    )
+
+    const rootEl = container.querySelector('[data-testid="json-root"]')
+    expect(rootEl).not.toBeNull()
+
+    const scriptEl = container.querySelector('script[type="application/json"]')
+    expect(scriptEl).not.toBeNull()
+    expect(scriptEl!.innerHTML).toBe(jsonData)
+  })
+
+  test('data script does not duplicate into document.head', async () => {
+    const jsonLd = JSON.stringify({
+      '@context': 'https://schema.org',
+      '@type': 'Organization',
+      name: 'Test Org',
+    })
+
+    const rootRoute = createRootRoute({
+      scripts: () => [
+        {
+          type: 'application/ld+json',
+          children: jsonLd,
+        },
+      ],
+      component: () => {
+        return (
+          <div>
+            <div data-testid="dup-root">root</div>
+            <Outlet />
+            <Scripts />
+          </div>
+        )
+      },
+    })
+
+    const indexRoute = createRoute({
+      path: '/',
+      getParentRoute: () => rootRoute,
+    })
+
+    const router = createRouter({
+      history: createMemoryHistory({
+        initialEntries: ['/'],
+      }),
+      routeTree: rootRoute.addChildren([indexRoute]),
+    })
+
+    await router.load()
+
+    const { container } = await act(() =>
+      render(<RouterProvider router={router} />),
+    )
+
+    const rootEl = container.querySelector('[data-testid="dup-root"]')
+    expect(rootEl).not.toBeNull()
+
+    // Data scripts should NOT be duplicated into document.head by useEffect
+    const headScripts = document.head.querySelectorAll(
+      'script[type="application/ld+json"]',
+    )
+    expect(headScripts.length).toBe(0)
+
+    // Should only exist once in the container
+    const containerScripts = container.querySelectorAll(
+      'script[type="application/ld+json"]',
+    )
+    expect(containerScripts.length).toBe(1)
+    expect(containerScripts[0]!.innerHTML).toBe(jsonLd)
+  })
+
+  test('empty string type is treated as executable, not data script', async () => {
+    const rootRoute = createRootRoute({
+      scripts: () => [
+        {
+          type: '',
+          children: 'console.log("empty type")',
+        },
+      ],
+      component: () => {
+        return (
+          <div>
+            <div data-testid="empty-type-root">root</div>
+            <Outlet />
+            <Scripts />
+          </div>
+        )
+      },
+    })
+
+    const indexRoute = createRoute({
+      path: '/',
+      getParentRoute: () => rootRoute,
+    })
+
+    const router = createRouter({
+      history: createMemoryHistory({
+        initialEntries: ['/'],
+      }),
+      routeTree: rootRoute.addChildren([indexRoute]),
+    })
+
+    await router.load()
+
+    const { container } = await act(() =>
+      render(<RouterProvider router={router} />),
+    )
+
+    const rootEl = container.querySelector('[data-testid="empty-type-root"]')
+    expect(rootEl).not.toBeNull()
+
+    const scriptEl = container.querySelector('script[type=""]')
+    expect(scriptEl).not.toBeNull()
+    // Empty type = text/javascript per HTML spec, should render empty like executable scripts
+    expect(scriptEl!.innerHTML).toBe('')
+  })
+})
diff --git a/packages/react-router/tests/link.test.tsx b/packages/react-router/tests/link.test.tsx
index eaefd2d899..da7078f785 100644
--- a/packages/react-router/tests/link.test.tsx
+++ b/packages/react-router/tests/link.test.tsx
@@ -6613,3 +6613,66 @@ describe('encoded and unicode paths', () => {
     },
   )
 })
+
+describe('protocolAllowlist', () => {
+  const rootRoute = createRootRoute()
+  const indexRoute = createRoute({
+    getParentRoute: () => rootRoute,
+    path: '/',
+    component: () => (
+      <>
+        <Link to="x-safari-https://example.com" />
+        <Link
+          to="intent://example.com#Intent;scheme=https;end"
+          reloadDocument
+        />
+      </>
+    ),
+  })
+
+  let consoleWarn = vi.fn()
+  beforeEach(() => {
+    consoleWarn = vi.fn()
+    vi.spyOn(console, 'warn').mockImplementation(consoleWarn)
+  })
+  afterEach(() => {
+    vi.restoreAllMocks()
+  })
+
+  it('should work like normal links when protocolAllowlist is set', async () => {
+    const router = createRouter({
+      routeTree: rootRoute.addChildren([indexRoute]),
+      history,
+      protocolAllowlist: ['x-safari-https:', 'intent:'],
+    })
+    render(<RouterProvider router={router} />)
+    const links = await screen.findAllByRole('link')
+    expect(links[0]).toHaveAttribute('href', 'x-safari-https://example.com')
+    expect(links[1]).toHaveAttribute(
+      'href',
+      'intent://example.com#Intent;scheme=https;end',
+    )
+    expect(consoleWarn).not.toHaveBeenCalled()
+  })
+
+  it('should fallback to relative links when protocol is not in allowlist', async () => {
+    const router = createRouter({
+      routeTree: rootRoute.addChildren([indexRoute]),
+      history,
+      protocolAllowlist: [],
+    })
+    render(<RouterProvider router={router} />)
+    const links = await screen.findAllByRole('link')
+    expect(links[0]).toHaveAttribute('href', '/x-safari-https:/example.com')
+    expect(links[1]).toHaveAttribute(
+      'href',
+      '/intent:/example.com#Intent;scheme=https;end',
+    )
+    expect(consoleWarn).toHaveBeenCalledWith(
+      'Blocked Link with dangerous protocol: x-safari-https://example.com',
+    )
+    expect(consoleWarn).toHaveBeenCalledWith(
+      'Blocked Link with dangerous protocol: intent://example.com#Intent;scheme=https;end',
+    )
+  })
+})
diff --git a/packages/react-router/tests/loaders.test.tsx b/packages/react-router/tests/loaders.test.tsx
index fc9e87b077..d9b5968d72 100644
--- a/packages/react-router/tests/loaders.test.tsx
+++ b/packages/react-router/tests/loaders.test.tsx
@@ -824,3 +824,119 @@ test('cancelMatches after pending timeout', async () => {
   expect(fooPendingComponentOnMountMock).toHaveBeenCalled()
   expect(onAbortMock).toHaveBeenCalled()
 })
+
+test('reproducer for #6388 - rapid navigation between parameterized routes should not trigger errorComponent', async () => {
+  const errorComponentRenderCount = vi.fn()
+  const onAbortMock = vi.fn()
+  const loaderCompleteMock = vi.fn()
+
+  const rootRoute = createRootRoute({
+    component: () => (
+      <div>
+        <Link data-testid="link-to-home" to="/">
+          Home
+        </Link>
+        <Link
+          data-testid="link-to-param-1"
+          to="/something/$id"
+          params={{ id: '1' }}
+          preload={false}
+        >
+          Param 1
+        </Link>
+        <Link
+          data-testid="link-to-param-2"
+          to="/something/$id"
+          params={{ id: '2' }}
+          preload={false}
+        >
+          Param 2
+        </Link>
+        <Outlet />
+      </div>
+    ),
+  })
+
+  const indexRoute = createRoute({
+    getParentRoute: () => rootRoute,
+    path: '/',
+    component: () => <div data-testid="home-page">Home page</div>,
+  })
+
+  const paramRoute = createRoute({
+    getParentRoute: () => rootRoute,
+    path: '/something/$id',
+    pendingMs: 0,
+    loader: async ({ params, abortController }) => {
+      const result = await new Promise<{ id: string; done: boolean }>(
+        (resolve, reject) => {
+          const timer = setTimeout(() => {
+            loaderCompleteMock(params.id)
+            resolve({ id: params.id, done: true })
+          }, WAIT_TIME * 5)
+
+          abortController.signal.addEventListener('abort', () => {
+            clearTimeout(timer)
+            onAbortMock(params.id)
+            reject(new DOMException('Aborted', 'AbortError'))
+          })
+        },
+      )
+
+      return result
+    },
+    component: () => {
+      const data = paramRoute.useLoaderData()
+      return (
+        <div data-testid="param-page">
+          Param Component {data.id} {data.done ? 'Done' : 'Not done'}
+        </div>
+      )
+    },
+    errorComponent: ({ error }) => {
+      errorComponentRenderCount(error)
+      return (
+        <div data-testid="error-component">
+          Error Component: {error.message} | Name: {error.name}
+        </div>
+      )
+    },
+    pendingComponent: () => <div data-testid="pending-component">Pending</div>,
+  })
+
+  const routeTree = rootRoute.addChildren([indexRoute, paramRoute])
+  const router = createRouter({
+    routeTree,
+    history,
+    defaultPreload: false,
+  })
+
+  render(<RouterProvider router={router} />)
+  await act(() => router.latestLoadPromise)
+
+  const pendingComponent = screen.findByTestId('pending-component')
+  expect(await screen.findByTestId('home-page')).toBeInTheDocument()
+
+  const param1Link = await screen.findByTestId('link-to-param-1')
+  fireEvent.click(param1Link)
+  expect(await pendingComponent).toBeInTheDocument()
+
+  const param2Link = await screen.findByTestId('link-to-param-2')
+  fireEvent.click(param2Link)
+  expect(await pendingComponent).toBeInTheDocument()
+
+  fireEvent.click(param1Link)
+  expect(await pendingComponent).toBeInTheDocument()
+
+  await act(() => router.latestLoadPromise)
+
+  expect(onAbortMock).toHaveBeenCalled()
+  expect(errorComponentRenderCount).not.toHaveBeenCalled()
+  expect(screen.queryByTestId('error-component')).not.toBeInTheDocument()
+  expect(await pendingComponent).not.toBeInTheDocument()
+
+  const paramPage = await screen.findByTestId('param-page')
+  expect(paramPage).toBeInTheDocument()
+  expect(paramPage).toHaveTextContent('Param Component 1 Done')
+  expect(loaderCompleteMock).toHaveBeenCalled()
+})
diff --git a/packages/react-router/tests/router.test.tsx b/packages/react-router/tests/router.test.tsx
index 052dafa377..61f5370c03 100644
--- a/packages/react-router/tests/router.test.tsx
+++ b/packages/react-router/tests/router.test.tsx
@@ -2484,6 +2484,255 @@ describe('statusCode', () => {
   )
 })
 
+describe('notFound in beforeLoad with pendingComponent', () => {
+  it('should transition router.state.status to idle when child beforeLoad throws notFound and parent has pendingComponent with pendingMs: 0', async () => {
+    const history = createMemoryHistory({ initialEntries: ['/'] })
+
+    const rootRoute = createRootRoute({
+      component: () => <Outlet />,
+      notFoundComponent: () => (
+        <div data-testid="root-not-found">Root Not Found</div>
+      ),
+    })
+
+    const indexRoute = createRoute({
+      getParentRoute: () => rootRoute,
+      path: '/',
+      component: () => (
+        <div data-testid="home-page">
+          <Link to="/parent/child">Go to child</Link>
+        </div>
+      ),
+    })
+
+    const parentRoute = createRoute({
+      getParentRoute: () => rootRoute,
+      path: '/parent',
+      pendingMs: 0,
+      pendingComponent: () => (
+        <div data-testid="pending-component">Loading...</div>
+      ),
+      component: () => (
+        <div data-testid="parent-component">
+          Parent
+          <Outlet />
+        </div>
+      ),
+      notFoundComponent: () => (
+        <div data-testid="parent-not-found">Parent Not Found</div>
+      ),
+    })
+
+    const childRoute = createRoute({
+      getParentRoute: () => parentRoute,
+      path: '/child',
+      beforeLoad: () => {
+        throw notFound()
+      },
+      component: () => <div data-testid="child-component">Child</div>,
+    })
+
+    const routeTree = rootRoute.addChildren([
+      indexRoute,
+      parentRoute.addChildren([childRoute]),
+    ])
+    const router = createRouter({ routeTree, history })
+
+    render(<RouterProvider router={router} />)
+
+    // Wait for initial load
+    await act(() => router.latestLoadPromise)
+    expect(router.state.status).toBe('idle')
+    expect(screen.getByTestId('home-page')).toBeInTheDocument()
+
+    // Navigate to the child route that throws notFound in beforeLoad
+    await act(() => router.navigate({ to: '/parent/child' }))
+
+    // The router status should eventually become idle
+    await waitFor(() => {
+      expect(router.state.status).toBe('idle')
+    })
+
+    expect(router.state.statusCode).toBe(404)
+  })
+
+  it('should transition router.state.status to idle when child beforeLoad throws notFound and parent has NO pendingComponent', async () => {
+    const history = createMemoryHistory({ initialEntries: ['/'] })
+
+    const rootRoute = createRootRoute({
+      notFoundComponent: () => (
+        <div data-testid="root-not-found">Root Not Found</div>
+      ),
+    })
+
+    const indexRoute = createRoute({
+      getParentRoute: () => rootRoute,
+      path: '/',
+      component: () => <div data-testid="home-page">Home</div>,
+    })
+
+    // Direct child of root (no intermediate parent)
+    const childRoute = createRoute({
+      getParentRoute: () => rootRoute,
+      path: '/child',
+      beforeLoad: () => {
+        throw notFound()
+      },
+      component: () => <div data-testid="child-component">Child</div>,
+      notFoundComponent: () => (
+        <div data-testid="child-not-found">Child Not Found</div>
+      ),
+    })
+
+    const routeTree = rootRoute.addChildren([indexRoute, childRoute])
+    const router = createRouter({ routeTree, history })
+
+    render(<RouterProvider router={router} />)
+
+    await act(() => router.latestLoadPromise)
+    expect(router.state.status).toBe('idle')
+
+    await act(() => router.navigate({ to: '/child' }))
+
+    await waitFor(() => {
+      expect(router.state.status).toBe('idle')
+    })
+
+    expect(router.state.statusCode).toBe(404)
+  })
+
+  it('should transition router.state.status to idle when nested child beforeLoad throws notFound WITHOUT pendingComponent', async () => {
+    const history = createMemoryHistory({ initialEntries: ['/'] })
+
+    const rootRoute = createRootRoute({
+      component: () => <Outlet />,
+      notFoundComponent: () => (
+        <div data-testid="root-not-found">Root Not Found</div>
+      ),
+    })
+
+    const indexRoute = createRoute({
+      getParentRoute: () => rootRoute,
+      path: '/',
+      component: () => <div data-testid="home-page">Home</div>,
+    })
+
+    const parentRoute = createRoute({
+      getParentRoute: () => rootRoute,
+      path: '/parent',
+      component: () => (
+        <div data-testid="parent-component">
+          Parent
+          <Outlet />
+        </div>
+      ),
+      notFoundComponent: () => (
+        <div data-testid="parent-not-found">Parent Not Found</div>
+      ),
+    })
+
+    const childRoute = createRoute({
+      getParentRoute: () => parentRoute,
+      path: '/child',
+      beforeLoad: () => {
+        throw notFound()
+      },
+      component: () => <div data-testid="child-component">Child</div>,
+    })
+
+    const routeTree = rootRoute.addChildren([
+      indexRoute,
+      parentRoute.addChildren([childRoute]),
+    ])
+    const router = createRouter({ routeTree, history })
+
+    render(<RouterProvider router={router} />)
+
+    await act(() => router.latestLoadPromise)
+    expect(router.state.status).toBe('idle')
+
+    await act(() => router.navigate({ to: '/parent/child' }))
+
+    await waitFor(() => {
+      expect(router.state.status).toBe('idle')
+    })
+
+    expect(router.state.statusCode).toBe(404)
+  })
+
+  it('should transition router.state.status to idle when child async beforeLoad throws notFound and parent has pendingComponent with pendingMs: 0', async () => {
+    const history = createMemoryHistory({ initialEntries: ['/'] })
+
+    const rootRoute = createRootRoute({
+      component: () => <Outlet />,
+      notFoundComponent: () => (
+        <div data-testid="root-not-found">Root Not Found</div>
+      ),
+    })
+
+    const indexRoute = createRoute({
+      getParentRoute: () => rootRoute,
+      path: '/',
+      component: () => (
+        <div data-testid="home-page">
+          <Link to="/parent/child">Go to child</Link>
+        </div>
+      ),
+    })
+
+    const parentRoute = createRoute({
+      getParentRoute: () => rootRoute,
+      path: '/parent',
+      pendingMs: 0,
+      pendingComponent: () => (
+        <div data-testid="pending-component">Loading...</div>
+      ),
+      component: () => (
+        <div data-testid="parent-component">
+          Parent
+          <Outlet />
+        </div>
+      ),
+      notFoundComponent: () => (
+        <div data-testid="parent-not-found">Parent Not Found</div>
+      ),
+    })
+
+    const childRoute = createRoute({
+      getParentRoute: () => parentRoute,
+      path: '/child',
+      beforeLoad: async () => {
+        await new Promise((resolve) => setTimeout(resolve, 10))
+        throw notFound()
+      },
+      component: () => <div data-testid="child-component">Child</div>,
+    })
+
+    const routeTree = rootRoute.addChildren([
+      indexRoute,
+      parentRoute.addChildren([childRoute]),
+    ])
+    const router = createRouter({ routeTree, history })
+
+    render(<RouterProvider router={router} />)
+
+    // Wait for initial load
+    await act(() => router.latestLoadPromise)
+    expect(router.state.status).toBe('idle')
+    expect(screen.getByTestId('home-page')).toBeInTheDocument()
+
+    // Navigate to the child route that throws notFound in beforeLoad
+    await act(() => router.navigate({ to: '/parent/child' }))
+
+    // The router status should eventually become idle
+    await waitFor(() => {
+      expect(router.state.status).toBe('idle')
+    })
+
+    expect(router.state.statusCode).toBe(404)
+  })
+})
+
 describe('Router rewrite functionality', () => {
   it('should rewrite URLs using input before router interprets them', async () => {
     const rootRoute = createRootRoute({
diff --git a/packages/react-router/tests/useParams.test.tsx b/packages/react-router/tests/useParams.test.tsx
index 3c15aade31..bb06345850 100644
--- a/packages/react-router/tests/useParams.test.tsx
+++ b/packages/react-router/tests/useParams.test.tsx
@@ -248,3 +248,73 @@ test('useParams must return parsed result if applicable.', async () => {
   expect(paramPostIdValue.textContent).toBe('2')
   expect(mockedfn).toHaveBeenCalledTimes(1)
 })
+
+test('useParams({ strict: false }) returns parsed params after child navigation', async () => {
+  const rootRoute = createRootRoute()
+
+  const parentRoute = createRoute({
+    getParentRoute: () => rootRoute,
+    path: 'parent',
+    component: ParentComponent,
+  })
+
+  const versionRoute = createRoute({
+    getParentRoute: () => parentRoute,
+    path: '$version',
+    params: {
+      parse: (params) => ({
+        ...params,
+        version: parseInt(params.version),
+      }),
+      stringify: (params) => ({
+        ...params,
+        version: `${params.version}`,
+      }),
+    },
+    component: VersionComponent,
+  })
+
+  function ParentComponent() {
+    const { version } = useParams({ strict: false })
+
+    return (
+      <div>
+        <div data-testid="version-type">{typeof version}</div>
+        <div data-testid="version-value">{String(version)}</div>
+        <Link
+          data-testid="version-2-link"
+          to={versionRoute.fullPath}
+          params={{ version: 2 }}
+        >
+          Version 2
+        </Link>
+        <Outlet />
+      </div>
+    )
+  }
+
+  function VersionComponent() {
+    return <div data-testid="version-route">Version Route</div>
+  }
+
+  window.history.replaceState({}, '', '/parent/1')
+
+  const router = createRouter({
+    routeTree: rootRoute.addChildren([parentRoute.addChildren([versionRoute])]),
+  })
+
+  render(<RouterProvider router={router} />)
+
+  await act(() => router.load())
+
+  expect(await screen.findByTestId('version-type')).toHaveTextContent('number')
+  expect(await screen.findByTestId('version-value')).toHaveTextContent('1')
+
+  const version2Link = await screen.findByTestId('version-2-link')
+
+  await act(() => fireEvent.click(version2Link))
+
+  expect(await screen.findByTestId('version-route')).toBeInTheDocument()
+  expect(await screen.findByTestId('version-type')).toHaveTextContent('number')
+  expect(await screen.findByTestId('version-value')).toHaveTextContent('2')
+})
diff --git a/packages/react-start-client/package.json b/packages/react-start-client/package.json
index 44577722ed..6439720424 100644
--- a/packages/react-start-client/package.json
+++ b/packages/react-start-client/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/react-start-client",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/react-start-server/package.json b/packages/react-start-server/package.json
index a74c696ede..1f915df6ea 100644
--- a/packages/react-start-server/package.json
+++ b/packages/react-start-server/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/react-start-server",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/react-start/README.md b/packages/react-start/README.md
index 2504d3e4af..4ead3764b3 100644
--- a/packages/react-start/README.md
+++ b/packages/react-start/README.md
@@ -2,7 +2,7 @@
 
 # TanStack React Start
 
-![TanStack React Start Header](https://github.com/tanstack/router/raw/main/media/header_start.png)
+![TanStack React Start Header](https://raw.githubusercontent.com/TanStack/router/main/media/header_start.png)
 
 SSR, Streaming, Server Functions, API Routes, bundling and more powered by [TanStack Router](https://tanstack.com/router) and Vite. Ready to deploy to your favorite hosting provider.
 
@@ -21,13 +21,13 @@ SSR, Streaming, Server Functions, API Routes, bundling and more powered by [TanS
 <a href="#badge">
   <img alt="semantic-release" src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg">
 </a>
-<a href="https://github.com/tanstack/router/discussions">
+<a href="https://github.com/TanStack/router/discussions">
   <img alt="Join the discussion on Github" src="https://img.shields.io/badge/Github%20Discussions%20%26%20Support-Chat%20now!-blue" />
 </a>
 <a href="https://bestofjs.org/projects/router">
   <img alt="Best of JS" src="https://img.shields.io/endpoint?url=https://bestofjs-serverless.now.sh/api/project-badge?fullName=tanstack%2Frouter%26since=daily" />
 </a>
-<a href="https://github.com/tanstack/router" target="\_parent">
+<a href="https://github.com/TanStack/router" target="\_parent">
   <img alt="" src="https://img.shields.io/github/stars/tanstack/router.svg?style=social&label=Star" />
 </a>
 <a href="https://twitter.com/tan_stack" target="\_parent">
@@ -37,6 +37,6 @@ SSR, Streaming, Server Functions, API Routes, bundling and more powered by [TanS
   <img alt="" src="https://img.shields.io/twitter/follow/tannerlinsley.svg?style=social&label=Follow @TannerLinsley" />
 </a>
 
-Enjoy this library? Try the entire [TanStack](https://tanstack.com)! [React Query](https://github.com/tannerlinsley/react-query), [React Table](https://github.com/tanstack/react-table), [React Charts](https://github.com/tannerlinsley/react-charts), [React Virtual](https://github.com/tannerlinsley/react-virtual)
+Enjoy this library? Try the entire [TanStack](https://tanstack.com)! [React Query](https://github.com/TanStack/query), [React Table](https://github.com/TanStack/table), [React Charts](https://github.com/TanStack/react-charts), [React Virtual](https://github.com/TanStack/virtual)
 
 Visit [tanstack.com/start](https://tanstack.com/start) for docs, guides, API and more!
diff --git a/packages/react-start/package.json b/packages/react-start/package.json
index 233f53168a..1b1de1f21f 100644
--- a/packages/react-start/package.json
+++ b/packages/react-start/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/react-start",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/router-cli/package.json b/packages/router-cli/package.json
index 971e32e6a3..0996de2897 100644
--- a/packages/router-cli/package.json
+++ b/packages/router-cli/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/router-cli",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/router-core/package.json b/packages/router-core/package.json
index 5901f75d42..da3a5de444 100644
--- a/packages/router-core/package.json
+++ b/packages/router-core/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/router-core",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/router-core/src/index.ts b/packages/router-core/src/index.ts
index 1897f07880..bb82dc5a50 100644
--- a/packages/router-core/src/index.ts
+++ b/packages/router-core/src/index.ts
@@ -273,6 +273,7 @@ export {
   createControlledPromise,
   isModuleNotFoundError,
   decodePath,
+  DEFAULT_PROTOCOL_ALLOWLIST,
   escapeHtml,
   isDangerousProtocol,
   buildDevStylesUrl,
diff --git a/packages/router-core/src/load-matches.ts b/packages/router-core/src/load-matches.ts
index 5fdca06fc7..838d77e9d3 100644
--- a/packages/router-core/src/load-matches.ts
+++ b/packages/router-core/src/load-matches.ts
@@ -74,7 +74,11 @@ const buildMatchContext = (
   return context
 }
 
-const _handleNotFound = (inner: InnerLoadContext, err: NotFoundError) => {
+const _handleNotFound = (
+  inner: InnerLoadContext,
+  err: NotFoundError,
+  routerCode?: string,
+) => {
   // Find the route that should handle the not found error
   // First check if a specific route is requested to show the error
   const routeCursor =
@@ -90,11 +94,19 @@ const _handleNotFound = (inner: InnerLoadContext, err: NotFoundError) => {
     ).defaultNotFoundComponent
   }
 
-  // Ensure we have a notFoundComponent
-  invariant(
-    routeCursor.options.notFoundComponent,
-    'No notFoundComponent found. Please set a notFoundComponent on your route or provide a defaultNotFoundComponent to the router.',
-  )
+  // For BEFORE_LOAD errors that will walk up to a parent route,
+  // don't require notFoundComponent on the current (child) route —
+  // an ancestor will handle it. Only enforce the invariant when
+  // we've reached a route that won't walk up further.
+  const willWalkUp = routerCode === 'BEFORE_LOAD' && routeCursor.parentRoute
+
+  if (!willWalkUp) {
+    // Ensure we have a notFoundComponent
+    invariant(
+      routeCursor.options.notFoundComponent,
+      'No notFoundComponent found. Please set a notFoundComponent on your route or provide a defaultNotFoundComponent to the router.',
+    )
+  }
 
   // Find the match for this route
   const matchForRoute = inner.matches.find((m) => m.routeId === routeCursor.id)
@@ -109,9 +121,9 @@ const _handleNotFound = (inner: InnerLoadContext, err: NotFoundError) => {
     isFetching: false,
   }))
 
-  if ((err as any).routerCode === 'BEFORE_LOAD' && routeCursor.parentRoute) {
-    err.routeId = routeCursor.parentRoute.id
-    _handleNotFound(inner, err)
+  if (willWalkUp) {
+    err.routeId = routeCursor.parentRoute!.id
+    _handleNotFound(inner, err, routerCode)
   }
 }
 
@@ -119,6 +131,7 @@ const handleRedirectAndNotFound = (
   inner: InnerLoadContext,
   match: AnyRouteMatch | undefined,
   err: unknown,
+  routerCode?: string,
 ): void => {
   if (!isRedirect(err) && !isNotFound(err)) return
 
@@ -159,7 +172,7 @@ const handleRedirectAndNotFound = (
     err = inner.router.resolveRedirect(err)
     throw err
   } else {
-    _handleNotFound(inner, err)
+    _handleNotFound(inner, err, routerCode)
     throw err
   }
 }
@@ -199,13 +212,23 @@ const handleSerialError = (
 
   err.routerCode = routerCode
   inner.firstBadMatchIndex ??= index
-  handleRedirectAndNotFound(inner, inner.router.getMatch(matchId), err)
+  handleRedirectAndNotFound(
+    inner,
+    inner.router.getMatch(matchId),
+    err,
+    routerCode,
+  )
 
   try {
     route.options.onError?.(err)
   } catch (errorHandlerErr) {
     err = errorHandlerErr
-    handleRedirectAndNotFound(inner, inner.router.getMatch(matchId), err)
+    handleRedirectAndNotFound(
+      inner,
+      inner.router.getMatch(matchId),
+      err,
+      routerCode,
+    )
   }
 
   inner.updateMatch(matchId, (prev) => {
@@ -699,6 +722,11 @@ const runLoader = async (
       let error = e
 
       if ((error as any)?.name === 'AbortError') {
+        if (match.abortController.signal.aborted) {
+          match._nonReactive.loaderPromise?.resolve()
+          match._nonReactive.loaderPromise = undefined
+          return
+        }
         inner.updateMatch(matchId, (prev) => ({
           ...prev,
           status: prev.status === 'pending' ? 'success' : prev.status,
@@ -749,6 +777,56 @@ const loadRouteMatch = async (
   inner: InnerLoadContext,
   index: number,
 ): Promise<AnyRouteMatch> => {
+  async function handleLoader(
+    preload: boolean,
+    prevMatch: AnyRouteMatch,
+    match: AnyRouteMatch,
+    route: AnyRoute,
+  ) {
+    const age = Date.now() - prevMatch.updatedAt
+
+    const staleAge = preload
+      ? (route.options.preloadStaleTime ??
+        inner.router.options.defaultPreloadStaleTime ??
+        30_000) // 30 seconds for preloads by default
+      : (route.options.staleTime ?? inner.router.options.defaultStaleTime ?? 0)
+
+    const shouldReloadOption = route.options.shouldReload
+
+    // Default to reloading the route all the time
+    // Allow shouldReload to get the last say,
+    // if provided.
+    const shouldReload =
+      typeof shouldReloadOption === 'function'
+        ? shouldReloadOption(getLoaderContext(inner, matchId, index, route))
+        : shouldReloadOption
+
+    // If the route is successful and still fresh, just resolve
+    const { status, invalid } = match
+    loaderShouldRunAsync =
+      status === 'success' && (invalid || (shouldReload ?? age > staleAge))
+    if (preload && route.options.preload === false) {
+      // Do nothing
+    } else if (loaderShouldRunAsync && !inner.sync) {
+      loaderIsRunningAsync = true
+      ;(async () => {
+        try {
+          await runLoader(inner, matchId, index, route)
+          const match = inner.router.getMatch(matchId)!
+          match._nonReactive.loaderPromise?.resolve()
+          match._nonReactive.loadPromise?.resolve()
+          match._nonReactive.loaderPromise = undefined
+        } catch (err) {
+          if (isRedirect(err)) {
+            await inner.router.navigate(err.options)
+          }
+        }
+      })()
+    } else if (status !== 'success' || (loaderShouldRunAsync && inner.sync)) {
+      await runLoader(inner, matchId, index, route)
+    }
+  }
+
   const { id: matchId, routeId } = inner.matches[index]!
   let loaderShouldRunAsync = false
   let loaderIsRunningAsync = false
@@ -759,7 +837,9 @@ const loadRouteMatch = async (
       return inner.router.getMatch(matchId)!
     }
   } else {
-    const prevMatch = inner.router.getMatch(matchId)!
+    const prevMatch = inner.router.getMatch(matchId)! // This is where all of the stale-while-revalidate magic happens
+    const preload = resolvePreload(inner, matchId)
+
     // there is a loaderPromise, so we are in the middle of a load
     if (prevMatch._nonReactive.loaderPromise) {
       // do not block if we already have stale data we can show
@@ -774,32 +854,13 @@ const loadRouteMatch = async (
       if (error) {
         handleRedirectAndNotFound(inner, match, error)
       }
-    } else {
-      // This is where all of the stale-while-revalidate magic happens
-      const age = Date.now() - prevMatch.updatedAt
-
-      const preload = resolvePreload(inner, matchId)
-
-      const staleAge = preload
-        ? (route.options.preloadStaleTime ??
-          inner.router.options.defaultPreloadStaleTime ??
-          30_000) // 30 seconds for preloads by default
-        : (route.options.staleTime ??
-          inner.router.options.defaultStaleTime ??
-          0)
-
-      const shouldReloadOption = route.options.shouldReload
-
-      // Default to reloading the route all the time
-      // Allow shouldReload to get the last say,
-      // if provided.
-      const shouldReload =
-        typeof shouldReloadOption === 'function'
-          ? shouldReloadOption(getLoaderContext(inner, matchId, index, route))
-          : shouldReloadOption
 
+      if (match.status === 'pending') {
+        await handleLoader(preload, prevMatch, match, route)
+      }
+    } else {
       const nextPreload =
-        !!preload && !inner.router.state.matches.some((d) => d.id === matchId)
+        preload && !inner.router.state.matches.some((d) => d.id === matchId)
       const match = inner.router.getMatch(matchId)!
       match._nonReactive.loaderPromise = createControlledPromise<void>()
       if (nextPreload !== match.preload) {
@@ -809,30 +870,7 @@ const loadRouteMatch = async (
         }))
       }
 
-      // If the route is successful and still fresh, just resolve
-      const { status, invalid } = match
-      loaderShouldRunAsync =
-        status === 'success' && (invalid || (shouldReload ?? age > staleAge))
-      if (preload && route.options.preload === false) {
-        // Do nothing
-      } else if (loaderShouldRunAsync && !inner.sync) {
-        loaderIsRunningAsync = true
-        ;(async () => {
-          try {
-            await runLoader(inner, matchId, index, route)
-            const match = inner.router.getMatch(matchId)!
-            match._nonReactive.loaderPromise?.resolve()
-            match._nonReactive.loadPromise?.resolve()
-            match._nonReactive.loaderPromise = undefined
-          } catch (err) {
-            if (isRedirect(err)) {
-              await inner.router.navigate(err.options)
-            }
-          }
-        })()
-      } else if (status !== 'success' || (loaderShouldRunAsync && inner.sync)) {
-        await runLoader(inner, matchId, index, route)
-      }
+      await handleLoader(preload, prevMatch, match, route)
     }
   }
   const match = inner.router.getMatch(matchId)!
diff --git a/packages/router-core/src/redirect.ts b/packages/router-core/src/redirect.ts
index 4cb1e0f5e2..b10fac6d7a 100644
--- a/packages/router-core/src/redirect.ts
+++ b/packages/router-core/src/redirect.ts
@@ -1,4 +1,3 @@
-import { SAFE_URL_PROTOCOLS, isDangerousProtocol } from './utils'
 import type { NavigateOptions } from './link'
 import type { AnyRouter, RegisteredRouter } from './router'
 import type { ParsedLocation } from './location'
@@ -124,17 +123,6 @@ export function redirect<
 ): Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> {
   opts.statusCode = opts.statusCode || opts.code || 307
 
-  // Block dangerous protocols in redirect href
-  if (
-    !opts._builtLocation &&
-    typeof opts.href === 'string' &&
-    isDangerousProtocol(opts.href)
-  ) {
-    throw new Error(
-      `Redirect blocked: unsafe protocol in href "${opts.href}". Only ${SAFE_URL_PROTOCOLS.join(', ')} protocols are allowed.`,
-    )
-  }
-
   if (
     !opts._builtLocation &&
     !opts.reloadDocument &&
diff --git a/packages/router-core/src/router.ts b/packages/router-core/src/router.ts
index 6520f30799..538caf09fd 100644
--- a/packages/router-core/src/router.ts
+++ b/packages/router-core/src/router.ts
@@ -3,6 +3,7 @@ import { createBrowserHistory, parseHref } from '@tanstack/history'
 import { isServer } from '@tanstack/router-core/isServer'
 import { batch } from './utils/batch'
 import {
+  DEFAULT_PROTOCOL_ALLOWLIST,
   createControlledPromise,
   decodePath,
   deepEqual,
@@ -470,6 +471,15 @@ export interface RouterOptions<
    */
   disableGlobalCatchBoundary?: boolean
 
+  /**
+   * An array of URL protocols to allow in links, redirects, and navigation.
+   * Absolute URLs with protocols not in this list will be rejected.
+   *
+   * @default DEFAULT_PROTOCOL_ALLOWLIST (http:, https:, mailto:, tel:)
+   * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#protocolallowlist-property)
+   */
+  protocolAllowlist?: Array<string>
+
   serializationAdapters?: ReadonlyArray<AnySerializationAdapter>
   /**
    * Configures how the router will rewrite the location between the actual href and the internal href of the router.
@@ -521,7 +531,6 @@ export interface RouterState<
   isLoading: boolean
   isTransitioning: boolean
   matches: Array<TRouteMatch>
-  pendingMatches?: Array<TRouteMatch>
   cachedMatches: Array<TRouteMatch>
   location: ParsedLocation<FullSearchSchema<TRouteTree>>
   resolvedLocation?: ParsedLocation<FullSearchSchema<TRouteTree>>
@@ -953,6 +962,7 @@ export class RouterCore<
   origin?: string
   latestLocation!: ParsedLocation<FullSearchSchema<TRouteTree>>
   pendingBuiltLocation?: ParsedLocation<FullSearchSchema<TRouteTree>>
+  private pendingMatchesInternal?: Array<AnyRouteMatch>
   basepath!: string
   routeTree!: TRouteTree
   routesById!: RoutesById<TRouteTree>
@@ -961,6 +971,7 @@ export class RouterCore<
   resolvePathCache!: LRUCache<string, string>
   isServer!: boolean
   pathParamsDecoder?: (encoded: string) => string
+  protocolAllowlist!: Set<string>
 
   /**
    * @deprecated Use the `createRouter` function instead
@@ -984,6 +995,8 @@ export class RouterCore<
       notFoundMode: options.notFoundMode ?? 'fuzzy',
       stringifySearch: options.stringifySearch ?? defaultStringifySearch,
       parseSearch: options.parseSearch ?? defaultParseSearch,
+      protocolAllowlist:
+        options.protocolAllowlist ?? DEFAULT_PROTOCOL_ALLOWLIST,
     })
 
     if (typeof document !== 'undefined') {
@@ -1029,6 +1042,8 @@ export class RouterCore<
 
     this.isServer = this.options.isServer ?? typeof document === 'undefined'
 
+    this.protocolAllowlist = new Set(this.options.protocolAllowlist)
+
     if (this.options.pathParamsAllowedCharacters)
       this.pathParamsDecoder = compileDecodeCharMap(
         this.options.pathParamsAllowedCharacters,
@@ -1070,6 +1085,7 @@ export class RouterCore<
       let processRouteTreeResult: ProcessRouteTreeResult<TRouteTree>
       if (
         (isServer ?? this.isServer) &&
+        process.env.NODE_ENV !== 'development' &&
         globalThis.__TSR_CACHE__ &&
         globalThis.__TSR_CACHE__.routeTree === this.routeTree
       ) {
@@ -1082,6 +1098,7 @@ export class RouterCore<
         // only cache if nothing else is cached yet
         if (
           (isServer ?? this.isServer) &&
+          process.env.NODE_ENV !== 'development' &&
           globalThis.__TSR_CACHE__ === undefined
         ) {
           globalThis.__TSR_CACHE__ = {
@@ -1268,14 +1285,14 @@ export class RouterCore<
         return {
           href: pathname + searchStr + hash,
           publicHref: href,
-          pathname: decodePath(pathname),
+          pathname: decodePath(pathname).path,
           external: false,
           searchStr,
           search: replaceEqualDeep(
             previousLocation?.search,
             parsedSearch,
           ) as any,
-          hash: decodePath(hash.slice(1)),
+          hash: decodePath(hash.slice(1)).path,
           state: replaceEqualDeep(previousLocation?.state, state),
         }
       }
@@ -1297,11 +1314,11 @@ export class RouterCore<
       return {
         href: fullPath,
         publicHref: href,
-        pathname: decodePath(url.pathname),
+        pathname: decodePath(url.pathname).path,
         external: !!this.rewrite && url.origin !== this.origin,
         searchStr,
         search: replaceEqualDeep(previousLocation?.search, parsedSearch) as any,
-        hash: decodePath(url.hash.slice(1)),
+        hash: decodePath(url.hash.slice(1)).path,
         state: replaceEqualDeep(previousLocation?.state, state),
       }
     }
@@ -1401,6 +1418,10 @@ export class RouterCore<
 
     const matches = new Array<AnyRouteMatch>(matchedRoutes.length)
 
+    const previousMatchesByRouteId = new Map(
+      this.state.matches.map((match) => [match.routeId, match]),
+    )
+
     for (let index = 0; index < matchedRoutes.length; index++) {
       const route = matchedRoutes[index]!
       // Take each matched route and resolve + validate its search params
@@ -1484,9 +1505,7 @@ export class RouterCore<
 
       const existingMatch = this.getMatch(matchId)
 
-      const previousMatch = this.state.matches.find(
-        (d) => d.routeId === route.id,
-      )
+      const previousMatch = previousMatchesByRouteId.get(route.id)
 
       const strictParams = existingMatch?._strictParams ?? usedParams
 
@@ -1520,9 +1539,7 @@ export class RouterCore<
         match = {
           ...existingMatch,
           cause,
-          params: previousMatch
-            ? replaceEqualDeep(previousMatch.params, routeParams)
-            : routeParams,
+          params: previousMatch?.params ?? routeParams,
           _strictParams: strictParams,
           search: previousMatch
             ? replaceEqualDeep(previousMatch.search, preMatchSearch)
@@ -1543,9 +1560,7 @@ export class RouterCore<
           ssr: (isServer ?? this.isServer) ? undefined : route.options.ssr,
           index,
           routeId: route.id,
-          params: previousMatch
-            ? replaceEqualDeep(previousMatch.params, routeParams)
-            : routeParams,
+          params: previousMatch?.params ?? routeParams,
           _strictParams: strictParams,
           pathname: interpolatedPath,
           updatedAt: Date.now(),
@@ -1605,7 +1620,11 @@ export class RouterCore<
       const route = this.looseRoutesById[match.routeId]!
       const existingMatch = this.getMatch(match.id)
 
-      // only execute `context` if we are not calling from router.buildLocation
+      // Update the match's params
+      const previousMatch = previousMatchesByRouteId.get(match.routeId)
+      match.params = previousMatch
+        ? replaceEqualDeep(previousMatch.params, routeParams)
+        : routeParams
 
       if (!existingMatch) {
         const parentMatch = matches[index - 1]
@@ -1745,7 +1764,7 @@ export class RouterCore<
       (match) => match.isFetching === 'loader',
     )
     const matchesToCancelArray = new Set([
-      ...(this.state.pendingMatches ?? []),
+      ...(this.pendingMatchesInternal ?? []),
       ...currentPendingMatches,
       ...currentLoadingMatches,
     ])
@@ -1879,7 +1898,7 @@ export class RouterCore<
                   decoder: this.pathParamsDecoder,
                   server: this.isServer,
                 }).interpolatedPath,
-          )
+          ).path
 
       // Resolve the next search
       let nextSearch = fromSearch
@@ -2244,9 +2263,9 @@ export class RouterCore<
       // otherwise use href directly (which may already include basepath)
       const reloadHref = !hrefIsUrl && publicHref ? publicHref : href
 
-      // Block dangerous protocols like javascript:, data:, vbscript:
+      // Block dangerous protocols like javascript:, blob:, data:
       // These could execute arbitrary code if passed to window.location
-      if (isDangerousProtocol(reloadHref)) {
+      if (isDangerousProtocol(reloadHref, this.protocolAllowlist)) {
         if (process.env.NODE_ENV !== 'production') {
           console.warn(
             `Blocked navigation to dangerous protocol: ${reloadHref}`,
@@ -2322,6 +2341,7 @@ export class RouterCore<
 
     // Match the routes
     const pendingMatches = this.matchRoutes(this.latestLocation)
+    this.pendingMatchesInternal = pendingMatches
 
     // Ingest the new matches
     this.__store.setState((s) => ({
@@ -2330,7 +2350,6 @@ export class RouterCore<
       statusCode: 200,
       isLoading: true,
       location: this.latestLocation,
-      pendingMatches,
       // If a cached moved to pendingMatches, remove it from cachedMatches
       cachedMatches: s.cachedMatches.filter(
         (d) => !pendingMatches.some((e) => e.id === d.id),
@@ -2372,7 +2391,7 @@ export class RouterCore<
           await loadMatches({
             router: this,
             sync: opts?.sync,
-            matches: this.state.pendingMatches as Array<AnyRouteMatch>,
+            matches: this.pendingMatchesInternal ?? [],
             location: next,
             updateMatch: this.updateMatch,
             // eslint-disable-next-line @typescript-eslint/require-await
@@ -2391,7 +2410,7 @@ export class RouterCore<
                   batch(() => {
                     this.__store.setState((s) => {
                       const previousMatches = s.matches
-                      const newMatches = s.pendingMatches || s.matches
+                      const newMatches = this.pendingMatchesInternal || s.matches
 
                       exitingMatches = previousMatches.filter(
                         (match) => !newMatches.some((d) => d.id === match.id),
@@ -2409,7 +2428,6 @@ export class RouterCore<
                         isLoading: false,
                         loadedAt: Date.now(),
                         matches: newMatches,
-                        pendingMatches: undefined,
                         /**
                          * When committing new matches, cache any exiting matches that are still usable.
                          * Routes that resolved with `status: 'error'` or `status: 'notFound'` are
@@ -2425,6 +2443,7 @@ export class RouterCore<
                         ],
                       }
                     })
+                    this.pendingMatchesInternal = undefined
                     this.clearExpiredCache()
                   })
 
@@ -2566,9 +2585,14 @@ export class RouterCore<
 
   updateMatch: UpdateMatchFn = (id, updater) => {
     this.startTransition(() => {
-      const matchesKey = this.state.pendingMatches?.some((d) => d.id === id)
-        ? 'pendingMatches'
-        : this.state.matches.some((d) => d.id === id)
+      if (this.pendingMatchesInternal?.some((d) => d.id === id)) {
+        this.pendingMatchesInternal = this.pendingMatchesInternal.map((d) =>
+          d.id === id ? updater(d) : d,
+        )
+        return
+      }
+
+      const matchesKey = this.state.matches.some((d) => d.id === id)
           ? 'matches'
           : this.state.cachedMatches.some((d) => d.id === id)
             ? 'cachedMatches'
@@ -2589,7 +2613,7 @@ export class RouterCore<
     const findFn = (d: { id: string }) => d.id === matchId
     return (
       this.state.cachedMatches.find(findFn) ??
-      this.state.pendingMatches?.find(findFn) ??
+      this.pendingMatchesInternal?.find(findFn) ??
       this.state.matches.find(findFn)
     )
   }
@@ -2626,11 +2650,12 @@ export class RouterCore<
       return d
     }
 
+    this.pendingMatchesInternal = this.pendingMatchesInternal?.map(invalidate)
+
     this.__store.setState((s) => ({
       ...s,
       matches: s.matches.map(invalidate),
       cachedMatches: s.cachedMatches.map(invalidate),
-      pendingMatches: s.pendingMatches?.map(invalidate),
     }))
 
     this.shouldViewTransition = false
@@ -2665,6 +2690,17 @@ export class RouterCore<
       }
     }
 
+    if (
+      redirect.options.href &&
+      !redirect.options._builtLocation &&
+      // Check for dangerous protocols before processing the redirect
+      isDangerousProtocol(redirect.options.href, this.protocolAllowlist)
+    ) {
+      throw new Error(
+        `Redirect blocked: unsafe protocol in href "${redirect.options.href}". Allowed protocols: ${Array.from(this.protocolAllowlist).join(', ')}.`,
+      )
+    }
+
     if (!redirect.headers.get('Location')) {
       redirect.headers.set('Location', redirect.options.href)
     }
@@ -2736,7 +2772,7 @@ export class RouterCore<
     })
 
     const activeMatchIds = new Set(
-      [...this.state.matches, ...(this.state.pendingMatches ?? [])].map(
+      [...this.state.matches, ...(this.pendingMatchesInternal ?? [])].map(
         (d) => d.id,
       ),
     )
@@ -2904,7 +2940,6 @@ export function getInitialRouterState(
     resolvedLocation: undefined,
     location,
     matches: [],
-    pendingMatches: [],
     cachedMatches: [],
     statusCode: 200,
   }
diff --git a/packages/router-core/src/ssr/createRequestHandler.ts b/packages/router-core/src/ssr/createRequestHandler.ts
index fe1b2d71c2..6fe0d68d4a 100644
--- a/packages/router-core/src/ssr/createRequestHandler.ts
+++ b/packages/router-core/src/ssr/createRequestHandler.ts
@@ -35,7 +35,7 @@ export function createRequestHandler<TRouter extends AnyRouter>({
       })
 
       // normalizing and sanitizing the pathname here for server, so we always deal with the same format during SSR.
-      const url = getNormalizedURL(request.url, 'http://localhost')
+      const { url } = getNormalizedURL(request.url, 'http://localhost')
       const origin = getOrigin(request)
       const href = url.href.replace(url.origin, '')
 
diff --git a/packages/router-core/src/ssr/ssr-server.ts b/packages/router-core/src/ssr/ssr-server.ts
index b98516e9d5..2c531de8ab 100644
--- a/packages/router-core/src/ssr/ssr-server.ts
+++ b/packages/router-core/src/ssr/ssr-server.ts
@@ -398,7 +398,9 @@ export function getNormalizedURL(url: string | URL, base?: string | URL) {
   if (typeof url === 'string') url = url.replace('\\', '%5C')
 
   const rawUrl = new URL(url, base)
-  const decodedPathname = decodePath(rawUrl.pathname)
+  const { path: decodedPathname, handledProtocolRelativeURL } = decodePath(
+    rawUrl.pathname,
+  )
   const searchParams = new URLSearchParams(rawUrl.search)
   const normalizedHref =
     decodedPathname +
@@ -406,5 +408,8 @@ export function getNormalizedURL(url: string | URL, base?: string | URL) {
     searchParams.toString() +
     rawUrl.hash
 
-  return new URL(normalizedHref, rawUrl.origin)
+  return {
+    url: new URL(normalizedHref, rawUrl.origin),
+    handledProtocolRelativeURL,
+  }
 }
diff --git a/packages/router-core/src/utils.ts b/packages/router-core/src/utils.ts
index eac67cce03..716e45204a 100644
--- a/packages/router-core/src/utils.ts
+++ b/packages/router-core/src/utils.ts
@@ -536,14 +536,22 @@ function decodeSegment(segment: string): string {
 }
 
 /**
- * List of URL protocols that are safe for navigation.
- * Only these protocols are allowed in redirects and navigation.
+ * Default list of URL protocols to allow in links, redirects, and navigation.
+ * Any absolute URL protocol not in this list is treated as dangerous by default.
  */
-export const SAFE_URL_PROTOCOLS = ['http:', 'https:', 'mailto:', 'tel:']
+export const DEFAULT_PROTOCOL_ALLOWLIST = [
+  // Standard web navigation
+  'http:',
+  'https:',
+
+  // Common browser-safe actions
+  'mailto:',
+  'tel:',
+]
 
 /**
- * Check if a URL string uses a protocol that is not in the safe list.
- * Returns true for dangerous protocols like javascript:, data:, vbscript:, etc.
+ * Check if a URL string uses a protocol that is not in the allowlist.
+ * Returns true for blocked protocols like javascript:, blob:, data:, etc.
  *
  * The URL constructor correctly normalizes:
  * - Mixed case (JavaScript: → javascript:)
@@ -553,16 +561,20 @@ export const SAFE_URL_PROTOCOLS = ['http:', 'https:', 'mailto:', 'tel:']
  * For relative URLs (no protocol), returns false (safe).
  *
  * @param url - The URL string to check
- * @returns true if the URL uses a dangerous (non-whitelisted) protocol
+ * @param allowlist - Set of protocols to allow
+ * @returns true if the URL uses a protocol that is not allowed
  */
-export function isDangerousProtocol(url: string): boolean {
+export function isDangerousProtocol(
+  url: string,
+  allowlist: Set<string>,
+): boolean {
   if (!url) return false
 
   try {
     // Use the URL constructor - it correctly normalizes protocols
     // per WHATWG URL spec, handling all bypass attempts automatically
     const parsed = new URL(url)
-    return !SAFE_URL_PROTOCOLS.includes(parsed.protocol)
+    return !allowlist.has(parsed.protocol)
   } catch {
     // URL constructor throws for relative URLs (no protocol)
     // These are safe - they can't execute scripts
@@ -593,8 +605,8 @@ export function escapeHtml(str: string): string {
   return str.replace(HTML_ESCAPE_REGEX, (match) => HTML_ESCAPE_LOOKUP[match]!)
 }
 
-export function decodePath(path: string, decodeIgnore?: Array<string>): string {
-  if (!path) return path
+export function decodePath(path: string) {
+  if (!path) return { path, handledProtocolRelativeURL: false }
 
   // Fast path: most paths are already decoded and safe.
   // Only fall back to the slower scan/regex path when we see a '%' (encoded),
@@ -602,12 +614,10 @@ export function decodePath(path: string, decodeIgnore?: Array<string>): string {
   // prefix which needs collapsing.
   // eslint-disable-next-line no-control-regex
   if (!/[%\\\x00-\x1f\x7f]/.test(path) && !path.startsWith('//')) {
-    return path
+    return { path, handledProtocolRelativeURL: false }
   }
 
-  const re = decodeIgnore
-    ? new RegExp(`${decodeIgnore.join('|')}`, 'gi')
-    : /%25|%5C/gi
+  const re = /%25|%5C/gi
   let cursor = 0
   let result = ''
   let match
@@ -620,11 +630,13 @@ export function decodePath(path: string, decodeIgnore?: Array<string>): string {
   // Prevent open redirect via protocol-relative URLs (e.g. "//evil.com")
   // After sanitizing control characters, paths like "/\r/evil.com" become "//evil.com"
   // Collapse leading double slashes to a single slash
+  let handledProtocolRelativeURL = false
   if (result.startsWith('//')) {
+    handledProtocolRelativeURL = true
     result = '/' + result.replace(/^\/+/, '')
   }
 
-  return result
+  return { path: result, handledProtocolRelativeURL }
 }
 
 /**
diff --git a/packages/router-core/tests/dangerous-protocols.test.ts b/packages/router-core/tests/dangerous-protocols.test.ts
index 54540eb91d..8ae8fe6cac 100644
--- a/packages/router-core/tests/dangerous-protocols.test.ts
+++ b/packages/router-core/tests/dangerous-protocols.test.ts
@@ -1,258 +1,229 @@
 import { describe, expect, it } from 'vitest'
-import { isDangerousProtocol } from '../src/utils'
+import { DEFAULT_PROTOCOL_ALLOWLIST, isDangerousProtocol } from '../src/utils'
 import { redirect } from '../src/redirect'
+import { BaseRootRoute, RouterCore } from '../src'
+
+const defaultAllowlistSet = new Set(DEFAULT_PROTOCOL_ALLOWLIST)
 
 describe('isDangerousProtocol', () => {
-  describe('dangerous protocols (not whitelisted)', () => {
+  describe('blocked protocols (not in default allowlist)', () => {
     it('should detect javascript: protocol', () => {
-      expect(isDangerousProtocol('javascript:alert(1)')).toBe(true)
-    })
-
-    it('should detect javascript: with newlines', () => {
-      expect(isDangerousProtocol('java\nscript:alert(1)')).toBe(true)
-      expect(isDangerousProtocol('java\rscript:alert(1)')).toBe(true)
-      expect(isDangerousProtocol('java\tscript:alert(1)')).toBe(true)
-    })
-
-    it('should detect javascript: with mixed case', () => {
-      expect(isDangerousProtocol('JavaScript:alert(1)')).toBe(true)
-      expect(isDangerousProtocol('JAVASCRIPT:alert(1)')).toBe(true)
-      expect(isDangerousProtocol('jAvAsCrIpT:alert(1)')).toBe(true)
-    })
-
-    it('should detect javascript: with leading whitespace', () => {
-      expect(isDangerousProtocol(' javascript:alert(1)')).toBe(true)
-      expect(isDangerousProtocol('\tjavascript:alert(1)')).toBe(true)
-      expect(isDangerousProtocol('\njavascript:alert(1)')).toBe(true)
-    })
-
-    it('should detect data: protocol', () => {
       expect(
-        isDangerousProtocol('data:text/html,<script>alert(1)</script>'),
+        isDangerousProtocol('javascript:alert(1)', defaultAllowlistSet),
       ).toBe(true)
     })
 
-    it('should detect vbscript: protocol', () => {
-      expect(isDangerousProtocol('vbscript:msgbox(1)')).toBe(true)
+    it('should detect javascript: with mixed case and whitespace', () => {
+      expect(
+        isDangerousProtocol('JavaScript:alert(1)', defaultAllowlistSet),
+      ).toBe(true)
+      expect(
+        isDangerousProtocol('  \t\n  javascript:alert(1)', defaultAllowlistSet),
+      ).toBe(true)
+      expect(
+        isDangerousProtocol('java\nscript:alert(1)', defaultAllowlistSet),
+      ).toBe(true)
     })
 
-    it('should detect file: protocol', () => {
-      expect(isDangerousProtocol('file:///etc/passwd')).toBe(true)
+    it('should detect known unsafe schemes', () => {
+      expect(
+        isDangerousProtocol(
+          'data:text/html,<script>alert(1)</script>',
+          defaultAllowlistSet,
+        ),
+      ).toBe(true)
+      expect(
+        isDangerousProtocol(
+          'blob:https://example.com/some-uuid',
+          defaultAllowlistSet,
+        ),
+      ).toBe(true)
+      expect(
+        isDangerousProtocol('vbscript:msgbox(1)', defaultAllowlistSet),
+      ).toBe(true)
+      expect(
+        isDangerousProtocol('file:///etc/passwd', defaultAllowlistSet),
+      ).toBe(true)
+      expect(isDangerousProtocol('about:blank', defaultAllowlistSet)).toBe(true)
     })
 
-    it('should detect unknown protocols', () => {
-      expect(isDangerousProtocol('custom:something')).toBe(true)
-      expect(isDangerousProtocol('foo:bar')).toBe(true)
+    it('should block custom protocols by default', () => {
+      expect(isDangerousProtocol('custom:something', defaultAllowlistSet)).toBe(
+        true,
+      )
+      expect(isDangerousProtocol('foo:bar', defaultAllowlistSet)).toBe(true)
     })
   })
 
-  describe('safe protocols (whitelisted)', () => {
-    it('should allow http: protocol', () => {
-      expect(isDangerousProtocol('http://example.com')).toBe(false)
-    })
-
-    it('should allow https: protocol', () => {
-      expect(isDangerousProtocol('https://example.com')).toBe(false)
-    })
-
-    it('should allow mailto: protocol', () => {
-      expect(isDangerousProtocol('mailto:user@example.com')).toBe(false)
+  describe('allowed protocols (in default allowlist)', () => {
+    it('should allow http and https', () => {
+      expect(
+        isDangerousProtocol('http://example.com', defaultAllowlistSet),
+      ).toBe(false)
+      expect(
+        isDangerousProtocol('https://example.com', defaultAllowlistSet),
+      ).toBe(false)
     })
 
-    it('should allow tel: protocol', () => {
-      expect(isDangerousProtocol('tel:+1234567890')).toBe(false)
+    it('should allow mailto and tel', () => {
+      expect(
+        isDangerousProtocol('mailto:user@example.com', defaultAllowlistSet),
+      ).toBe(false)
+      expect(isDangerousProtocol('tel:+1234567890', defaultAllowlistSet)).toBe(
+        false,
+      )
     })
   })
 
   describe('relative URLs (no protocol)', () => {
-    it('should allow relative paths', () => {
-      expect(isDangerousProtocol('/path/to/page')).toBe(false)
-      expect(isDangerousProtocol('./relative')).toBe(false)
-      expect(isDangerousProtocol('../parent')).toBe(false)
-    })
-
-    it('should allow query strings', () => {
-      expect(isDangerousProtocol('?foo=bar')).toBe(false)
-    })
-
-    it('should allow hash fragments', () => {
-      expect(isDangerousProtocol('#section')).toBe(false)
+    it('should allow relative paths, query strings and hash fragments', () => {
+      expect(isDangerousProtocol('/path/to/page', defaultAllowlistSet)).toBe(
+        false,
+      )
+      expect(isDangerousProtocol('./relative', defaultAllowlistSet)).toBe(false)
+      expect(isDangerousProtocol('../parent', defaultAllowlistSet)).toBe(false)
+      expect(isDangerousProtocol('?foo=bar', defaultAllowlistSet)).toBe(false)
+      expect(isDangerousProtocol('#section', defaultAllowlistSet)).toBe(false)
     })
   })
 
   describe('edge cases', () => {
     it('should handle empty and null-ish inputs', () => {
-      expect(isDangerousProtocol('')).toBe(false)
+      expect(isDangerousProtocol('', defaultAllowlistSet)).toBe(false)
+      expect(
+        isDangerousProtocol(null as unknown as string, defaultAllowlistSet),
+      ).toBe(false)
+      expect(
+        isDangerousProtocol(
+          undefined as unknown as string,
+          defaultAllowlistSet,
+        ),
+      ).toBe(false)
     })
 
-    it('should not be fooled by javascript in pathname', () => {
-      expect(isDangerousProtocol('https://example.com/javascript:foo')).toBe(
+    it('should not be fooled by javascript in pathname or query', () => {
+      expect(
+        isDangerousProtocol(
+          'https://example.com/javascript:foo',
+          defaultAllowlistSet,
+        ),
+      ).toBe(false)
+      expect(isDangerousProtocol('/javascript:foo', defaultAllowlistSet)).toBe(
+        false,
+      )
+      expect(isDangerousProtocol('/path?time=12:00', defaultAllowlistSet)).toBe(
         false,
       )
-      expect(isDangerousProtocol('/javascript:foo')).toBe(false)
     })
 
-    it('should not be fooled by colon in query string', () => {
-      expect(isDangerousProtocol('/path?time=12:00')).toBe(false)
+    it('should return false for malformed/encoded scheme strings that URL rejects', () => {
+      expect(
+        isDangerousProtocol(
+          '%6a%61%76%61%73%63%72%69%70%74:alert(1)',
+          defaultAllowlistSet,
+        ),
+      ).toBe(false)
+      expect(isDangerousProtocol(':::', defaultAllowlistSet)).toBe(false)
+      expect(isDangerousProtocol('123:456', defaultAllowlistSet)).toBe(false)
+      expect(isDangerousProtocol('//example.com', defaultAllowlistSet)).toBe(
+        false,
+      )
     })
-  })
 
-  describe('additional edge cases', () => {
-    describe('null and undefined inputs', () => {
-      it('should return false for null', () => {
-        expect(isDangerousProtocol(null as unknown as string)).toBe(false)
-      })
-
-      it('should return false for undefined', () => {
-        expect(isDangerousProtocol(undefined as unknown as string)).toBe(false)
-      })
+    it('should detect dangerous protocol with leading control characters', () => {
+      expect(
+        isDangerousProtocol('\x00javascript:alert(1)', defaultAllowlistSet),
+      ).toBe(true)
+      expect(
+        isDangerousProtocol(
+          '\x01\x02\x03javascript:alert(1)',
+          defaultAllowlistSet,
+        ),
+      ).toBe(true)
     })
+  })
 
-    describe('URL-encoded schemes', () => {
-      it('should return false for URL-encoded javascript: protocol (URL constructor does not decode protocol)', () => {
-        // %6a%61%76%61%73%63%72%69%70%74 = javascript
-        // The URL constructor treats this as an invalid URL (throws), so it returns false
-        // This is safe because browsers also don't decode percent-encoding in protocols
-        expect(
-          isDangerousProtocol('%6a%61%76%61%73%63%72%69%70%74:alert(1)'),
-        ).toBe(false)
-      })
-
-      it('should return false for partially URL-encoded javascript: protocol', () => {
-        // URL constructor throws for these malformed URLs
-        expect(isDangerousProtocol('%6aavascript:alert(1)')).toBe(false)
-        expect(isDangerousProtocol('j%61vascript:alert(1)')).toBe(false)
-      })
-
-      it('should return false for URL-encoded data: protocol', () => {
-        // %64%61%74%61 = data
-        // URL constructor treats this as invalid
-        expect(
-          isDangerousProtocol(
-            '%64%61%74%61:text/html,<script>alert(1)</script>',
-          ),
-        ).toBe(false)
-      })
-
-      it('should return false for URL-encoded vbscript: protocol', () => {
-        // %76%62%73%63%72%69%70%74 = vbscript
-        // URL constructor treats this as invalid
-        expect(isDangerousProtocol('%76%62%73%63%72%69%70%74:msgbox(1)')).toBe(
-          false,
-        )
-      })
+  describe('custom allowlist', () => {
+    it('should use custom allowlist when provided', () => {
+      const customAllowlist = new Set(['ftp:', 'ssh:'])
 
-      it('should return false for URL-encoded safe protocols (URL constructor does not decode)', () => {
-        // %68%74%74%70%73 = https
-        // URL constructor treats this as invalid since percent-encoding in protocol is not decoded
-        expect(isDangerousProtocol('%68%74%74%70%73://example.com')).toBe(false)
-      })
+      expect(isDangerousProtocol('ftp://example.com', customAllowlist)).toBe(
+        false,
+      )
+      expect(isDangerousProtocol('ssh://example.com', customAllowlist)).toBe(
+        false,
+      )
+      expect(isDangerousProtocol('javascript:alert(1)', customAllowlist)).toBe(
+        true,
+      )
+      expect(isDangerousProtocol('https://example.com', customAllowlist)).toBe(
+        true,
+      )
     })
 
-    describe('protocol-relative URLs', () => {
-      it('should return false for protocol-relative URLs', () => {
-        expect(isDangerousProtocol('//example.com')).toBe(false)
-      })
-
-      it('should return false for protocol-relative URLs with paths', () => {
-        expect(isDangerousProtocol('//example.com/path/to/page')).toBe(false)
-      })
-
-      it('should return false for protocol-relative URLs with query strings', () => {
-        expect(isDangerousProtocol('//example.com?foo=bar')).toBe(false)
-      })
-
-      it('should return false for protocol-relative URLs with hash', () => {
-        expect(isDangerousProtocol('//example.com#section')).toBe(false)
-      })
+    it('should block absolute URLs with an empty allowlist', () => {
+      const emptyAllowlist = new Set<string>()
+      expect(isDangerousProtocol('javascript:alert(1)', emptyAllowlist)).toBe(
+        true,
+      )
+      expect(isDangerousProtocol('data:text/html,test', emptyAllowlist)).toBe(
+        true,
+      )
+      expect(isDangerousProtocol('https://example.com', emptyAllowlist)).toBe(
+        true,
+      )
     })
 
-    describe('malformed inputs', () => {
-      it('should return false for strings without valid protocol pattern', () => {
-        expect(isDangerousProtocol('not a url at all')).toBe(false)
-      })
-
-      it('should return false for strings with only colons', () => {
-        expect(isDangerousProtocol(':::')).toBe(false)
-      })
-
-      it('should return false for strings starting with numbers', () => {
-        expect(isDangerousProtocol('123:456')).toBe(false)
-      })
-
-      it('should handle strings with non-printable characters', () => {
-        expect(isDangerousProtocol('\x00javascript:alert(1)')).toBe(true)
-        expect(isDangerousProtocol('\x01\x02\x03javascript:alert(1)')).toBe(
-          true,
-        )
-      })
+    it('should allow extending the default allowlist', () => {
+      const extendedAllowlist = new Set([
+        ...DEFAULT_PROTOCOL_ALLOWLIST,
+        'ftp:',
+        'gopher:',
+      ])
 
-      it('should return false for very long benign paths', () => {
-        const longPath = '/' + 'a'.repeat(10000)
-        expect(isDangerousProtocol(longPath)).toBe(false)
-      })
-
-      it('should return false for very long query strings', () => {
-        const longQuery = '/path?' + 'a=b&'.repeat(1000)
-        expect(isDangerousProtocol(longQuery)).toBe(false)
-      })
-
-      it('should detect dangerous protocol even with long payload', () => {
-        const longPayload = 'javascript:' + 'a'.repeat(10000)
-        expect(isDangerousProtocol(longPayload)).toBe(true)
-      })
-
-      it('should handle unicode characters in URLs', () => {
-        expect(isDangerousProtocol('/путь/к/странице')).toBe(false)
-        expect(isDangerousProtocol('https://例え.jp/path')).toBe(false)
-      })
-
-      it('should return false for full-width unicode characters (not recognized as javascript protocol)', () => {
-        // Full-width characters are not normalized by URL constructor
-        // URL constructor throws, so this is treated as safe (relative URL)
-        expect(isDangerousProtocol('ｊａｖａｓｃｒｉｐｔ:alert(1)')).toBe(false)
-      })
+      expect(
+        isDangerousProtocol('javascript:alert(1)', extendedAllowlist),
+      ).toBe(true)
+      expect(isDangerousProtocol('ftp://example.com', extendedAllowlist)).toBe(
+        false,
+      )
+      expect(
+        isDangerousProtocol('gopher://example.com', extendedAllowlist),
+      ).toBe(false)
+      expect(
+        isDangerousProtocol('https://example.com', extendedAllowlist),
+      ).toBe(false)
     })
+  })
 
-    describe('whitespace variations', () => {
-      it('should detect javascript: with various whitespace combinations', () => {
-        expect(isDangerousProtocol('  \t\n  javascript:alert(1)')).toBe(true)
-        expect(isDangerousProtocol('\r\njavascript:alert(1)')).toBe(true)
-      })
-
-      it('should return false for non-breaking space prefix (URL constructor throws)', () => {
-        // Non-breaking space is not stripped by URL constructor, causes it to throw
-        expect(isDangerousProtocol('\u00A0javascript:alert(1)')).toBe(false)
-      })
-
-      it('should return false for javascript: with embedded null bytes (URL constructor throws)', () => {
-        // Null bytes in the protocol cause URL constructor to throw
-        expect(isDangerousProtocol('java\x00script:alert(1)')).toBe(false)
-      })
+  describe('DEFAULT_PROTOCOL_ALLOWLIST', () => {
+    it('should contain the expected default protocols', () => {
+      expect(DEFAULT_PROTOCOL_ALLOWLIST).toEqual([
+        'http:',
+        'https:',
+        'mailto:',
+        'tel:',
+      ])
     })
   })
 })
 
-describe('redirect with dangerous protocols', () => {
-  it('should throw when href uses javascript: protocol', () => {
-    expect(() => redirect({ href: 'javascript:alert(1)' })).toThrow(
-      /unsafe protocol/,
-    )
+describe('redirect creation (no protocol validation)', () => {
+  it('should allow creating redirect with javascript: protocol', () => {
+    expect(() => redirect({ href: 'javascript:alert(1)' })).not.toThrow()
   })
 
-  it('should throw when href uses javascript: with bypass attempts', () => {
-    expect(() => redirect({ href: 'java\nscript:alert(1)' })).toThrow(
-      /unsafe protocol/,
-    )
-    expect(() => redirect({ href: 'JavaScript:alert(1)' })).toThrow(
-      /unsafe protocol/,
-    )
+  it('should allow creating redirect with data: protocol', () => {
+    expect(() =>
+      redirect({ href: 'data:text/html,<script>alert(1)</script>' }),
+    ).not.toThrow()
   })
 
-  it('should throw when href uses data: protocol', () => {
+  it('should allow creating redirect with any protocol', () => {
+    expect(() => redirect({ href: 'custom:something' })).not.toThrow()
     expect(() =>
-      redirect({ href: 'data:text/html,<script>alert(1)</script>' }),
-    ).toThrow(/unsafe protocol/)
+      redirect({ href: 'blob:https://example.com/uuid' }),
+    ).not.toThrow()
   })
 
   it('should allow safe protocols', () => {
@@ -265,3 +236,41 @@ describe('redirect with dangerous protocols', () => {
     expect(() => redirect({ to: '/home' })).not.toThrow()
   })
 })
+
+describe('integration test on Router', () => {
+  const inputs = [
+    'x-safari-https://example.com',
+    'googlechromes://example.com',
+    'intent://example.com#Intent;scheme=https;end',
+    'foo:bar',
+  ]
+  it('should accept weird protocols from the allowlist', () => {
+    const router = new RouterCore({
+      routeTree: new BaseRootRoute(),
+      protocolAllowlist: [
+        'x-safari-https:',
+        'googlechromes:',
+        'intent:',
+        'foo:',
+      ],
+    })
+    // Each protocol in the inputs should be accepted by resolveRedirect
+    for (const href of inputs) {
+      const redir = redirect({ href })
+      expect(() => router.resolveRedirect(redir)).not.toThrow()
+    }
+  })
+  it('should block weird protocols not in the allowlist', () => {
+    const router = new RouterCore({
+      routeTree: new BaseRootRoute(),
+      protocolAllowlist: [],
+    })
+    // Each protocol in the inputs should be blocked by resolveRedirect
+    for (const href of inputs) {
+      const redir = redirect({ href })
+      expect(() => router.resolveRedirect(redir)).toThrow(
+        /Redirect blocked: unsafe protocol/,
+      )
+    }
+  })
+})
diff --git a/packages/router-core/tests/getNormalizedURL.test.ts b/packages/router-core/tests/getNormalizedURL.test.ts
index 6af6b2736a..d459c8b418 100644
--- a/packages/router-core/tests/getNormalizedURL.test.ts
+++ b/packages/router-core/tests/getNormalizedURL.test.ts
@@ -9,12 +9,12 @@ describe('getNormalizedURL', () => {
     const normalizedUrl1 = getNormalizedURL(url1)
     const normalizedUrl2 = getNormalizedURL(url2)
 
-    expect(normalizedUrl1.pathname).toBe('/%EB%8C%80|/path')
-    expect(normalizedUrl1.pathname).toBe(normalizedUrl2.pathname)
+    expect(normalizedUrl1.url.pathname).toBe('/%EB%8C%80|/path')
+    expect(normalizedUrl1.url.pathname).toBe(normalizedUrl2.url.pathname)
     expect(new URL(url1).pathname).not.toBe(new URL(url2).pathname)
 
-    expect(normalizedUrl1.search).toBe(`?query=%EB%8C%80%7C`)
-    expect(normalizedUrl1.search).toBe(normalizedUrl2.search)
+    expect(normalizedUrl1.url.search).toBe(`?query=%EB%8C%80%7C`)
+    expect(normalizedUrl1.url.search).toBe(normalizedUrl2.url.search)
     expect(new URL(url1).search).not.toBe(new URL(url2).search)
   })
 
@@ -120,9 +120,9 @@ describe('getNormalizedURL', () => {
     'should treat encoded URL specific characters correctly',
     ({ url, expectedPathName, expectedHash, expectedSearchParams }) => {
       const normalizedUrl = getNormalizedURL(url)
-      expect(normalizedUrl.pathname).toBe(expectedPathName)
-      expect(normalizedUrl.search).toBe(expectedSearchParams)
-      expect(normalizedUrl.hash).toBe(expectedHash)
+      expect(normalizedUrl.url.pathname).toBe(expectedPathName)
+      expect(normalizedUrl.url.search).toBe(expectedSearchParams)
+      expect(normalizedUrl.url.hash).toBe(expectedHash)
     },
   )
 })
diff --git a/packages/router-core/tests/load.test.ts b/packages/router-core/tests/load.test.ts
index b312cfe71c..eb2b1ce476 100644
--- a/packages/router-core/tests/load.test.ts
+++ b/packages/router-core/tests/load.test.ts
@@ -84,8 +84,9 @@ describe('beforeLoad skip or exec', () => {
     const router = setup({ beforeLoad })
     const navigation = router.navigate({ to: '/foo' })
     expect(beforeLoad).toHaveBeenCalledTimes(1)
-    expect(router.state.pendingMatches).toEqual(
-      expect.arrayContaining([expect.objectContaining({ id: '/foo/foo' })]),
+    expect(router.state.status).toBe('pending')
+    expect(router.getMatch('/foo/foo')).toEqual(
+      expect.objectContaining({ id: '/foo/foo' }),
     )
     await navigation
     expect(router.state.location.pathname).toBe('/foo')
@@ -266,8 +267,9 @@ describe('loader skip or exec', () => {
     const router = setup({ loader })
     const navigation = router.navigate({ to: '/foo' })
     expect(loader).toHaveBeenCalledTimes(1)
-    expect(router.state.pendingMatches).toEqual(
-      expect.arrayContaining([expect.objectContaining({ id: '/foo/foo' })]),
+    expect(router.state.status).toBe('pending')
+    expect(router.getMatch('/foo/foo')).toEqual(
+      expect.objectContaining({ id: '/foo/foo' }),
     )
     await navigation
     expect(router.state.location.pathname).toBe('/foo')
@@ -566,11 +568,7 @@ describe('params.parse notFound', () => {
     })
 
     await router.load()
-
-    const match = router.state.pendingMatches?.find(
-      (m) => m.routeId === testRoute.id,
-    )
-
+    const match = router.getMatch(testRoute.id + '/test/invalid')
     expect(match?.status).toBe('notFound')
   })
 
diff --git a/packages/router-core/tests/utils.test.ts b/packages/router-core/tests/utils.test.ts
index ea466a0ec4..95874f230e 100644
--- a/packages/router-core/tests/utils.test.ts
+++ b/packages/router-core/tests/utils.test.ts
@@ -501,81 +501,12 @@ describe('deepEqual', () => {
 })
 
 describe('decodePath', () => {
-  it('should decode a path segment with no ignored items existing', () => {
-    const itemsToCheck = ['%25', '%5C']
-    const stringToCheck =
-      'https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B'
-    const expectedResult = 'https://mozilla.org/?x=шеллы'
-
-    const result = decodePath(stringToCheck, itemsToCheck)
-
-    expect(result).toBe(expectedResult)
-  })
-
-  it('should decode a path segment with one ignored character and one ignored item existing', () => {
-    const itemsToCheck = ['%25']
-    const stringToCheck =
-      'https://mozilla.org/?x=%25%D1%88%D0%B5%5C%D0%BB%D0%BB%D1%8B'
-    const expectedResult = 'https://mozilla.org/?x=%25ше\\ллы'
-
-    const result = decodePath(stringToCheck, itemsToCheck)
-
-    expect(result).toBe(expectedResult)
-  })
-
-  it('should decode a path segment with multiple ignored characters and first ignored item existing', () => {
-    const itemsToCheck = ['%25', '%5C']
-    let stringToCheck =
-      'https://mozilla.org/?x=%25%D1%88%D0%B5%D0%BB%D0%BB%D1%8B'
-    let expectedResult = 'https://mozilla.org/?x=%25шеллы'
-
-    let result = decodePath(stringToCheck, itemsToCheck)
-
-    expect(result).toBe(expectedResult)
-
-    stringToCheck = 'https://mozilla.org/?x=%D1%88%D0%B5%5C%D0%BB%D0%BB%D1%8B'
-    expectedResult = 'https://mozilla.org/?x=ше%5Cллы'
-
-    result = decodePath(stringToCheck, itemsToCheck)
-
-    expect(result).toBe(expectedResult)
-  })
-
-  it('should decode a path segment with multiple ignored characters and other ignored item existing', () => {
-    const itemsToCheck = ['%25', '%5C']
-    let stringToCheck =
-      'https://mozilla.org/?x=%5C%D1%88%D0%B5%D0%BB%D0%BB%D1%8B'
-    let expectedResult = 'https://mozilla.org/?x=%5Cшеллы'
-
-    let result = decodePath(stringToCheck, itemsToCheck)
-
-    expect(result).toBe(expectedResult)
-
-    stringToCheck = 'https://mozilla.org/?x=%D1%88%D0%B5%5C%D0%BB%D0%BB%D1%8B'
-    expectedResult = 'https://mozilla.org/?x=ше%5Cллы'
-
-    result = decodePath(stringToCheck, itemsToCheck)
-
-    expect(result).toBe(expectedResult)
-  })
-
-  it('should decode a path segment with multiple ignored characters and multiple ignored items existing', () => {
-    const itemsToCheck = ['%25', '%5C']
-    const stringToCheck =
-      'https://mozilla.org/?x=%25%D1%88%D0%B5%5C%D0%BB%D0%BB%D1%8B'
-    const expectedResult = 'https://mozilla.org/?x=%25ше%5Cллы'
-
-    const result = decodePath(stringToCheck, itemsToCheck)
-
-    expect(result).toBe(expectedResult)
-  })
-
   it('should decode a path segment, ignoring `%` and `\\` by default, with multiple ignored items existing', () => {
     const stringToCheck =
       'https://mozilla.org/?x=%25%D1%88%D0%B5%5C%D0%BB%D0%BB%D1%8B%2F'
     const expectedResult = 'https://mozilla.org/?x=%25ше%5Cллы%2F'
 
-    const result = decodePath(stringToCheck)
+    const result = decodePath(stringToCheck).path
 
     expect(result).toBe(expectedResult)
   })
@@ -583,34 +514,34 @@ describe('decodePath', () => {
   it('should handle malformed percent-encodings gracefully', () => {
     const stringToCheck = 'path%ZZ%D1%88test%5C%C3%A9'
     // Malformed sequences should remain as-is, valid ones decoded
-    const result = decodePath(stringToCheck)
+    const result = decodePath(stringToCheck).path
     expect(result).toBe(`path%ZZ%D1%88test%5Cé`)
   })
 
   it('should return empty string unchanged', () => {
-    expect(decodePath('')).toBe('')
+    expect(decodePath('').path).toBe('')
   })
 
   it('should return strings without encoding unchanged', () => {
     const stringToCheck = 'plain-text-path'
-    expect(decodePath(stringToCheck)).toBe(stringToCheck)
+    expect(decodePath(stringToCheck).path).toBe(stringToCheck)
   })
 
   it('should handle consecutive ignored characters', () => {
     const stringToCheck = 'test%25%25end'
     const expectedResult = 'test%25%25end'
-    expect(decodePath(stringToCheck)).toBe(expectedResult)
+    expect(decodePath(stringToCheck).path).toBe(expectedResult)
   })
 
   it('should handle multiple ignored items of the same type with varying case', () => {
     const stringToCheck = '/params-ps/named/foo%2Fabc/c%2Fh'
     const expectedResult = '/params-ps/named/foo%2Fabc/c%2Fh'
-    expect(decodePath(stringToCheck)).toBe(expectedResult)
+    expect(decodePath(stringToCheck).path).toBe(expectedResult)
 
     const stringToCheckWithLowerCase = '/params-ps/named/foo%2Fabc/c%5C%2f%5cAh'
     const expectedResultWithLowerCase =
       '/params-ps/named/foo%2Fabc/c%5C%2f%5cAh'
-    expect(decodePath(stringToCheckWithLowerCase)).toBe(
+    expect(decodePath(stringToCheckWithLowerCase).path).toBe(
       expectedResultWithLowerCase,
     )
   })
@@ -620,49 +551,61 @@ describe('decodePath', () => {
       // /%0d/google.com/ decodes to /\r/google.com/ which becomes //google.com/
       // This must be sanitized to prevent protocol-relative URL interpretation
       const result = decodePath('/%0d/google.com/')
-      expect(result).toBe('/google.com/')
-      expect(result).not.toMatch(/^\/\//)
+      expect(result.path).toBe('/google.com/')
+      expect(result.path).not.toMatch(/^\/\//)
+      expect(result.handledProtocolRelativeURL).toBe(true)
     })
 
     it('should strip LF (%0a) to prevent open redirect', () => {
       const result = decodePath('/%0a/evil.com/')
-      expect(result).toBe('/evil.com/')
-      expect(result).not.toMatch(/^\/\//)
+      expect(result.path).toBe('/evil.com/')
+      expect(result.path).not.toMatch(/^\/\//)
+      expect(result.handledProtocolRelativeURL).toBe(true)
     })
 
     it('should strip CRLF (%0d%0a) to prevent open redirect', () => {
       const result = decodePath('/%0d%0a/evil.com/')
-      expect(result).toBe('/evil.com/')
-      expect(result).not.toMatch(/^\/\//)
+      expect(result.path).toBe('/evil.com/')
+      expect(result.path).not.toMatch(/^\/\//)
+      expect(result.handledProtocolRelativeURL).toBe(true)
     })
 
     it('should strip multiple control characters to prevent open redirect', () => {
       const result = decodePath('/%0d%0d%0d/evil.com/')
-      expect(result).toBe('/evil.com/')
-      expect(result).not.toMatch(/^\/\//)
+      expect(result.path).toBe('/evil.com/')
+      expect(result.path).not.toMatch(/^\/\//)
+      expect(result.handledProtocolRelativeURL).toBe(true)
     })
 
     it('should strip null bytes and other control characters', () => {
       const result = decodePath('/%00/test/')
-      expect(result).toBe('/test/')
+      expect(result.path).toBe('/test/')
+      expect(result.handledProtocolRelativeURL).toBe(true)
     })
 
     it('should collapse leading double slashes to prevent protocol-relative URLs', () => {
       // After stripping control chars, ensure we don't end up with //evil.com
       const result = decodePath('/%0d%0a/evil.com/path')
       // Should resolve to localhost, not evil.com
-      const url = new URL(result, 'http://localhost:3000')
+      const url = new URL(result.path, 'http://localhost:3000')
       expect(url.origin).toBe('http://localhost:3000')
+      expect(result.handledProtocolRelativeURL).toBe(true)
     })
 
     it('should handle normal paths unchanged', () => {
-      expect(decodePath('/users/profile/')).toBe('/users/profile/')
-      expect(decodePath('/api/v1/data')).toBe('/api/v1/data')
+      expect(decodePath('/users/profile/').path).toBe('/users/profile/')
+      expect(decodePath('/users/profile/').handledProtocolRelativeURL).toBe(
+        false,
+      )
+      expect(decodePath('/api/v1/data').path).toBe('/api/v1/data')
+      expect(decodePath('/api/v1/data').handledProtocolRelativeURL).toBe(false)
     })
 
     it('should handle double slash only input', () => {
       // Direct // input should also be collapsed
-      expect(decodePath('//')).toBe('/')
+      const result = decodePath('//')
+      expect(result.path).toBe('/')
+      expect(result.handledProtocolRelativeURL).toBe(true)
     })
   })
 })
diff --git a/packages/router-devtools-core/package.json b/packages/router-devtools-core/package.json
index f4a763d90d..f7aa43dc6c 100644
--- a/packages/router-devtools-core/package.json
+++ b/packages/router-devtools-core/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/router-devtools-core",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for Web applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/router-devtools-core/src/BaseTanStackRouterDevtoolsPanel.tsx b/packages/router-devtools-core/src/BaseTanStackRouterDevtoolsPanel.tsx
index c306d82d80..88fb0ff8d5 100644
--- a/packages/router-devtools-core/src/BaseTanStackRouterDevtoolsPanel.tsx
+++ b/packages/router-devtools-core/src/BaseTanStackRouterDevtoolsPanel.tsx
@@ -141,10 +141,13 @@ function RouteComp({
 }) {
   const styles = useStyles()
   const matches = createMemo(
-    () => routerState().pendingMatches || routerState().matches,
+    () =>
+      routerState().status === 'pending'
+        ? router().matchRoutes(router().latestLocation)
+        : routerState().matches,
   )
   const match = createMemo(() =>
-    routerState().matches.find((d) => d.routeId === route.id),
+    matches().find((d) => d.routeId === route.id),
   )
 
   const param = createMemo(() => {
@@ -279,6 +282,14 @@ export const BaseTanStackRouterDevtoolsPanel =
 
     const [history, setHistory] = createSignal<Array<AnyRouteMatch>>([])
     const [hasHistoryOverflowed, setHasHistoryOverflowed] = createSignal(false)
+    const pendingMatches = createMemo(() =>
+      routerState().status === 'pending'
+        ? router().matchRoutes(router().latestLocation)
+        : [],
+    )
+    const displayedMatches = createMemo(() =>
+      pendingMatches().length ? pendingMatches() : routerState().matches,
+    )
 
     createEffect(() => {
       const matches = routerState().matches
@@ -309,7 +320,7 @@ export const BaseTanStackRouterDevtoolsPanel =
 
     const activeMatch = createMemo(() => {
       const matches = [
-        ...(routerState().pendingMatches ?? []),
+        ...pendingMatches(),
         ...routerState().matches,
         ...routerState().cachedMatches,
       ]
@@ -521,10 +532,7 @@ export const BaseTanStackRouterDevtoolsPanel =
                 </Match>
                 <Match when={currentTab() === 'matches'}>
                   <div>
-                    {(routerState().pendingMatches?.length
-                      ? routerState().pendingMatches
-                      : routerState().matches
-                    )?.map((match: any, _i: any) => {
+                    {displayedMatches().map((match: any, _i: any) => {
                       return (
                         <div
                           role="button"
@@ -679,9 +687,7 @@ export const BaseTanStackRouterDevtoolsPanel =
                 <div class={styles().matchDetailsInfoLabel}>
                   <div>State:</div>
                   <div class={styles().matchDetailsInfo}>
-                    {routerState().pendingMatches?.find(
-                      (d: any) => d.id === activeMatch()?.id,
-                    )
+                    {pendingMatches().find((d: any) => d.id === activeMatch()?.id)
                       ? 'Pending'
                       : routerState().matches.find(
                             (d: any) => d.id === activeMatch()?.id,
diff --git a/packages/router-devtools/package.json b/packages/router-devtools/package.json
index 8bc7ed1eef..87637067d9 100644
--- a/packages/router-devtools/package.json
+++ b/packages/router-devtools/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/router-devtools",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/router-generator/package.json b/packages/router-generator/package.json
index e916251101..9bca1d9ab0 100644
--- a/packages/router-generator/package.json
+++ b/packages/router-generator/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/router-generator",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/router-plugin/ARCHITECTURE-CODE-SPLITTING.md b/packages/router-plugin/ARCHITECTURE-CODE-SPLITTING.md
new file mode 100644
index 0000000000..b301693078
--- /dev/null
+++ b/packages/router-plugin/ARCHITECTURE-CODE-SPLITTING.md
@@ -0,0 +1,992 @@
+# Automatic Code-Splitting Architecture
+
+> Internal documentation for the TanStack Router code-splitting system.
+> This covers the Babel-based transform pipeline that splits route files into
+> lazily-loaded modules (typically separate chunks) at build time.
+
+---
+
+## Table of Contents
+
+1. [Overview](#overview)
+2. [Architecture Diagram](#architecture-diagram)
+3. [Plugin Pipeline](#plugin-pipeline)
+4. [Virtual File Mechanism](#virtual-file-mechanism)
+5. [Shared Bindings System](#shared-bindings-system)
+6. [Code Split Groupings](#code-split-groupings)
+7. [Compiler Functions Reference](#compiler-functions-reference)
+8. [Dead Code Elimination](#dead-code-elimination)
+9. [Framework Support](#framework-support)
+10. [Edge Cases and Gotchas](#edge-cases-and-gotchas)
+11. [Module Graph Diagrams](#module-graph-diagrams)
+
+---
+
+## Overview
+
+TanStack Router's automatic code-splitting transforms a single route file into
+multiple modules at build time so that heavy route properties (components,
+loaders) are loaded on demand rather than eagerly.
+
+Given a route file like:
+
+```tsx
+// src/routes/about.tsx
+import { createFileRoute } from '@tanstack/react-router'
+
+export const Route = createFileRoute('/about')({
+  loader: () => fetchAboutData(),
+  component: () => <div>About page</div>,
+})
+```
+
+The plugin produces up to three modules from the **same physical file**:
+
+| Module                                    | What it contains                                                                                                                                                                                       |
+| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `about.tsx` (reference)                   | Route config with `component` replaced by `lazyRouteComponent($$splitComponentImporter, 'component')` and an injected `const $$splitComponentImporter = () => import('about.tsx?tsr-split=component')` |
+| `about.tsx?tsr-split=component` (virtual) | Only the component function, exported as `component`                                                                                                                                                   |
+| `about.tsx?tsr-shared=1` (shared)         | Optional; created only when bindings are shared between split and non-split properties                                                                                                                 |
+
+The bundler (Vite, Webpack, Rspack) treats query-parameterized imports as
+distinct modules, so `about.tsx` and `about.tsx?tsr-split=component` are
+separate entries in the module graph — each transformed differently by the
+corresponding plugin.
+
+### Why This Exists
+
+Without code-splitting, every route's component tree ships in the initial
+bundle. For large applications with dozens of routes, this means megabytes
+of JavaScript the user downloads but never executes until they navigate to
+that specific route. Automatic code-splitting solves this by:
+
+1. Replacing component/loader values with lazy wrappers (dynamic `import()`)
+2. Stripping the original implementations via dead-code elimination
+3. Producing separate modules (typically separate chunks) the bundler can load on demand
+
+---
+
+## Architecture Diagram
+
+```mermaid
+flowchart TB
+    subgraph "Physical File System"
+        RF["src/routes/about.tsx<br/>(original source)"]
+    end
+
+    subgraph "Plugin 1: compile-reference-file"
+        P1["Transform about.tsx<br/>• computeSharedBindings()<br/>• compileCodeSplitReferenceRoute()"]
+    end
+
+    subgraph "Plugin 2: compile-virtual-file"
+        P2["Transform about.tsx?tsr-split=component<br/>• compileCodeSplitVirtualRoute()"]
+    end
+
+    subgraph "Plugin 3: compile-shared-file"
+        P3["Transform about.tsx?tsr-shared=1<br/>• compileCodeSplitSharedRoute()"]
+    end
+
+    SBM[("sharedBindingsMap<br/>(closure-shared Map)")]
+
+    RF --> P1
+    P1 -->|"writes shared bindings"| SBM
+    P1 -->|"emits import('...?tsr-split=...')"| P2
+    P1 -->|"emits import('...?tsr-shared=1')\n(only when needed)"| P3
+    SBM -->|"reads shared bindings"| P2
+    SBM -->|"reads shared bindings"| P3
+
+    subgraph "Bundler Output"
+        REF["Reference module<br/>(Route config + lazy wrappers)"]
+        SPLIT["Split module(s)<br/>(component, errorComponent, etc.)"]
+        SHARED["Shared module<br/>(shared bindings, if any)"]
+    end
+
+    P1 --> REF
+    P2 --> SPLIT
+    P3 --> SHARED
+```
+
+---
+
+## Plugin Pipeline
+
+`unpluginRouterCodeSplitterFactory` (in `router-code-splitter-plugin.ts`)
+returns an **array of 3 plugins** that share a closure containing:
+
+- `sharedBindingsMap: Map<string, Set<string>>` — maps normalized file paths
+  to their computed shared binding names
+- `userConfig` — resolved plugin configuration
+- Helper functions for grouping resolution
+
+### Plugin 1: `tanstack-router:code-splitter:compile-reference-file`
+
+**Filter:** File IDs matching `/\.(m|c)?(j|t)sx?$/` whose code contains one of
+`createFileRoute(`, `createRootRoute(`, or `createRootRouteWithContext(`.
+Excludes file IDs that include `tsr-split` or `tsr-shared`.
+
+**What it does:**
+
+1. Detects per-route `codeSplitGroupings` if specified inline
+2. Calls `computeSharedBindings()` and caches the result in `sharedBindingsMap`
+3. Calls `compileCodeSplitReferenceRoute()` which:
+   - Replaces split properties with `lazyRouteComponent()` / `lazyFn()` wrappers
+   - Injects `import()` expressions pointing to `?tsr-split=<encoded>` URLs
+   - Removes shared binding declarations, replacing them with
+     `import { ... } from '...?tsr-shared=1'`
+   - Re-exports any user-exported shared bindings via
+     `export { ... } from '...?tsr-shared=1'`
+   - Runs dead-code elimination
+   - Optionally appends HMR handling code (dev mode)
+
+**Vite hooks:**
+
+- `configResolved`: Validates plugin ordering (router must come before JSX
+  transformation plugins like `@vitejs/plugin-react`)
+- `applyToEnvironment`: Scopes the plugin to a specific Vite environment when
+  `plugin.vite.environmentName` is configured (needed for TanStack Start which
+  creates separate client/SSR plugin instances)
+
+### Plugin 2: `tanstack-router:code-splitter:compile-virtual-file`
+
+**Filter:** File IDs containing `tsr-split`.
+
+**What it does:**
+
+1. Extracts the grouping from the `?tsr-split=<encoded>` query parameter
+2. Decodes it via `decodeIdentifier()` to get the list of properties this
+   virtual file should export (e.g., `['component']`)
+3. Reads shared bindings from `sharedBindingsMap` for the base file
+4. Calls `compileCodeSplitVirtualRoute()` which:
+   - Removes shared binding declarations before traversal (prevents scope
+     collision crashes)
+   - Keeps only the intended split properties as named exports
+   - Converts user-exported declarations to imports from the base file
+   - Adds `import { ... } from '...?tsr-shared=1'` if shared bindings exist
+   - Runs dead-code elimination
+   - Strips orphaned expression statements
+
+**Vite hooks:**
+
+- `applyToEnvironment`: Same environment scoping behavior as the reference
+  plugin.
+
+### Plugin 3: `tanstack-router:code-splitter:compile-shared-file`
+
+**Filter:** File IDs containing `tsr-shared`.
+
+**What it does:**
+
+1. Extracts the base file path from the ID
+2. Looks up shared bindings from `sharedBindingsMap`
+3. Calls `compileCodeSplitSharedRoute()` which:
+   - Keeps only declarations of shared bindings and their transitive
+     dependencies
+   - Strips `export` wrappers from kept declarations
+   - Adds a single `export { ... }` statement for all shared bindings
+   - Runs dead-code elimination to remove unused imports
+
+**Vite hooks:**
+
+- `applyToEnvironment`: Same environment scoping behavior as the reference
+  plugin.
+
+---
+
+## Virtual File Mechanism
+
+The system does **not** create actual virtual files. Instead, it leverages
+the fact that bundlers (Vite, Webpack, Rspack) treat the same physical file
+with different query parameters as distinct module IDs:
+
+```
+src/routes/about.tsx                        → Module A (reference)
+src/routes/about.tsx?tsr-split=component    → Module B (virtual/split)
+src/routes/about.tsx?tsr-shared=1           → Module C (shared)
+```
+
+All three modules start from the **same source code** — the bundler reads the
+physical file each time. Each plugin's `transform` filter matches on different
+query parameters, so each module gets a different transformation applied.
+
+### Path ID Encoding
+
+The `?tsr-split` query parameter value is an encoded representation of the
+split grouping. The encoding (in `path-ids.ts`) works as follows:
+
+1. Sort the property names alphabetically (grouping order is not preserved)
+2. Join with `---` delimiter
+3. Replace unsafe URL characters with safe tokens:
+   - `/` → `--slash--`
+   - `?` → `--question--`
+   - `#` → `--hash--`
+   - etc.
+
+For example, a grouping of `['component']` becomes `?tsr-split=component`.
+A combined grouping of `['component', 'errorComponent']` becomes
+`?tsr-split=component---errorComponent`.
+
+The decoding is the inverse: `decodeIdentifier()` reverses the token
+replacements and splits on `---`.
+
+Note: this encoding is not a general-purpose reversible scheme (it maps spaces
+to `_` and decodes `_` back to spaces). It's safe here because split grouping
+strings are known route option keys like `component` and `loader`.
+
+### Resolution Flow
+
+When the reference compiler emits:
+
+```js
+const $$splitComponentImporter = () => import('about.tsx?tsr-split=component')
+```
+
+The bundler:
+
+1. Resolves `about.tsx?tsr-split=component` to the physical file `about.tsx`
+   with the query parameter preserved
+2. Reads the source of `about.tsx`
+3. Runs the transform pipeline — Plugin 2 matches (`tsr-split` in ID) and
+   transforms it into a module that exports only `component`
+4. The result is a separate module in the output graph (often a separate chunk, depending on bundler chunking)
+
+---
+
+## Shared Bindings System
+
+### The Problem
+
+Consider a route file with a module-level variable used by both the `loader`
+(non-split by default) and the `component` (split by default):
+
+```tsx
+const cache = new Map()
+function getCached(key: string) {
+  return cache.get(key)
+}
+function setCached(key: string, val: unknown) {
+  cache.set(key, val)
+}
+
+export const Route = createFileRoute('/cached')({
+  loader: async () => {
+    setCached('data', await fetch('/api').then((r) => r.json()))
+    return getCached('data')
+  },
+  component: () => <div>{JSON.stringify(getCached('data'))}</div>,
+})
+```
+
+Without the shared bindings system, `cache` and `getCached` would be
+**duplicated** — one copy in the reference module (used by `loader`) and another
+in the split component module. Each would have its own `Map` instance, so
+`setCached` in the loader would write to a different map than `getCached` in
+the component reads from. This is a **correctness bug**, not just a bundle
+size issue.
+
+### The Solution
+
+`computeSharedBindings()` identifies bindings that are referenced by properties
+in 2+ distinct "groups" (where each split grouping index is one group, and all
+non-split properties form group `-1`). These bindings are extracted into a
+third virtual module (`?tsr-shared=1`) that both the reference module and the
+split modules import from, ensuring a single shared instance.
+
+### How `computeSharedBindings()` Works
+
+**Location:** `src/core/code-splitter/compilers.ts` (`computeSharedBindings`)
+
+**Algorithm:**
+
+1. **Collect local bindings** — Cheap loop over `program.body` to find all
+   module-level `const`/`let`/`var`/`function`/`class` declarations. Deletes
+   `Route` from the set (must never be extracted). If no local bindings
+   remain, returns empty set immediately (fast path).
+
+2. **Find route options** — Uses `babel.traverse` to locate the
+   `createFileRoute('/')({ ... })` call and extract the options object.
+
+3. **Fast path: group count check** — Iterates over route option properties,
+   tracking whether any non-split properties exist, and counting distinct
+   split group indices.
+   - If there are no non-split properties and fewer than 2 split groups are
+     present, nothing can be shared and it returns an empty set.
+
+4. **Build dependency graph** — `buildDependencyGraph()` creates a map from
+   each local binding to the set of other local bindings it references. Uses
+   `collectIdentifiersFromNode()` (a fast recursive walker, much cheaper than
+   `babel.traverse`) for each declaration.
+
+5. **Attribute bindings to groups** — For each route option property:
+   - Collects direct module-level references from the property value
+   - Expands transitively via the dependency graph (BFS)
+   - Records which group index each binding belongs to
+
+6. **Identify shared bindings** — Any binding appearing in 2+ distinct groups
+   is shared.
+
+7. **Handle destructured declarators** — If bindings from the same
+   `const { a, b } = fn()` appear in different groups, the entire declarator
+   must be shared (can't split the initialization).
+
+8. **Expand destructured declarations** — If any binding in a destructured
+   pattern is shared, all bindings in that pattern must be shared.
+
+9. **Remove Route-dependent bindings** — `removeBindingsDependingOnRoute()`
+   builds a reverse dependency graph, walks backwards from `Route` via BFS,
+   and removes any shared binding that transitively depends on `Route`. This
+   prevents Route duplication in the shared module.
+
+### Concrete Example
+
+**Input** (`shared-function.tsx`):
+
+```tsx
+import { createFileRoute } from '@tanstack/react-router'
+
+const cache = new Map()
+function getCached(key: string) {
+  return cache.get(key)
+}
+function setCached(key: string, val: unknown) {
+  cache.set(key, val)
+}
+
+export const Route = createFileRoute('/cached')({
+  loader: async () => {
+    setCached('data', await fetch('/api').then((r) => r.json()))
+    return getCached('data')
+  },
+  component: () => <div>{JSON.stringify(getCached('data'))}</div>,
+})
+```
+
+**Analysis:**
+
+- `loader` is non-split (group `-1`), references: `setCached`, `getCached`
+- `component` is split (group `0`), references: `getCached`
+- `getCached` appears in groups `-1` and `0` → **shared**
+- `getCached` depends on `cache` → `cache` is transitively shared
+- `setCached` appears only in group `-1` → **not shared**
+
+**Output — Reference file** (`shared-function.tsx`):
+
+```tsx
+import { getCached, cache } from 'shared-function.tsx?tsr-shared=1'
+const $$splitComponentImporter = () =>
+  import('shared-function.tsx?tsr-split=component')
+import { lazyRouteComponent } from '@tanstack/react-router'
+import { createFileRoute } from '@tanstack/react-router'
+function setCached(key: string, val: unknown) {
+  cache.set(key, val)
+}
+export const Route = createFileRoute('/cached')({
+  loader: async () => {
+    setCached('data', await fetch('/api').then((r) => r.json()))
+    return getCached('data')
+  },
+  component: lazyRouteComponent($$splitComponentImporter, 'component'),
+})
+```
+
+**Output — Split module** (`shared-function.tsx?tsr-split=component`):
+
+```tsx
+import { getCached } from 'shared-function.tsx?tsr-shared=1'
+const SplitComponent = () => <div>{JSON.stringify(getCached('data'))}</div>
+export { SplitComponent as component }
+```
+
+**Output — Shared module** (`shared-function.tsx?tsr-shared=1`):
+
+```tsx
+const cache = new Map()
+function getCached(key: string) {
+  return cache.get(key)
+}
+export { cache, getCached }
+```
+
+Note how `setCached` is **not** in the shared module — it's only used by
+`loader` (non-split), so it stays in the reference file. The reference file
+imports `cache` (needed by `setCached`) from the shared module.
+
+### Cross-Plugin Communication
+
+The three plugins share a closure containing `sharedBindingsMap`:
+
+```
+Plugin 1 (reference): computeSharedBindings() → sharedBindingsMap.set(id, bindings)
+Plugin 2 (virtual):   sharedBindingsMap.get(baseId) → pass to compileCodeSplitVirtualRoute()
+Plugin 3 (shared):    sharedBindingsMap.get(baseId) → pass to compileCodeSplitSharedRoute()
+```
+
+This works because all three plugins run in the same JavaScript process and
+the map is captured by closure. In typical builds, the reference module is
+transformed first and then the bundler resolves the emitted dynamic imports,
+which triggers transformations for the virtual/shared module IDs.
+
+---
+
+## Code Split Groupings
+
+### Default Groupings
+
+Defined in `constants.ts`:
+
+```ts
+export const defaultCodeSplitGroupings: CodeSplitGroupings = [
+  ['component'], // group 0 → separate module ID (often a separate chunk)
+  ['errorComponent'], // group 1 → separate module ID (often a separate chunk)
+  ['notFoundComponent'], // group 2 → separate module ID (often a separate chunk)
+]
+```
+
+**Important:** `loader` is **not** split by default. It stays in the reference
+file alongside non-split properties like `beforeLoad`, `validateSearch`,
+`context`, etc.
+
+### Splittable Properties
+
+Only these 5 properties can be split (defined in `splitRouteIdentNodes`):
+
+- `loader`
+- `component`
+- `pendingComponent`
+- `errorComponent`
+- `notFoundComponent`
+
+Any property not in `splitRouteIdentNodes` is never split, regardless of
+configuration.
+
+### How Groupings Work
+
+Each array within the groupings array represents one split module ID.
+Properties in the same inner array end up in the same split module:
+
+```ts
+// Default: 3 separate split module IDs (often 3 separate chunks)
+;[['component'], ['errorComponent'], ['notFoundComponent']][
+  // Combined: component + loader in one module, error in another
+  (['component', 'loader'], ['errorComponent'])
+][
+  // All in one module
+  ['component', 'loader', 'errorComponent', 'notFoundComponent']
+]
+```
+
+### Configuring Groupings
+
+There are three levels of configuration, applied with this priority:
+
+1. **Per-route inline** (highest priority):
+
+   ```tsx
+   export const Route = createFileRoute('/about')({
+     codeSplitGroupings: [['component', 'loader']],
+     component: ...,
+     loader: ...,
+   })
+   ```
+
+2. **Per-route via plugin** (`splitBehavior` callback):
+
+   ```ts
+   tanstackRouter({
+     codeSplittingOptions: {
+       splitBehavior: ({ routeId }) => {
+         if (routeId === '/dashboard') return [['component', 'loader']]
+         return undefined // use default
+       },
+     },
+   })
+   ```
+
+3. **Global default** (`defaultBehavior`):
+   ```ts
+   tanstackRouter({
+     codeSplittingOptions: {
+       defaultBehavior: [['component', 'loader'], ['errorComponent']],
+     },
+   })
+   ```
+
+### `findIndexForSplitNode()`
+
+This function determines which group a property belongs to:
+
+```ts
+function findIndexForSplitNode(str: string) {
+  return opts.codeSplitGroupings.findIndex((group) =>
+    group.includes(str as any),
+  )
+}
+```
+
+Returns the group index (`0`, `1`, `2`, ...) for split properties, or `-1`
+for properties not in any group (non-split properties like `beforeLoad`,
+`validateSearch`, `context`, etc.).
+
+The group index `-1` is treated as its own group in the shared bindings
+computation — it represents "stays in the reference file."
+
+---
+
+## Compiler Functions Reference
+
+All compiler functions live in `compilers.ts`.
+
+### `compileCodeSplitReferenceRoute()`
+
+**Purpose:** Transform the original route file into the "reference" module.
+
+**Input:** Original source code, split groupings, framework target, options.
+
+**Output:** Modified source where split properties are replaced with lazy
+wrappers, shared bindings are replaced with imports, and dead code is
+eliminated.
+
+**Key steps:**
+
+1. Parse AST, collect `findReferencedIdentifiers()` for DCE
+2. For each split-able property in route options:
+   - Check if the value is exported (if so, skip splitting — warn user)
+   - Generate a dynamic import URL: `addSplitSearchParamToFilename()`
+   - Create importer: `const $$splitComponentImporter = () => import('...')`
+   - Replace property value with `lazyRouteComponent(importer, 'component')`
+     or `lazyFn(importer, 'loader')`
+3. Remove unused import paths
+4. If shared bindings exist:
+   - Remove shared declarations from AST
+   - Add `import { ... } from '...?tsr-shared=1'`
+   - Re-export user-exported shared bindings
+5. Run `deadCodeElimination()`
+6. Generate output code with source maps
+
+### `compileCodeSplitVirtualRoute()`
+
+**Purpose:** Transform a copy of the route file into a split module that
+exports only specific properties.
+
+**Input:** Original source code, split targets (e.g., `['component']`),
+shared bindings set.
+
+**Output:** A module that exports only the intended properties.
+
+**Key steps:**
+
+1. Parse AST, collect referenced identifiers
+2. **Remove shared declarations first** (before `babel.traverse`) — critical
+   to avoid `checkBlockScopedCollisions` crashes
+3. Track split-able nodes and their metadata
+4. For each intended split target:
+   - Resolve the property value through bindings
+   - Create a named export (e.g., `export { SplitComponent as component }`)
+5. Convert remaining user exports to imports from the base file
+6. Add shared bindings import if applicable
+7. Run `deadCodeElimination()`
+8. Strip orphaned expression statements
+9. Generate output with source maps
+
+### `compileCodeSplitSharedRoute()`
+
+**Purpose:** Produce the shared virtual module containing only the shared
+binding declarations.
+
+**Input:** Original source code, set of shared binding names.
+
+**Output:** A module that declares and exports only shared bindings and their
+transitive dependencies.
+
+**Key steps:**
+
+1. Parse AST, collect referenced identifiers
+2. Build dependency graph, expand shared bindings transitively
+3. Filter `program.body` to keep only:
+   - Import declarations (DCE removes unused ones)
+   - Declarations of bindings in the keep set
+4. Strip `export` wrappers from kept declarations
+5. Add `export { ... }` for all shared bindings
+6. Run `deadCodeElimination()`
+7. Generate output with source maps
+
+### `computeSharedBindings()`
+
+**Purpose:** Analyze a route file to determine which module-level bindings
+are referenced by multiple split groups.
+
+See [Shared Bindings System](#shared-bindings-system) for the full algorithm.
+
+### `detectCodeSplitGroupingsFromRoute()`
+
+**Purpose:** Parse inline `codeSplitGroupings` from route options.
+
+Traverses the AST looking for a `codeSplitGroupings` property on the route
+options object (supports both `createFileRoute` and `createRoute` call sites).
+If found, extracts the array-of-arrays value and returns it.
+
+### Helper Functions
+
+| Function                                | Purpose                                                                                                        |
+| --------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
+| `collectIdentifiersFromNode()`          | Fast recursive walker to collect referenced identifier names from any AST node. Cheaper than `babel.traverse`. |
+| `buildDeclarationMap()`                 | Maps binding name → AST declaration node for all module-level declarations.                                    |
+| `buildDependencyGraph()`                | Maps binding name → set of other local bindings it references.                                                 |
+| `expandTransitively()`                  | BFS expansion of a set through a dependency graph.                                                             |
+| `removeBindingsDependingOnRoute()`      | Reverse-graph BFS from `Route` to find and remove dependents.                                                  |
+| `expandDestructuredDeclarations()`      | If any binding in a destructured pattern is shared, mark all as shared.                                        |
+| `expandSharedDestructuredDeclarators()` | If bindings from same declarator appear in different groups, mark declarator as shared.                        |
+| `collectLocalBindingsFromStatement()`   | Collects locally-declared names from a statement (cheap, no traversal).                                        |
+| `collectModuleLevelRefsFromNode()`      | Intersects `collectIdentifiersFromNode()` with local module-level bindings.                                    |
+| `removeSharedDeclarations()`            | Filters shared binding declarations out of `program.body`.                                                     |
+| `findExportedSharedBindings()`          | Finds which shared bindings have `export` in the original source.                                              |
+
+---
+
+## Dead Code Elimination
+
+After each compiler transforms the AST, it runs `deadCodeElimination()` from
+`@tanstack/router-utils`. This is critical because:
+
+- The reference file no longer uses the component implementation (it was
+  replaced with a lazy wrapper), so the original component code and its
+  dependencies should be stripped.
+- The virtual file only exports specific properties, so everything else
+  (loader, beforeLoad, other components) should be stripped.
+- The shared file only keeps shared bindings, so everything else should be
+  stripped.
+
+### How It Works
+
+1. **`findReferencedIdentifiers(ast)`** — Collects all `Identifier` NodePaths
+   in the AST that are in a "referenced" position (not binding sites). Returns
+   a `Set<NodePath>`.
+
+2. **`deadCodeElimination(ast, refIdents)`** — Iterates over all bindings in
+   the program scope. For each binding, checks whether any of its references
+   are in `refIdents`. If not, the binding is unreferenced and its declaration
+   is removed. Repeats until no more bindings can be removed (handles chains
+   where removing one binding makes another unreferenced).
+
+### Import Registration for DCE
+
+When the compilers add new imports (for shared bindings, or convert exports
+to imports in virtual files), they must register the import specifier locals
+in `refIdents` so DCE can later decide whether to keep or remove them:
+
+```ts
+sharedImportPath.traverse({
+  Identifier(identPath) {
+    if (identPath.parentPath.isImportSpecifier() && identPath.key === 'local') {
+      refIdents.add(identPath)
+    }
+  },
+})
+```
+
+Without this, DCE would have no path references for the new imports and would
+always remove them.
+
+### Post-DCE Cleanup in Virtual Files
+
+DCE only removes unused **declarations**. Bare side-effect statements like
+`console.log(...)` survive even when no locally-bound names reference them.
+The virtual compiler has an additional cleanup pass:
+
+```ts
+ast.program.body = ast.program.body.filter((stmt) => {
+  if (!t.isExpressionStatement(stmt)) return true
+  const refs = collectIdentifiersFromNode(stmt)
+  return [...refs].some((name) => locallyBound.has(name))
+})
+```
+
+This strips expression statements that don't reference any locally-bound name.
+
+### Directive Prologue Handling
+
+If the file body is empty after DCE (virtual file where no properties matched),
+directive prologues (`'use client'`, `'use strict'`) are also stripped:
+
+```ts
+if (ast.program.body.length === 0) {
+  ast.program.directives = []
+}
+```
+
+---
+
+## Framework Support
+
+The code-splitting system is framework-agnostic at the Babel transform level.
+Framework differences are confined to `framework-options.ts`:
+
+| Framework | Package                  | `createFileRoute` | `lazyFn` | `lazyRouteComponent` |
+| --------- | ------------------------ | ----------------- | -------- | -------------------- |
+| React     | `@tanstack/react-router` | `createFileRoute` | `lazyFn` | `lazyRouteComponent` |
+| Solid     | `@tanstack/solid-router` | `createFileRoute` | `lazyFn` | `lazyRouteComponent` |
+| Vue       | `@tanstack/vue-router`   | `createFileRoute` | `lazyFn` | `lazyRouteComponent` |
+
+Currently all frameworks use the same identifier names. The framework option
+is used to determine which package to import `lazyRouteComponent` and `lazyFn`
+from.
+
+### Plugin Order Validation (Vite only)
+
+The reference plugin's `configResolved` hook checks that the TanStack Router
+plugin appears **before** JSX transformation plugins in the Vite config. This
+is required because the code-splitter must transform the source before JSX
+is compiled away. Validated plugins:
+
+- **React:** `@vitejs/plugin-react` (Babel), `@vitejs/plugin-react-swc` (SWC),
+  `@vitejs/plugin-react-oxc` (OXC)
+- **Solid:** `vite-plugin-solid`
+
+If the order is wrong, the plugin throws an error with a suggested fix.
+
+### Environment Scoping
+
+When `userConfig.plugin?.vite?.environmentName` is set, all three plugins use
+`applyToEnvironment` to restrict themselves to that specific Vite environment.
+This is necessary for TanStack Start, which creates separate plugin instances
+for client and SSR environments.
+
+---
+
+## Edge Cases and Gotchas
+
+### 1. Exported Identifiers Are Not Split
+
+If a value for a splittable route option is exported from the route file
+(e.g. `export const MyComp = ...` used as `component: MyComp`), the plugin
+**skips** splitting it. The value stays in the reference file and a warning is
+emitted:
+
+```
+[tanstack-router] These exports from "about.tsx" will not be code-split and will increase your bundle size:
+- MyComp
+For the best optimization, these items should either have their export statements removed, or be imported from another location that is not a route file.
+```
+
+This is because other modules may import `MyComp` directly, and splitting it
+would break those imports. (In dev, the warning is also injected into the
+compiled output as a `console.warn` to make it obvious during local testing.)
+
+### 2. Root Routes Are Never Split
+
+`createRootRoute()` and `createRootRouteWithContext()` are in
+`unsplittableCreateRouteFns`. The reference compiler adds HMR handling but
+exits before attempting any code-splitting transforms.
+
+### 3. `undefined`, `null`, and `boolean` Values Are Kept In-Place
+
+Properties with these literal values are not split:
+
+```tsx
+createFileRoute('/about')({
+  component: undefined, // kept in reference
+  errorComponent: false, // kept in reference
+  notFoundComponent: null, // kept in reference
+})
+```
+
+These represent "fall back to parent route" semantics and must not be moved.
+
+### 4. Destructured Declarations Must Be Shared Atomically
+
+```tsx
+const { a, b } = createHelpers()
+```
+
+If `a` is used by `component` (split) and `b` is used by `loader` (non-split),
+the entire `const { a, b } = createHelpers()` declaration must go to the
+shared module. You can't split the initialization — calling `createHelpers()`
+twice would be incorrect.
+
+### 5. Route-Dependent Bindings Cannot Be Shared
+
+```tsx
+const routePath = Route.fullPath
+function useRouteStuff() {
+  return routePath
+}
+```
+
+Even if `useRouteStuff` is referenced by multiple groups, it cannot be
+extracted to the shared module because it depends on `Route`. Extracting it
+would require `Route` in the shared module, duplicating the route singleton.
+`removeBindingsDependingOnRoute()` handles this via reverse-graph BFS.
+
+### 6. `removeSharedDeclarations` Must Run Before `babel.traverse` in Virtual Files
+
+In `compileCodeSplitVirtualRoute()`, shared declarations are removed
+**before** `babel.traverse` runs:
+
+```ts
+if (opts.sharedBindings && opts.sharedBindings.size > 0) {
+  removeSharedDeclarations(ast, opts.sharedBindings)
+}
+
+babel.traverse(ast, { ... })
+```
+
+If done after, Babel's scope analysis would see both the shared declaration
+and the new shared import, causing a `checkBlockScopedCollisions` crash
+(duplicate `const` binding in the same scope).
+
+### 7. Directive Prologues Survive Code-Splitting
+
+Babel stores directives (like `'use client'`) in `program.directives`, not
+in `program.body`. They are preserved through all transforms automatically.
+The only exception is when the body is completely empty after DCE — then
+directives are stripped too (a file with just `'use client'` and no code is
+useless).
+
+### 8. Plugin Ordering in the Array Matters
+
+The 3 plugins must be returned in order: reference, virtual, shared. The
+reference plugin populates `sharedBindingsMap` before the other two consume
+it. Bundlers process transforms in plugin array order for a given module ID.
+
+### 9. Imported Bindings Are Never Shared
+
+`computeSharedBindings()` only considers **locally-declared** module-level
+bindings. Import statements are handled by the bundler's module system — if
+both the reference file and a virtual file import the same external module,
+the bundler deduplicates that import automatically. No shared module needed.
+
+### 10. `SPLIT_NODES_CONFIG` — Split Strategy per Property
+
+Each splittable property has a configured split strategy:
+
+| Property            | Strategy             | Wrapper                                     |
+| ------------------- | -------------------- | ------------------------------------------- |
+| `component`         | `lazyRouteComponent` | Wraps with Suspense-compatible lazy loading |
+| `pendingComponent`  | `lazyRouteComponent` | Same                                        |
+| `errorComponent`    | `lazyRouteComponent` | Same                                        |
+| `notFoundComponent` | `lazyRouteComponent` | Same                                        |
+| `loader`            | `lazyFn`             | Wraps as a lazy function call               |
+
+Components use `lazyRouteComponent` (framework-provided). In React this
+integrates with Suspense-compatible lazy loading. Loaders use `lazyFn` which
+wraps the async function for deferred loading.
+
+### 11. Source Maps Are Preserved
+
+All three compilers pass `sourceMaps: true` and `sourceFileName` to
+`generateFromAst()`, ensuring the browser's devtools can map back to the
+original source file.
+
+---
+
+## Module Graph Diagrams
+
+### Simple Route (No Shared Bindings)
+
+```mermaid
+graph LR
+    subgraph "Reference Module"
+        REF["about.tsx"]
+    end
+
+    subgraph "Split Module"
+        COMP["about.tsx?tsr-split=component"]
+    end
+
+    REF -->|"() => import()"| COMP
+```
+
+When the route has no module-level bindings shared between split and non-split
+properties, there is no shared module. The reference module has a dynamic
+import to the split module.
+
+### Route With Shared Bindings
+
+```mermaid
+graph LR
+    subgraph "Reference Module"
+        REF["cached.tsx"]
+    end
+
+    subgraph "Split Module"
+        COMP["cached.tsx?tsr-split=component"]
+    end
+
+    subgraph "Shared Module"
+        SHARED["cached.tsx?tsr-shared=1"]
+    end
+
+    REF -->|"() => import()"| COMP
+    REF -->|"import { getCached, cache }"| SHARED
+    COMP -->|"import { getCached }"| SHARED
+```
+
+The shared module is imported synchronously by both the reference module and
+the split module. Bundlers will usually dedupe this to a single module instance;
+whether it becomes a separate chunk or gets inlined into another chunk depends
+on the bundler's chunking strategy.
+
+### Route With Multiple Split Groups
+
+```mermaid
+graph LR
+    subgraph "Reference Module"
+        REF["dashboard.tsx"]
+    end
+
+    subgraph "Split Modules"
+        COMP["dashboard.tsx?tsr-split=component"]
+        ERR["dashboard.tsx?tsr-split=errorComponent"]
+        NF["dashboard.tsx?tsr-split=notFoundComponent"]
+    end
+
+    subgraph "Shared Module"
+        SHARED["?tsr-shared=1"]
+    end
+
+    REF -->|"() => import()"| COMP
+    REF -->|"() => import()"| ERR
+    REF -->|"() => import()"| NF
+    REF --> SHARED
+    COMP --> SHARED
+    ERR --> SHARED
+    NF --> SHARED
+```
+
+Each split group gets its own split module. If a binding is shared across any
+two of these (or between a split module and the reference module), it lives in
+the shared module.
+
+### Combined Groupings
+
+```mermaid
+graph LR
+    subgraph "Reference Module"
+        REF["page.tsx"]
+    end
+
+    subgraph "Split Module"
+        COMBINED["page.tsx?tsr-split=component---loader"]
+    end
+
+    REF -->|"() => import()"| COMBINED
+```
+
+When `component` and `loader` are in the same grouping
+(`[['component', 'loader']]`), they end up in a single split module. This
+reduces the number of split modules (and likely requests) at the cost of
+loading the loader even when only the component is needed (and vice versa).
+
+---
+
+## Key Source Files
+
+| File                                          | Description                                                                  |
+| --------------------------------------------- | ---------------------------------------------------------------------------- |
+| `src/core/router-code-splitter-plugin.ts`     | Plugin factory — creates 3 plugins, manages `sharedBindingsMap`              |
+| `src/core/code-splitter/compilers.ts`         | All compiler functions (~1,970 lines)                                        |
+| `src/core/constants.ts`                       | `tsrSplit`, `tsrShared`, `splitRouteIdentNodes`, `defaultCodeSplitGroupings` |
+| `src/core/code-splitter/framework-options.ts` | Per-framework package/ident configuration                                    |
+| `src/core/code-splitter/path-ids.ts`          | URL-safe encoding/decoding for split identifiers                             |
+| `src/core/config.ts`                          | Plugin configuration types and validation                                    |
+| `src/core/route-hmr-statement.ts`             | HMR handling code template                                                   |
+| `tests/code-splitter/`                        | Unit tests and snapshot fixtures                                             |
diff --git a/packages/router-plugin/package.json b/packages/router-plugin/package.json
index 7dae551a72..7d769ce512 100644
--- a/packages/router-plugin/package.json
+++ b/packages/router-plugin/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/router-plugin",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/router-plugin/src/core/code-splitter/compilers.ts b/packages/router-plugin/src/core/code-splitter/compilers.ts
index 9a45bc020a..766a6e7790 100644
--- a/packages/router-plugin/src/core/code-splitter/compilers.ts
+++ b/packages/router-plugin/src/core/code-splitter/compilers.ts
@@ -7,7 +7,7 @@ import {
   generateFromAst,
   parseAst,
 } from '@tanstack/router-utils'
-import { tsrSplit } from '../constants'
+import { tsrShared, tsrSplit } from '../constants'
 import { routeHmrStatement } from '../route-hmr-statement'
 import { createIdentifier } from './path-ids'
 import { getFrameworkOptions } from './framework-options'
@@ -94,6 +94,11 @@ function removeSplitSearchParamFromFilename(filename: string) {
   return bareFilename!
 }
 
+export function addSharedSearchParamToFilename(filename: string) {
+  const [bareFilename] = filename.split('?')
+  return `${bareFilename}?${tsrShared}=1`
+}
+
 const splittableCreateRouteFns = ['createFileRoute']
 const unsplittableCreateRouteFns = [
   'createRootRoute',
@@ -104,6 +109,530 @@ const allCreateRouteFns = [
   ...unsplittableCreateRouteFns,
 ]
 
+/**
+ * Recursively walk an AST node and collect referenced identifier-like names.
+ * Much cheaper than babel.traverse — no path/scope overhead.
+ *
+ * Notes:
+ * - Uses @babel/types `isReferenced` to avoid collecting non-references like
+ *   object keys, member expression properties, or binding identifiers.
+ * - Also handles JSX identifiers for component references.
+ */
+export function collectIdentifiersFromNode(node: t.Node): Set<string> {
+  const ids = new Set<string>()
+
+  ;(function walk(
+    n: t.Node | null | undefined,
+    parent?: t.Node,
+    grandparent?: t.Node,
+    parentKey?: string,
+  ) {
+    if (!n) return
+
+    if (t.isIdentifier(n)) {
+      // When we don't have parent info (node passed in isolation), treat as referenced.
+      if (!parent || t.isReferenced(n, parent, grandparent)) {
+        ids.add(n.name)
+      }
+      return
+    }
+
+    if (t.isJSXIdentifier(n)) {
+      // Skip attribute names: <div data-testid="x" />
+      if (parent && t.isJSXAttribute(parent) && parentKey === 'name') {
+        return
+      }
+
+      // Skip member properties: <Foo.Bar /> should count Foo, not Bar
+      if (
+        parent &&
+        t.isJSXMemberExpression(parent) &&
+        parentKey === 'property'
+      ) {
+        return
+      }
+
+      // Intrinsic elements (lowercase) are not identifiers
+      const first = n.name[0]
+      if (first && first === first.toLowerCase()) {
+        return
+      }
+
+      ids.add(n.name)
+      return
+    }
+
+    for (const key of t.VISITOR_KEYS[n.type] || []) {
+      const child = (n as any)[key]
+      if (Array.isArray(child)) {
+        for (const c of child) {
+          if (c && typeof c.type === 'string') {
+            walk(c, n, parent, key)
+          }
+        }
+      } else if (child && typeof child.type === 'string') {
+        walk(child, n, parent, key)
+      }
+    }
+  })(node)
+
+  return ids
+}
+
+/**
+ * Build a map from binding name → declaration AST node for all
+ * locally-declared module-level bindings. Built once, O(1) lookup.
+ */
+export function buildDeclarationMap(ast: t.File): Map<string, t.Node> {
+  const map = new Map<string, t.Node>()
+  for (const stmt of ast.program.body) {
+    const decl =
+      t.isExportNamedDeclaration(stmt) && stmt.declaration
+        ? stmt.declaration
+        : stmt
+
+    if (t.isVariableDeclaration(decl)) {
+      for (const declarator of decl.declarations) {
+        for (const name of collectIdentifiersFromPattern(declarator.id)) {
+          map.set(name, declarator)
+        }
+      }
+    } else if (t.isFunctionDeclaration(decl) && decl.id) {
+      map.set(decl.id.name, decl)
+    } else if (t.isClassDeclaration(decl) && decl.id) {
+      map.set(decl.id.name, decl)
+    }
+  }
+  return map
+}
+
+/**
+ * Build a dependency graph: for each local binding, the set of other local
+ * bindings its declaration references. Built once via simple node walking.
+ */
+export function buildDependencyGraph(
+  declMap: Map<string, t.Node>,
+  localBindings: Set<string>,
+): Map<string, Set<string>> {
+  const graph = new Map<string, Set<string>>()
+  for (const [name, declNode] of declMap) {
+    if (!localBindings.has(name)) continue
+    const allIds = collectIdentifiersFromNode(declNode)
+    const deps = new Set<string>()
+    for (const id of allIds) {
+      if (id !== name && localBindings.has(id)) deps.add(id)
+    }
+    graph.set(name, deps)
+  }
+  return graph
+}
+
+/**
+ * Computes module-level bindings that are shared between split and non-split
+ * route properties. These bindings need to be extracted into a shared virtual
+ * module to avoid double-initialization.
+ *
+ * A binding is "shared" if it is referenced by at least one split property
+ * AND at least one non-split property. Only locally-declared module-level
+ * bindings are candidates (not imports — bundlers dedupe those).
+ */
+export function computeSharedBindings(opts: {
+  code: string
+  codeSplitGroupings: CodeSplitGroupings
+}): Set<string> {
+  const ast = parseAst(opts)
+
+  // Early bailout: collect all module-level locally-declared binding names.
+  // This is a cheap loop over program.body (no traversal). If the file has
+  // no local bindings (aside from `Route`), nothing can be shared — skip
+  // the expensive babel.traverse entirely.
+  const localModuleLevelBindings = new Set<string>()
+  for (const node of ast.program.body) {
+    collectLocalBindingsFromStatement(node, localModuleLevelBindings)
+  }
+
+  // File-based routes always export a route config binding (usually `Route`).
+  // This must never be extracted into the shared module.
+  localModuleLevelBindings.delete('Route')
+
+  if (localModuleLevelBindings.size === 0) {
+    return new Set()
+  }
+
+  function findIndexForSplitNode(str: string) {
+    return opts.codeSplitGroupings.findIndex((group) =>
+      group.includes(str as any),
+    )
+  }
+
+  // Find the route options object — needs babel.traverse for scope resolution
+  let routeOptions: t.ObjectExpression | undefined
+
+  babel.traverse(ast, {
+    CallExpression(path) {
+      if (!t.isIdentifier(path.node.callee)) return
+      if (!splittableCreateRouteFns.includes(path.node.callee.name)) return
+
+      if (t.isCallExpression(path.parentPath.node)) {
+        const opts = resolveIdentifier(path, path.parentPath.node.arguments[0])
+        if (t.isObjectExpression(opts)) routeOptions = opts
+      } else if (t.isVariableDeclarator(path.parentPath.node)) {
+        const caller = resolveIdentifier(path, path.parentPath.node.init)
+        if (t.isCallExpression(caller)) {
+          const opts = resolveIdentifier(path, caller.arguments[0])
+          if (t.isObjectExpression(opts)) routeOptions = opts
+        }
+      }
+    },
+  })
+
+  if (!routeOptions) return new Set()
+
+  // Fast path: if fewer than 2 distinct groups are referenced by route options,
+  // nothing can be shared and we can skip the rest of the work.
+  const splitGroupsPresent = new Set<number>()
+  let hasNonSplit = false
+  for (const prop of routeOptions.properties) {
+    if (!t.isObjectProperty(prop) || !t.isIdentifier(prop.key)) continue
+    if (prop.key.name === 'codeSplitGroupings') continue
+    if (t.isIdentifier(prop.value) && prop.value.name === 'undefined') continue
+    const groupIndex = findIndexForSplitNode(prop.key.name) // -1 if non-split
+    if (groupIndex === -1) {
+      hasNonSplit = true
+    } else {
+      splitGroupsPresent.add(groupIndex)
+    }
+  }
+
+  if (!hasNonSplit && splitGroupsPresent.size < 2) return new Set()
+
+  // Build dependency graph up front — needed for transitive expansion per-property.
+  // This graph excludes `Route` (deleted above) so group attribution works correctly.
+  const declMap = buildDeclarationMap(ast)
+  const depGraph = buildDependencyGraph(declMap, localModuleLevelBindings)
+
+  // Build a second dependency graph that includes `Route` so we can detect
+  // bindings that transitively depend on it. Such bindings must NOT be
+  // extracted into the shared module because they would drag the Route
+  // singleton with them, duplicating it across modules.
+  const allLocalBindings = new Set(localModuleLevelBindings)
+  allLocalBindings.add('Route')
+  const fullDepGraph = buildDependencyGraph(declMap, allLocalBindings)
+
+  // For each route property, track which "group" it belongs to.
+  // Non-split properties get group index -1.
+  // Split properties get their codeSplitGroupings index (0, 1, ...).
+  // A binding is "shared" if it appears in 2+ distinct groups.
+  // We expand each property's refs transitively BEFORE comparing groups,
+  // so indirect refs (e.g., component: MyComp where MyComp uses `shared`)
+  // are correctly attributed.
+  const refsByGroup = new Map<string, Set<number>>()
+
+  for (const prop of routeOptions.properties) {
+    if (!t.isObjectProperty(prop) || !t.isIdentifier(prop.key)) continue
+    const key = prop.key.name
+
+    if (key === 'codeSplitGroupings') continue
+
+    const groupIndex = findIndexForSplitNode(key) // -1 if non-split
+
+    const directRefs = collectModuleLevelRefsFromNode(
+      prop.value,
+      localModuleLevelBindings,
+    )
+
+    // Expand transitively: if component references SharedComp which references
+    // `shared`, then `shared` is also attributed to component's group.
+    const allRefs = new Set(directRefs)
+    expandTransitively(allRefs, depGraph)
+
+    for (const ref of allRefs) {
+      let groups = refsByGroup.get(ref)
+      if (!groups) {
+        groups = new Set()
+        refsByGroup.set(ref, groups)
+      }
+      groups.add(groupIndex)
+    }
+  }
+
+  // Shared = bindings appearing in 2+ distinct groups
+  const shared = new Set<string>()
+  for (const [name, groups] of refsByGroup) {
+    if (groups.size >= 2) shared.add(name)
+  }
+
+  // Destructured declarators (e.g. `const { a, b } = fn()`) must be treated
+  // as a single initialization unit. Even if each binding is referenced by
+  // only one group, if *different* bindings from the same declarator are
+  // referenced by different groups, the declarator must be extracted to the
+  // shared module to avoid double initialization.
+  expandSharedDestructuredDeclarators(ast, refsByGroup, shared)
+
+  if (shared.size === 0) return shared
+
+  // If any binding from a destructured declaration is shared,
+  // all bindings from that declaration must be shared
+  expandDestructuredDeclarations(ast, shared)
+
+  // Remove shared bindings that transitively depend on `Route`.
+  // The Route singleton must stay in the reference file; extracting a
+  // binding that references it would duplicate Route in the shared module.
+  removeBindingsDependingOnRoute(shared, fullDepGraph)
+
+  return shared
+}
+
+/**
+ * If bindings from the same destructured declarator are referenced by
+ * different groups, mark all bindings from that declarator as shared.
+ */
+export function expandSharedDestructuredDeclarators(
+  ast: t.File,
+  refsByGroup: Map<string, Set<number>>,
+  shared: Set<string>,
+) {
+  for (const stmt of ast.program.body) {
+    const decl =
+      t.isExportNamedDeclaration(stmt) && stmt.declaration
+        ? stmt.declaration
+        : stmt
+
+    if (!t.isVariableDeclaration(decl)) continue
+
+    for (const declarator of decl.declarations) {
+      if (!t.isObjectPattern(declarator.id) && !t.isArrayPattern(declarator.id))
+        continue
+
+      const names = collectIdentifiersFromPattern(declarator.id)
+
+      const usedGroups = new Set<number>()
+      for (const name of names) {
+        const groups = refsByGroup.get(name)
+        if (!groups) continue
+        for (const g of groups) usedGroups.add(g)
+      }
+
+      if (usedGroups.size >= 2) {
+        for (const name of names) {
+          shared.add(name)
+        }
+      }
+    }
+  }
+}
+
+/**
+ * Collect locally-declared module-level binding names from a statement.
+ * Pure node inspection, no traversal.
+ */
+export function collectLocalBindingsFromStatement(
+  node: t.Statement | t.ModuleDeclaration,
+  bindings: Set<string>,
+) {
+  const decl =
+    t.isExportNamedDeclaration(node) && node.declaration
+      ? node.declaration
+      : node
+
+  if (t.isVariableDeclaration(decl)) {
+    for (const declarator of decl.declarations) {
+      for (const name of collectIdentifiersFromPattern(declarator.id)) {
+        bindings.add(name)
+      }
+    }
+  } else if (t.isFunctionDeclaration(decl) && decl.id) {
+    bindings.add(decl.id.name)
+  } else if (t.isClassDeclaration(decl) && decl.id) {
+    bindings.add(decl.id.name)
+  }
+}
+
+/**
+ * Collect direct module-level binding names referenced from a given AST node.
+ * Uses a simple recursive walk instead of babel.traverse.
+ */
+export function collectModuleLevelRefsFromNode(
+  node: t.Node,
+  localModuleLevelBindings: Set<string>,
+): Set<string> {
+  const allIds = collectIdentifiersFromNode(node)
+  const refs = new Set<string>()
+  for (const name of allIds) {
+    if (localModuleLevelBindings.has(name)) refs.add(name)
+  }
+  return refs
+}
+
+/**
+ * Expand the shared set transitively using a prebuilt dependency graph.
+ * No AST traversals — pure graph BFS.
+ */
+export function expandTransitively(
+  shared: Set<string>,
+  depGraph: Map<string, Set<string>>,
+) {
+  const queue = [...shared]
+  const visited = new Set<string>()
+
+  while (queue.length > 0) {
+    const name = queue.pop()!
+    if (visited.has(name)) continue
+    visited.add(name)
+
+    const deps = depGraph.get(name)
+    if (!deps) continue
+
+    for (const dep of deps) {
+      if (!shared.has(dep)) {
+        shared.add(dep)
+        queue.push(dep)
+      }
+    }
+  }
+}
+
+/**
+ * Remove any bindings from `shared` that transitively depend on `Route`.
+ * The Route singleton must remain in the reference file; if a shared binding
+ * references it (directly or transitively), extracting that binding would
+ * duplicate Route in the shared module.
+ *
+ * Uses `depGraph` which must include `Route` as a node so the dependency
+ * chain is visible.
+ */
+export function removeBindingsDependingOnRoute(
+  shared: Set<string>,
+  depGraph: Map<string, Set<string>>,
+) {
+  const reverseGraph = new Map<string, Set<string>>()
+  for (const [name, deps] of depGraph) {
+    for (const dep of deps) {
+      let parents = reverseGraph.get(dep)
+      if (!parents) {
+        parents = new Set<string>()
+        reverseGraph.set(dep, parents)
+      }
+      parents.add(name)
+    }
+  }
+
+  // Walk backwards from Route to find all bindings that can reach it.
+  const visited = new Set<string>()
+  const queue = ['Route']
+  while (queue.length > 0) {
+    const cur = queue.pop()!
+    if (visited.has(cur)) continue
+    visited.add(cur)
+
+    const parents = reverseGraph.get(cur)
+    if (!parents) continue
+    for (const parent of parents) {
+      if (!visited.has(parent)) queue.push(parent)
+    }
+  }
+
+  for (const name of [...shared]) {
+    if (visited.has(name)) {
+      shared.delete(name)
+    }
+  }
+}
+
+/**
+ * If any binding from a destructured declaration is shared,
+ * ensure all bindings from that same declaration are also shared.
+ * Pure node inspection of program.body, no traversal.
+ */
+export function expandDestructuredDeclarations(
+  ast: t.File,
+  shared: Set<string>,
+) {
+  for (const stmt of ast.program.body) {
+    const decl =
+      t.isExportNamedDeclaration(stmt) && stmt.declaration
+        ? stmt.declaration
+        : stmt
+
+    if (!t.isVariableDeclaration(decl)) continue
+
+    for (const declarator of decl.declarations) {
+      if (!t.isObjectPattern(declarator.id) && !t.isArrayPattern(declarator.id))
+        continue
+
+      const names = collectIdentifiersFromPattern(declarator.id)
+      const hasShared = names.some((n) => shared.has(n))
+      if (hasShared) {
+        for (const n of names) {
+          shared.add(n)
+        }
+      }
+    }
+  }
+}
+
+/**
+ * Find which shared bindings are user-exported in the original source.
+ * These need to be re-exported from the shared module.
+ */
+function findExportedSharedBindings(
+  ast: t.File,
+  sharedBindings: Set<string>,
+): Set<string> {
+  const exported = new Set<string>()
+  for (const stmt of ast.program.body) {
+    if (!t.isExportNamedDeclaration(stmt) || !stmt.declaration) continue
+
+    if (t.isVariableDeclaration(stmt.declaration)) {
+      for (const decl of stmt.declaration.declarations) {
+        for (const name of collectIdentifiersFromPattern(decl.id)) {
+          if (sharedBindings.has(name)) exported.add(name)
+        }
+      }
+    } else if (
+      t.isFunctionDeclaration(stmt.declaration) &&
+      stmt.declaration.id
+    ) {
+      if (sharedBindings.has(stmt.declaration.id.name))
+        exported.add(stmt.declaration.id.name)
+    } else if (t.isClassDeclaration(stmt.declaration) && stmt.declaration.id) {
+      if (sharedBindings.has(stmt.declaration.id.name))
+        exported.add(stmt.declaration.id.name)
+    }
+  }
+  return exported
+}
+
+/**
+ * Remove declarations of shared bindings from the AST.
+ * Handles both plain and exported declarations, including destructured patterns.
+ * Removes the entire statement if all bindings in it are shared.
+ */
+function removeSharedDeclarations(ast: t.File, sharedBindings: Set<string>) {
+  ast.program.body = ast.program.body.filter((stmt) => {
+    const decl =
+      t.isExportNamedDeclaration(stmt) && stmt.declaration
+        ? stmt.declaration
+        : stmt
+
+    if (t.isVariableDeclaration(decl)) {
+      // Filter out declarators where all bound names are shared
+      decl.declarations = decl.declarations.filter((declarator) => {
+        const names = collectIdentifiersFromPattern(declarator.id)
+        return !names.every((n) => sharedBindings.has(n))
+      })
+      // If no declarators remain, remove the entire statement
+      if (decl.declarations.length === 0) return false
+    } else if (t.isFunctionDeclaration(decl) && decl.id) {
+      if (sharedBindings.has(decl.id.name)) return false
+    } else if (t.isClassDeclaration(decl) && decl.id) {
+      if (sharedBindings.has(decl.id.name)) return false
+    }
+
+    return true
+  })
+}
+
 export function compileCodeSplitReferenceRoute(
   opts: ParseAstOptions & {
     codeSplitGroupings: CodeSplitGroupings
@@ -112,6 +641,7 @@ export function compileCodeSplitReferenceRoute(
     filename: string
     id: string
     addHmr?: boolean
+    sharedBindings?: Set<string>
   },
 ): GeneratorResult | null {
   const ast = parseAst(opts)
@@ -135,6 +665,7 @@ export function compileCodeSplitReferenceRoute(
 
   let modified = false as boolean
   let hmrAdded = false as boolean
+  let sharedExportedNames: Set<string> | undefined
   babel.traverse(ast, {
     Program: {
       enter(programPath) {
@@ -424,6 +955,56 @@ export function compileCodeSplitReferenceRoute(
             },
           })
         }
+
+        // Handle shared bindings inside the Program visitor so we have
+        // access to programPath for cheap refIdents registration.
+        if (opts.sharedBindings && opts.sharedBindings.size > 0) {
+          sharedExportedNames = findExportedSharedBindings(
+            ast,
+            opts.sharedBindings,
+          )
+          removeSharedDeclarations(ast, opts.sharedBindings)
+
+          const sharedModuleUrl = addSharedSearchParamToFilename(opts.filename)
+
+          const sharedImportSpecifiers = [...opts.sharedBindings].map((name) =>
+            t.importSpecifier(t.identifier(name), t.identifier(name)),
+          )
+          const [sharedImportPath] = programPath.unshiftContainer(
+            'body',
+            t.importDeclaration(
+              sharedImportSpecifiers,
+              t.stringLiteral(sharedModuleUrl),
+            ),
+          )
+
+          // Register import specifier locals in refIdents so DCE can remove unused ones
+          sharedImportPath.traverse({
+            Identifier(identPath) {
+              if (
+                identPath.parentPath.isImportSpecifier() &&
+                identPath.key === 'local'
+              ) {
+                refIdents.add(identPath)
+              }
+            },
+          })
+
+          // Re-export user-exported shared bindings from the shared module
+          if (sharedExportedNames.size > 0) {
+            const reExportSpecifiers = [...sharedExportedNames].map((name) =>
+              t.exportSpecifier(t.identifier(name), t.identifier(name)),
+            )
+            programPath.pushContainer(
+              'body',
+              t.exportNamedDeclaration(
+                null,
+                reExportSpecifiers,
+                t.stringLiteral(sharedModuleUrl),
+              ),
+            )
+          }
+        }
       },
     },
   })
@@ -465,11 +1046,18 @@ export function compileCodeSplitVirtualRoute(
   opts: ParseAstOptions & {
     splitTargets: Array<SplitRouteIdentNodes>
     filename: string
+    sharedBindings?: Set<string>
   },
 ): GeneratorResult {
   const ast = parseAst(opts)
   const refIdents = findReferencedIdentifiers(ast)
 
+  // Remove shared declarations BEFORE babel.traverse so the scope never sees
+  // conflicting bindings (avoids checkBlockScopedCollisions crash in DCE)
+  if (opts.sharedBindings && opts.sharedBindings.size > 0) {
+    removeSharedDeclarations(ast, opts.sharedBindings)
+  }
+
   const intendedSplitNodes = new Set(opts.splitTargets)
 
   const knownExportedIdents = new Set<string>()
@@ -583,6 +1171,14 @@ export function compileCodeSplitVirtualRoute(
           let splitNode = splitKey.node
           const splitMeta = { ...splitKey.meta, shouldRemoveNode: true }
 
+          // Track the original identifier name before resolving through bindings,
+          // needed for destructured patterns where the binding resolves to the
+          // entire VariableDeclarator (ObjectPattern) rather than the specific binding
+          let originalIdentName: string | undefined
+          if (t.isIdentifier(splitNode)) {
+            originalIdentName = splitNode.name
+          }
+
           while (t.isIdentifier(splitNode)) {
             const binding = programPath.scope.getBinding(splitNode.name)
             splitNode = binding?.path.node
@@ -630,6 +1226,13 @@ export function compileCodeSplitVirtualRoute(
               if (t.isIdentifier(splitNode.id)) {
                 splitMeta.localExporterIdent = splitNode.id.name
                 splitMeta.shouldRemoveNode = false
+              } else if (t.isObjectPattern(splitNode.id)) {
+                // Destructured binding like `const { component: MyComp } = createBits()`
+                // Use the original identifier name that was tracked before resolving
+                if (originalIdentName) {
+                  splitMeta.localExporterIdent = originalIdentName
+                }
+                splitMeta.shouldRemoveNode = false
               } else {
                 throw new Error(
                   `Unexpected splitNode type ☝️: ${splitNode.type}`,
@@ -733,13 +1336,48 @@ export function compileCodeSplitVirtualRoute(
 
             if (path.node.declaration) {
               if (t.isVariableDeclaration(path.node.declaration)) {
+                const specifiers = path.node.declaration.declarations.flatMap(
+                  (decl) => {
+                    if (t.isIdentifier(decl.id)) {
+                      return [
+                        t.importSpecifier(
+                          t.identifier(decl.id.name),
+                          t.identifier(decl.id.name),
+                        ),
+                      ]
+                    }
+
+                    if (t.isObjectPattern(decl.id)) {
+                      return collectIdentifiersFromPattern(decl.id).map(
+                        (name) =>
+                          t.importSpecifier(
+                            t.identifier(name),
+                            t.identifier(name),
+                          ),
+                      )
+                    }
+
+                    if (t.isArrayPattern(decl.id)) {
+                      return collectIdentifiersFromPattern(decl.id).map(
+                        (name) =>
+                          t.importSpecifier(
+                            t.identifier(name),
+                            t.identifier(name),
+                          ),
+                      )
+                    }
+
+                    return []
+                  },
+                )
+
+                if (specifiers.length === 0) {
+                  path.remove()
+                  return
+                }
+
                 const importDecl = t.importDeclaration(
-                  path.node.declaration.declarations.map((decl) =>
-                    t.importSpecifier(
-                      t.identifier((decl.id as any).name),
-                      t.identifier((decl.id as any).name),
-                    ),
-                  ),
+                  specifiers,
                   t.stringLiteral(
                     removeSplitSearchParamFromFilename(opts.filename),
                   ),
@@ -764,12 +1402,188 @@ export function compileCodeSplitVirtualRoute(
             }
           },
         })
+
+        // Add shared bindings import, registering specifiers in refIdents
+        // so DCE can remove unused ones (same pattern as import replacements above).
+        if (opts.sharedBindings && opts.sharedBindings.size > 0) {
+          const sharedImportSpecifiers = [...opts.sharedBindings].map((name) =>
+            t.importSpecifier(t.identifier(name), t.identifier(name)),
+          )
+          const sharedModuleUrl = addSharedSearchParamToFilename(
+            removeSplitSearchParamFromFilename(opts.filename),
+          )
+          const [sharedImportPath] = programPath.unshiftContainer(
+            'body',
+            t.importDeclaration(
+              sharedImportSpecifiers,
+              t.stringLiteral(sharedModuleUrl),
+            ),
+          )
+
+          sharedImportPath.traverse({
+            Identifier(identPath) {
+              if (
+                identPath.parentPath.isImportSpecifier() &&
+                identPath.key === 'local'
+              ) {
+                refIdents.add(identPath)
+              }
+            },
+          })
+        }
       },
     },
   })
 
   deadCodeElimination(ast, refIdents)
 
+  // Strip top-level expression statements that reference no locally-bound names.
+  // DCE only removes unused declarations; bare side-effect statements like
+  // `console.log(...)` survive even when the virtual file has no exports.
+  {
+    const locallyBound = new Set<string>()
+    for (const stmt of ast.program.body) {
+      collectLocalBindingsFromStatement(stmt, locallyBound)
+    }
+    ast.program.body = ast.program.body.filter((stmt) => {
+      if (!t.isExpressionStatement(stmt)) return true
+      const refs = collectIdentifiersFromNode(stmt)
+      // Keep if it references at least one locally-bound identifier
+      return [...refs].some((name) => locallyBound.has(name))
+    })
+  }
+
+  // If the body is empty after DCE, strip directive prologues too.
+  // A file containing only `'use client'` with no real code is useless.
+  if (ast.program.body.length === 0) {
+    ast.program.directives = []
+  }
+
+  return generateFromAst(ast, {
+    sourceMaps: true,
+    sourceFileName: opts.filename,
+    filename: opts.filename,
+  })
+}
+
+/**
+ * Compile the shared virtual module (`?tsr-shared=1`).
+ * Keeps only shared binding declarations, their transitive dependencies,
+ * and imports they need. Exports all shared bindings.
+ */
+export function compileCodeSplitSharedRoute(
+  opts: ParseAstOptions & {
+    sharedBindings: Set<string>
+    filename: string
+  },
+): GeneratorResult {
+  const ast = parseAst(opts)
+  const refIdents = findReferencedIdentifiers(ast)
+
+  // Collect all names that need to stay: shared bindings + their transitive deps
+  const localBindings = new Set<string>()
+  for (const node of ast.program.body) {
+    collectLocalBindingsFromStatement(node, localBindings)
+  }
+
+  // Route must never be extracted into the shared module.
+  // Excluding it from the dep graph prevents expandTransitively from
+  // pulling it in as a transitive dependency of a shared binding.
+  localBindings.delete('Route')
+
+  const declMap = buildDeclarationMap(ast)
+  const depGraph = buildDependencyGraph(declMap, localBindings)
+
+  // Start with shared bindings and expand transitively
+  const keepBindings = new Set(opts.sharedBindings)
+  keepBindings.delete('Route')
+  expandTransitively(keepBindings, depGraph)
+
+  // Remove all statements except:
+  // - Import declarations (needed for deps; DCE will clean unused ones)
+  // - Declarations of bindings in keepBindings
+  ast.program.body = ast.program.body.filter((stmt) => {
+    // Always keep imports — DCE will remove unused ones
+    if (t.isImportDeclaration(stmt)) return true
+
+    const decl =
+      t.isExportNamedDeclaration(stmt) && stmt.declaration
+        ? stmt.declaration
+        : stmt
+
+    if (t.isVariableDeclaration(decl)) {
+      // Keep declarators where at least one binding is in keepBindings
+      decl.declarations = decl.declarations.filter((declarator) => {
+        const names = collectIdentifiersFromPattern(declarator.id)
+        return names.some((n) => keepBindings.has(n))
+      })
+      if (decl.declarations.length === 0) return false
+
+      // Strip the `export` wrapper — shared module controls its own exports
+      if (t.isExportNamedDeclaration(stmt) && stmt.declaration) {
+        return true // keep for now, we'll convert below
+      }
+      return true
+    } else if (t.isFunctionDeclaration(decl) && decl.id) {
+      return keepBindings.has(decl.id.name)
+    } else if (t.isClassDeclaration(decl) && decl.id) {
+      return keepBindings.has(decl.id.name)
+    }
+
+    // Remove everything else (expression statements, other exports, etc.)
+    return false
+  })
+
+  // Convert `export const/function/class` to plain declarations
+  // (we'll add our own export statement at the end)
+  ast.program.body = ast.program.body.map((stmt) => {
+    if (t.isExportNamedDeclaration(stmt) && stmt.declaration) {
+      return stmt.declaration
+    }
+    return stmt
+  })
+
+  // Export all shared bindings (sorted for deterministic output)
+  const exportNames = [...opts.sharedBindings].sort((a, b) =>
+    a.localeCompare(b),
+  )
+  const exportSpecifiers = exportNames.map((name) =>
+    t.exportSpecifier(t.identifier(name), t.identifier(name)),
+  )
+  if (exportSpecifiers.length > 0) {
+    const exportDecl = t.exportNamedDeclaration(null, exportSpecifiers)
+    ast.program.body.push(exportDecl)
+
+    // Register export specifier locals in refIdents so DCE doesn't treat
+    // the exported bindings as unreferenced.
+    babel.traverse(ast, {
+      Program(programPath) {
+        const bodyPaths = programPath.get('body')
+        const last = bodyPaths[bodyPaths.length - 1]
+        if (last && last.isExportNamedDeclaration()) {
+          last.traverse({
+            Identifier(identPath) {
+              if (
+                identPath.parentPath.isExportSpecifier() &&
+                identPath.key === 'local'
+              ) {
+                refIdents.add(identPath)
+              }
+            },
+          })
+        }
+        programPath.stop()
+      },
+    })
+  }
+
+  deadCodeElimination(ast, refIdents)
+
+  // If the body is empty after DCE, strip directive prologues too.
+  if (ast.program.body.length === 0) {
+    ast.program.directives = []
+  }
+
   return generateFromAst(ast, {
     sourceMaps: true,
     sourceFileName: opts.filename,
@@ -921,6 +1735,50 @@ function getImportSpecifierAndPathFromLocalName(
   return { specifier, path }
 }
 
+/**
+ * Recursively collects all identifier names from a destructuring pattern
+ * (ObjectPattern, ArrayPattern, AssignmentPattern, RestElement).
+ */
+function collectIdentifiersFromPattern(
+  node: t.LVal | t.Node | null | undefined,
+): Array<string> {
+  if (!node) {
+    return []
+  }
+
+  if (t.isIdentifier(node)) {
+    return [node.name]
+  }
+
+  if (t.isAssignmentPattern(node)) {
+    return collectIdentifiersFromPattern(node.left)
+  }
+
+  if (t.isRestElement(node)) {
+    return collectIdentifiersFromPattern(node.argument)
+  }
+
+  if (t.isObjectPattern(node)) {
+    return node.properties.flatMap((prop) => {
+      if (t.isObjectProperty(prop)) {
+        return collectIdentifiersFromPattern(prop.value as t.LVal)
+      }
+      if (t.isRestElement(prop)) {
+        return collectIdentifiersFromPattern(prop.argument)
+      }
+      return []
+    })
+  }
+
+  if (t.isArrayPattern(node)) {
+    return node.elements.flatMap((element) =>
+      collectIdentifiersFromPattern(element),
+    )
+  }
+
+  return []
+}
+
 // Reusable function to get literal value or resolve variable to literal
 function resolveIdentifier(path: any, node: any): t.Node | undefined {
   if (t.isIdentifier(node)) {
@@ -945,6 +1803,41 @@ function resolveIdentifier(path: any, node: any): t.Node | undefined {
 function removeIdentifierLiteral(path: babel.NodePath, node: t.Identifier) {
   const binding = path.scope.getBinding(node.name)
   if (binding) {
+    // If the binding is a destructured property from an ObjectPattern,
+    // only remove that property instead of the entire declaration
+    if (
+      t.isVariableDeclarator(binding.path.node) &&
+      t.isObjectPattern(binding.path.node.id)
+    ) {
+      const objectPattern = binding.path.node.id
+      objectPattern.properties = objectPattern.properties.filter((prop) => {
+        if (!t.isObjectProperty(prop)) {
+          return true
+        }
+
+        if (t.isIdentifier(prop.value) && prop.value.name === node.name) {
+          return false
+        }
+
+        if (
+          t.isAssignmentPattern(prop.value) &&
+          t.isIdentifier(prop.value.left) &&
+          prop.value.left.name === node.name
+        ) {
+          return false
+        }
+
+        return true
+      })
+
+      // If no properties remain, remove the entire declaration
+      if (objectPattern.properties.length === 0) {
+        binding.path.remove()
+      }
+
+      return
+    }
+
     binding.path.remove()
   }
 }
@@ -963,6 +1856,15 @@ function hasExport(ast: t.File, node: t.Identifier): boolean {
                 if (decl.id.name === node.name) {
                   found = true
                 }
+              } else if (
+                t.isObjectPattern(decl.id) ||
+                t.isArrayPattern(decl.id)
+              ) {
+                // Handle destructured exports like `export const { a, b } = fn()`
+                const names = collectIdentifiersFromPattern(decl.id)
+                if (names.includes(node.name)) {
+                  found = true
+                }
               }
             }
           })
@@ -1020,6 +1922,16 @@ function removeExports(ast: t.File, node: t.Identifier): boolean {
                   path.remove()
                   removed = true
                 }
+              } else if (
+                t.isObjectPattern(decl.id) ||
+                t.isArrayPattern(decl.id)
+              ) {
+                // Handle destructured exports like `export const { a, b } = fn()`
+                const names = collectIdentifiersFromPattern(decl.id)
+                if (names.includes(node.name)) {
+                  path.remove()
+                  removed = true
+                }
               }
             }
           })
diff --git a/packages/router-plugin/src/core/constants.ts b/packages/router-plugin/src/core/constants.ts
index b4d4bb940f..5659065d49 100644
--- a/packages/router-plugin/src/core/constants.ts
+++ b/packages/router-plugin/src/core/constants.ts
@@ -1,4 +1,5 @@
 export const tsrSplit = 'tsr-split'
+export const tsrShared = 'tsr-shared'
 
 export const splitRouteIdentNodes = [
   'loader',
diff --git a/packages/router-plugin/src/core/route-hmr-statement.ts b/packages/router-plugin/src/core/route-hmr-statement.ts
index b910c1340b..e5ab998789 100644
--- a/packages/router-plugin/src/core/route-hmr-statement.ts
+++ b/packages/router-plugin/src/core/route-hmr-statement.ts
@@ -29,9 +29,12 @@ function handleRouteUpdate(
   // TODO: how to rebuild the tree if we add a new route?
   walkReplaceSegmentTree(newRoute, router.processedTree.segmentTree)
   const filter = (m: AnyRouteMatch) => m.routeId === oldRoute.id
+  const hasPendingRouteMatch =
+    router.state.status === 'pending' &&
+    router.matchRoutes(router.latestLocation).some(filter)
   if (
     router.state.matches.find(filter) ||
-    router.state.pendingMatches?.find(filter)
+    hasPendingRouteMatch
   ) {
     router.invalidate({ filter })
   }
diff --git a/packages/router-plugin/src/core/router-code-splitter-plugin.ts b/packages/router-plugin/src/core/router-code-splitter-plugin.ts
index 2dba5474a7..c0d8bf357e 100644
--- a/packages/router-plugin/src/core/router-code-splitter-plugin.ts
+++ b/packages/router-plugin/src/core/router-code-splitter-plugin.ts
@@ -8,12 +8,15 @@ import { logDiff } from '@tanstack/router-utils'
 import { getConfig, splitGroupingsSchema } from './config'
 import {
   compileCodeSplitReferenceRoute,
+  compileCodeSplitSharedRoute,
   compileCodeSplitVirtualRoute,
+  computeSharedBindings,
   detectCodeSplitGroupingsFromRoute,
 } from './code-splitter/compilers'
 import {
   defaultCodeSplitGroupings,
   splitRouteIdentNodes,
+  tsrShared,
   tsrSplit,
 } from './constants'
 import { decodeIdentifier } from './code-splitter/path-ids'
@@ -88,6 +91,10 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
   }
   const isProduction = process.env.NODE_ENV === 'production'
 
+  // Map from normalized route file path → set of shared binding names.
+  // Populated by the reference compiler, consumed by virtual and shared compilers.
+  const sharedBindingsMap = new Map<string, Set<string>>()
+
   const getGlobalCodeSplitGroupings = () => {
     return (
       userConfig.codeSplittingOptions?.defaultBehavior ||
@@ -138,6 +145,17 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
     const splitGroupings: CodeSplitGroupings =
       fromCode.groupings || pluginSplitBehavior || getGlobalCodeSplitGroupings()
 
+    // Compute shared bindings before compiling the reference route
+    const sharedBindings = computeSharedBindings({
+      code,
+      codeSplitGroupings: splitGroupings,
+    })
+    if (sharedBindings.size > 0) {
+      sharedBindingsMap.set(id, sharedBindings)
+    } else {
+      sharedBindingsMap.delete(id)
+    }
+
     const compiledReferenceRoute = compileCodeSplitReferenceRoute({
       code,
       codeSplitGroupings: splitGroupings,
@@ -149,6 +167,7 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
         : undefined,
       addHmr:
         (userConfig.codeSplittingOptions?.addHmr ?? true) && !isProduction,
+      sharedBindings: sharedBindings.size > 0 ? sharedBindings : undefined,
     })
 
     if (compiledReferenceRoute === null) {
@@ -189,10 +208,14 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
       splitRouteIdentNodes.includes(p as any),
     ) as Array<SplitRouteIdentNodes>
 
+    const baseId = id.split('?')[0]!
+    const resolvedSharedBindings = sharedBindingsMap.get(baseId)
+
     const result = compileCodeSplitVirtualRoute({
       code,
       filename: id,
       splitTargets: grouping,
+      sharedBindings: resolvedSharedBindings,
     })
 
     if (debug) {
@@ -216,7 +239,7 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
       transform: {
         filter: {
           id: {
-            exclude: tsrSplit,
+            exclude: [tsrSplit, tsrShared],
             // this is necessary for webpack / rspack to avoid matching .html files
             include: /\.(m|c)?(j|t)sx?$/,
           },
@@ -325,6 +348,60 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
           return handleCompilingVirtualFile(code, normalizedId)
         },
       },
+
+      vite: {
+        applyToEnvironment(environment) {
+          if (userConfig.plugin?.vite?.environmentName) {
+            return userConfig.plugin.vite.environmentName === environment.name
+          }
+          return true
+        },
+      },
+    },
+    {
+      name: 'tanstack-router:code-splitter:compile-shared-file',
+      enforce: 'pre',
+
+      transform: {
+        filter: {
+          id: /tsr-shared/,
+        },
+        handler(code, id) {
+          const url = pathToFileURL(id)
+          url.searchParams.delete('v')
+          const normalizedId = normalizePath(fileURLToPath(url))
+          const [baseId] = normalizedId.split('?')
+
+          if (!baseId) return null
+
+          const sharedBindings = sharedBindingsMap.get(baseId)
+          if (!sharedBindings || sharedBindings.size === 0) return null
+
+          if (debug) console.info('Compiling Shared Module: ', id)
+
+          const result = compileCodeSplitSharedRoute({
+            code,
+            sharedBindings,
+            filename: normalizedId,
+          })
+
+          if (debug) {
+            logDiff(code, result.code)
+            console.log('Output:\n', result.code + '\n\n')
+          }
+
+          return result
+        },
+      },
+
+      vite: {
+        applyToEnvironment(environment) {
+          if (userConfig.plugin?.vite?.environmentName) {
+            return userConfig.plugin.vite.environmentName === environment.name
+          }
+          return true
+        },
+      },
     },
   ]
 }
diff --git a/packages/router-plugin/tests/add-hmr/snapshots/react/arrow-function@true.tsx b/packages/router-plugin/tests/add-hmr/snapshots/react/arrow-function@true.tsx
index 5a3588a7dc..4b8538d87e 100644
--- a/packages/router-plugin/tests/add-hmr/snapshots/react/arrow-function@true.tsx
+++ b/packages/router-plugin/tests/add-hmr/snapshots/react/arrow-function@true.tsx
@@ -26,7 +26,8 @@ if (import.meta.hot) {
         router.resolvePathCache.clear();
         walkReplaceSegmentTree(newRoute, router.processedTree.segmentTree);
         const filter = m => m.routeId === oldRoute.id;
-        if (router.state.matches.find(filter) || router.state.pendingMatches?.find(filter)) {
+        const hasPendingRouteMatch = router.state.status === 'pending' && router.matchRoutes(router.latestLocation).some(filter);
+        if (router.state.matches.find(filter) || hasPendingRouteMatch) {
           router.invalidate({
             filter
           });
@@ -44,4 +45,4 @@ if (import.meta.hot) {
       })(Route, newModule.Route);
     }
   });
-}
\ No newline at end of file
+}
diff --git a/packages/router-plugin/tests/add-hmr/snapshots/react/function-declaration@true.tsx b/packages/router-plugin/tests/add-hmr/snapshots/react/function-declaration@true.tsx
index bee310532f..f352e1e1b8 100644
--- a/packages/router-plugin/tests/add-hmr/snapshots/react/function-declaration@true.tsx
+++ b/packages/router-plugin/tests/add-hmr/snapshots/react/function-declaration@true.tsx
@@ -26,7 +26,8 @@ if (import.meta.hot) {
         router.resolvePathCache.clear();
         walkReplaceSegmentTree(newRoute, router.processedTree.segmentTree);
         const filter = m => m.routeId === oldRoute.id;
-        if (router.state.matches.find(filter) || router.state.pendingMatches?.find(filter)) {
+        const hasPendingRouteMatch = router.state.status === 'pending' && router.matchRoutes(router.latestLocation).some(filter);
+        if (router.state.matches.find(filter) || hasPendingRouteMatch) {
           router.invalidate({
             filter
           });
@@ -44,4 +45,4 @@ if (import.meta.hot) {
       })(Route, newModule.Route);
     }
   });
-}
\ No newline at end of file
+}
diff --git a/packages/router-plugin/tests/add-hmr/snapshots/solid/arrow-function@true.tsx b/packages/router-plugin/tests/add-hmr/snapshots/solid/arrow-function@true.tsx
index 3ad31b8eb2..c3ccbca0a2 100644
--- a/packages/router-plugin/tests/add-hmr/snapshots/solid/arrow-function@true.tsx
+++ b/packages/router-plugin/tests/add-hmr/snapshots/solid/arrow-function@true.tsx
@@ -25,7 +25,8 @@ if (import.meta.hot) {
         router.resolvePathCache.clear();
         walkReplaceSegmentTree(newRoute, router.processedTree.segmentTree);
         const filter = m => m.routeId === oldRoute.id;
-        if (router.state.matches.find(filter) || router.state.pendingMatches?.find(filter)) {
+        const hasPendingRouteMatch = router.state.status === 'pending' && router.matchRoutes(router.latestLocation).some(filter);
+        if (router.state.matches.find(filter) || hasPendingRouteMatch) {
           router.invalidate({
             filter
           });
@@ -43,4 +44,4 @@ if (import.meta.hot) {
       })(Route, newModule.Route);
     }
   });
-}
\ No newline at end of file
+}
diff --git a/packages/router-plugin/tests/code-splitter.test.ts b/packages/router-plugin/tests/code-splitter.test.ts
index 6edf37b5f1..5a68f9453f 100644
--- a/packages/router-plugin/tests/code-splitter.test.ts
+++ b/packages/router-plugin/tests/code-splitter.test.ts
@@ -1,10 +1,22 @@
 import { readFile, readdir } from 'node:fs/promises'
 import path from 'node:path'
 import { describe, expect, it } from 'vitest'
+import { parseAst } from '@tanstack/router-utils'
 
 import {
+  buildDeclarationMap,
+  buildDependencyGraph,
+  collectIdentifiersFromNode,
+  collectLocalBindingsFromStatement,
+  collectModuleLevelRefsFromNode,
   compileCodeSplitReferenceRoute,
+  compileCodeSplitSharedRoute,
   compileCodeSplitVirtualRoute,
+  computeSharedBindings,
+  expandDestructuredDeclarations,
+  expandSharedDestructuredDeclarators,
+  expandTransitively,
+  removeBindingsDependingOnRoute,
 } from '../src/core/code-splitter/compilers'
 import { createIdentifier } from '../src/core/code-splitter/path-ids'
 import { defaultCodeSplitGroupings } from '../src/core/constants'
@@ -58,6 +70,11 @@ describe('code-splitter works', () => {
             const file = await readFile(path.join(dirs.files, filename))
             const code = file.toString()
 
+            const sharedBindings = computeSharedBindings({
+              code,
+              codeSplitGroupings: grouping,
+            })
+
             const compileResult = compileCodeSplitReferenceRoute({
               code,
               filename,
@@ -65,6 +82,8 @@ describe('code-splitter works', () => {
               addHmr: false,
               codeSplitGroupings: grouping,
               targetFramework: framework,
+              sharedBindings:
+                sharedBindings.size > 0 ? sharedBindings : undefined,
             })
 
             await expect(compileResult?.code || code).toMatchFileSnapshot(
@@ -79,6 +98,11 @@ describe('code-splitter works', () => {
             const file = await readFile(path.join(dirs.files, filename))
             const code = file.toString()
 
+            const sharedBindings = computeSharedBindings({
+              code,
+              codeSplitGroupings: grouping,
+            })
+
             for (const targets of grouping) {
               const ident = createIdentifier(targets)
 
@@ -86,6 +110,8 @@ describe('code-splitter works', () => {
                 code,
                 filename: `${filename}?${ident}`,
                 splitTargets: targets,
+                sharedBindings:
+                  sharedBindings.size > 0 ? sharedBindings : undefined,
               })
 
               const snapshotFilename = path.join(
@@ -99,6 +125,931 @@ describe('code-splitter works', () => {
             }
           },
         )
+
+        it.each(filenames)(
+          `should compile "shared" for "%s"`,
+          async (filename) => {
+            const file = await readFile(path.join(dirs.files, filename))
+            const code = file.toString()
+
+            const sharedBindings = computeSharedBindings({
+              code,
+              codeSplitGroupings: grouping,
+            })
+
+            const snapshotFilename = path.join(
+              dirs.snapshots,
+              groupName,
+              `${filename.replace('.tsx', '')}@shared.tsx`,
+            )
+
+            if (sharedBindings.size === 0) {
+              // No shared module — snapshot should be empty string
+              await expect('').toMatchFileSnapshot(snapshotFilename)
+              return
+            }
+
+            const sharedResult = compileCodeSplitSharedRoute({
+              code,
+              sharedBindings,
+              filename: `${filename}?tsr-shared=1`,
+            })
+
+            await expect(sharedResult.code).toMatchFileSnapshot(
+              snapshotFilename,
+            )
+          },
+        )
+      },
+    )
+  })
+})
+
+describe('computeSharedBindings fast paths', () => {
+  it('returns empty when only one split group is present (default groupings)', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const shared = 42
+export const Route = createFileRoute('/')({
+  component: () => shared,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultCodeSplitGroupings,
+    })
+    expect(result.size).toBe(0)
+  })
+
+  it('returns empty when all split props are in the same group', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const shared = 42
+export const Route = createFileRoute('/')({
+  component: () => shared,
+  loader: () => shared,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: [['component', 'loader']],
+    })
+    expect(result.size).toBe(0)
+  })
+
+  it('returns empty when all route option values are undefined', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+export const Route = createFileRoute('/')({
+  component: undefined,
+  errorComponent: undefined,
+  notFoundComponent: undefined,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultCodeSplitGroupings,
+    })
+    expect(result.size).toBe(0)
+  })
+
+  it('returns empty when no local bindings exist (only imports + Route)', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+export const Route = createFileRoute('/')({
+  component: () => <div>hello</div>,
+  errorComponent: () => <div>error</div>,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultCodeSplitGroupings,
+    })
+    expect(result.size).toBe(0)
+  })
+
+  it('does not fast-path when there is a non-split and a split group', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const shared = 42
+export const Route = createFileRoute('/')({
+  component: () => shared,
+  beforeLoad: () => shared,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultCodeSplitGroupings,
+    })
+    expect(result).toContain('shared')
+  })
+})
+
+// ============================================================================
+// LAYER 1: Algebraic Property Tests on Helper Functions
+//
+// These test that the pure graph/set functions obey mathematical contracts
+// independent of any particular route file.
+// ============================================================================
+
+describe('expandTransitively', () => {
+  it('is idempotent — running twice yields the same result as once', () => {
+    // Graph: a -> b -> c, d -> b
+    const depGraph = new Map<string, Set<string>>([
+      ['a', new Set(['b'])],
+      ['b', new Set(['c'])],
+      ['c', new Set()],
+      ['d', new Set(['b'])],
+    ])
+
+    const first = new Set(['a'])
+    expandTransitively(first, depGraph)
+    const afterFirst = new Set(first)
+
+    expandTransitively(first, depGraph)
+    expect(first).toEqual(afterFirst)
+  })
+
+  it('is monotone — larger initial set produces equal or larger result', () => {
+    const depGraph = new Map<string, Set<string>>([
+      ['a', new Set(['c'])],
+      ['b', new Set(['d'])],
+      ['c', new Set()],
+      ['d', new Set()],
+    ])
+
+    const small = new Set(['a'])
+    expandTransitively(small, depGraph)
+
+    const large = new Set(['a', 'b'])
+    expandTransitively(large, depGraph)
+
+    for (const item of small) {
+      expect(large.has(item)).toBe(true)
+    }
+  })
+
+  it('handles cycles without infinite loops', () => {
+    const depGraph = new Map<string, Set<string>>([
+      ['a', new Set(['b'])],
+      ['b', new Set(['c'])],
+      ['c', new Set(['a'])],
+    ])
+
+    const set = new Set(['a'])
+    expandTransitively(set, depGraph)
+    expect(set).toEqual(new Set(['a', 'b', 'c']))
+  })
+
+  it('is a no-op when there are no dependencies', () => {
+    const depGraph = new Map<string, Set<string>>([
+      ['a', new Set()],
+      ['b', new Set()],
+    ])
+
+    const set = new Set(['a'])
+    expandTransitively(set, depGraph)
+    expect(set).toEqual(new Set(['a']))
+  })
+
+  it('handles missing entries in the graph gracefully', () => {
+    const depGraph = new Map<string, Set<string>>()
+    const set = new Set(['unknown'])
+    expandTransitively(set, depGraph)
+    expect(set).toEqual(new Set(['unknown']))
+  })
+})
+
+describe('buildDependencyGraph', () => {
+  it('result keys are a subset of localBindings', () => {
+    const code = `
+const a = 1
+const b = a + 1
+const c = 2
+`
+    const ast = parseAst({ code })
+    const declMap = buildDeclarationMap(ast)
+    const localBindings = new Set(['a', 'b', 'c'])
+    const graph = buildDependencyGraph(declMap, localBindings)
+
+    for (const key of graph.keys()) {
+      expect(localBindings.has(key)).toBe(true)
+    }
+  })
+
+  it('dependency values are also subsets of localBindings', () => {
+    const code = `
+import { external } from 'somewhere'
+const a = external
+const b = a + 1
+`
+    const ast = parseAst({ code })
+    const declMap = buildDeclarationMap(ast)
+    const localBindings = new Set(['a', 'b'])
+    const graph = buildDependencyGraph(declMap, localBindings)
+
+    for (const deps of graph.values()) {
+      for (const dep of deps) {
+        expect(localBindings.has(dep)).toBe(true)
+      }
+    }
+  })
+
+  it('captures direct references correctly', () => {
+    const code = `
+const x = 10
+const y = x + 1
+`
+    const ast = parseAst({ code })
+    const declMap = buildDeclarationMap(ast)
+    const localBindings = new Set(['x', 'y'])
+    const graph = buildDependencyGraph(declMap, localBindings)
+
+    expect(graph.get('y')).toEqual(new Set(['x']))
+    expect(graph.get('x')?.size ?? 0).toBe(0)
+  })
+})
+
+describe('removeBindingsDependingOnRoute', () => {
+  it('removes bindings that directly reference Route', () => {
+    const depGraph = new Map<string, Set<string>>([
+      ['helper', new Set(['Route'])],
+      ['standalone', new Set()],
+      ['Route', new Set()],
+    ])
+
+    const shared = new Set(['helper', 'standalone'])
+    removeBindingsDependingOnRoute(shared, depGraph)
+
+    expect(shared.has('helper')).toBe(false)
+    expect(shared.has('standalone')).toBe(true)
+  })
+
+  it('removes bindings that transitively reference Route', () => {
+    const depGraph = new Map<string, Set<string>>([
+      ['a', new Set(['b'])],
+      ['b', new Set(['Route'])],
+      ['c', new Set()],
+      ['Route', new Set()],
+    ])
+
+    const shared = new Set(['a', 'c'])
+    removeBindingsDependingOnRoute(shared, depGraph)
+
+    expect(shared.has('a')).toBe(false)
+    expect(shared.has('c')).toBe(true)
+  })
+
+  it('is a no-op when nothing depends on Route', () => {
+    const depGraph = new Map<string, Set<string>>([
+      ['a', new Set(['b'])],
+      ['b', new Set()],
+      ['Route', new Set()],
+    ])
+
+    const shared = new Set(['a', 'b'])
+    const before = new Set(shared)
+    removeBindingsDependingOnRoute(shared, depGraph)
+
+    expect(shared).toEqual(before)
+  })
+})
+
+describe('expandDestructuredDeclarations', () => {
+  it('is idempotent', () => {
+    const code = `const { a, b } = fn()`
+    const ast = parseAst({ code })
+
+    const shared = new Set(['a'])
+    expandDestructuredDeclarations(ast, shared)
+    const afterFirst = new Set(shared)
+
+    expandDestructuredDeclarations(ast, shared)
+    expect(shared).toEqual(afterFirst)
+  })
+
+  it('pulls all siblings when one destructured binding is shared', () => {
+    const code = `const { a, b, c } = fn()`
+    const ast = parseAst({ code })
+
+    const shared = new Set(['b'])
+    expandDestructuredDeclarations(ast, shared)
+
+    expect(shared).toEqual(new Set(['a', 'b', 'c']))
+  })
+
+  it('does not affect non-destructured declarations', () => {
+    const code = `
+const x = 1
+const y = 2
+`
+    const ast = parseAst({ code })
+
+    const shared = new Set(['x'])
+    expandDestructuredDeclarations(ast, shared)
+
+    expect(shared).toEqual(new Set(['x']))
+  })
+})
+
+describe('collectLocalBindingsFromStatement', () => {
+  it('collects variable declaration names', () => {
+    const code = `const x = 1`
+    const ast = parseAst({ code })
+    const bindings = new Set<string>()
+    collectLocalBindingsFromStatement(ast.program.body[0]!, bindings)
+    expect(bindings).toEqual(new Set(['x']))
+  })
+
+  it('collects function declaration names', () => {
+    const code = `function foo() {}`
+    const ast = parseAst({ code })
+    const bindings = new Set<string>()
+    collectLocalBindingsFromStatement(ast.program.body[0]!, bindings)
+    expect(bindings).toEqual(new Set(['foo']))
+  })
+
+  it('collects class declaration names', () => {
+    const code = `class MyClass {}`
+    const ast = parseAst({ code })
+    const bindings = new Set<string>()
+    collectLocalBindingsFromStatement(ast.program.body[0]!, bindings)
+    expect(bindings).toEqual(new Set(['MyClass']))
+  })
+
+  it('collects exported declaration names', () => {
+    const code = `export const a = 1`
+    const ast = parseAst({ code })
+    const bindings = new Set<string>()
+    collectLocalBindingsFromStatement(ast.program.body[0]!, bindings)
+    expect(bindings).toEqual(new Set(['a']))
+  })
+
+  it('collects destructured binding names', () => {
+    const code = `const { a, b } = obj`
+    const ast = parseAst({ code })
+    const bindings = new Set<string>()
+    collectLocalBindingsFromStatement(ast.program.body[0]!, bindings)
+    expect(bindings).toEqual(new Set(['a', 'b']))
+  })
+})
+
+// ============================================================================
+// LAYER 2: Invariant Tests on computeSharedBindings
+//
+// These verify the core "contracts" of the shared bindings computation:
+// - Route is never extracted
+// - Results are always real local bindings
+// - Destructured cohesion holds
+// - Transitive dependencies are included
+// - Route-dependent bindings are excluded
+// ============================================================================
+
+describe('computeSharedBindings invariants', () => {
+  const defaultGroupings = defaultCodeSplitGroupings
+
+  function getLocalBindings(code: string): Set<string> {
+    const ast = parseAst({ code })
+    const bindings = new Set<string>()
+    for (const stmt of ast.program.body) {
+      collectLocalBindingsFromStatement(stmt, bindings)
+    }
+    bindings.delete('Route')
+    return bindings
+  }
+
+  it('INVARIANT: Route is never in the shared set', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const shared = 42
+export const Route = createFileRoute('/')({
+  component: () => shared,
+  beforeLoad: () => shared,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result.has('Route')).toBe(false)
+  })
+
+  it('INVARIANT: all results are actual local bindings from the source', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+import { external } from 'somewhere'
+const config = { url: external, timeout: 5000 }
+const fetcher = (path) => fetch(config.url + path)
+export const Route = createFileRoute('/')({
+  loader: () => fetcher('/data'),
+  component: () => <div>{config.timeout}</div>,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    const localBindings = getLocalBindings(code)
+
+    for (const name of result) {
+      expect(localBindings.has(name)).toBe(true)
+    }
+  })
+
+  it('INVARIANT: imports are never in the shared set', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+import { helper } from './utils'
+export const Route = createFileRoute('/')({
+  loader: () => helper(),
+  component: () => <div>{helper()}</div>,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result.has('helper')).toBe(false)
+  })
+
+  it('INVARIANT: destructured siblings are either all shared or none shared', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const { a, b, c } = createHelpers()
+export const Route = createFileRoute('/')({
+  loader: () => a,
+  component: () => <div>{b}</div>,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+
+    // If any destructured sibling is shared, all must be
+    const siblings = ['a', 'b', 'c']
+    const sharedSiblings = siblings.filter((s) => result.has(s))
+    if (sharedSiblings.length > 0) {
+      expect(sharedSiblings.length).toBe(siblings.length)
+    }
+  })
+
+  it('INVARIANT: transitive dependencies of shared bindings are also shared', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const BASE = 'https://api.example.com'
+const config = { url: BASE }
+const fetcher = () => fetch(config.url)
+export const Route = createFileRoute('/')({
+  loader: () => fetcher(),
+  component: () => <div>{config.url}</div>,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+
+    // If config is shared (referenced by both loader via fetcher and component directly),
+    // then BASE (which config depends on) should also be shared
+    if (result.has('config')) {
+      expect(result.has('BASE')).toBe(true)
+    }
+  })
+
+  it('INVARIANT: bindings depending on Route are excluded from shared', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const HEADER = 'Page'
+function usePageTitle() {
+  return HEADER + ' - ' + Route.fullPath
+}
+export const Route = createFileRoute('/about')({
+  loader: () => usePageTitle(),
+  component: () => <div>{usePageTitle()}</div>,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+
+    // usePageTitle references Route, so it must NOT be shared
+    expect(result.has('usePageTitle')).toBe(false)
+    // HEADER is only referenced by usePageTitle which depends on Route,
+    // so HEADER should also not be shared (unless it has other references)
+  })
+
+  it('INVARIANT: single-group-only bindings are never shared', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const loaderOnly = () => fetch('/api')
+const componentOnly = () => <span>hi</span>
+const shared = 42
+export const Route = createFileRoute('/')({
+  loader: () => { loaderOnly(); return shared },
+  component: () => <div>{componentOnly()} {shared}</div>,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+
+    // loaderOnly is only used by loader (non-split), should NOT be shared
+    expect(result.has('loaderOnly')).toBe(false)
+    // componentOnly is only used by component (split), should NOT be shared
+    expect(result.has('componentOnly')).toBe(false)
+    // shared IS used by both groups
+    expect(result.has('shared')).toBe(true)
+  })
+
+  it('INVARIANT: empty result for unsplittable routes (createRootRoute)', () => {
+    const code = `
+import { createRootRoute } from '@tanstack/react-router'
+const shared = 42
+export const Route = createRootRoute({
+  component: () => <div>{shared}</div>,
+  beforeLoad: () => shared,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result.size).toBe(0)
+  })
+
+  it('INVARIANT: result is stable across multiple calls with same input', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const shared = { name: 'test' }
+export const Route = createFileRoute('/')({
+  loader: () => shared.name,
+  component: () => <div>{shared.name}</div>,
+})
+`
+    const opts = { code, codeSplitGroupings: defaultGroupings }
+    const result1 = computeSharedBindings(opts)
+    const result2 = computeSharedBindings(opts)
+    const result3 = computeSharedBindings(opts)
+
+    expect(result1).toEqual(result2)
+    expect(result2).toEqual(result3)
+  })
+})
+
+// ============================================================================
+// LAYER 3: Small-Scope Exhaustive Tests
+//
+// Inspired by Alloy's "small scope hypothesis" — most bugs show up in small
+// counterexamples. We exhaustively test all combinations of:
+// - binding declaration types (const, function, class)
+// - route property configurations (loader+component, loader+errorComponent, etc.)
+// - split grouping configurations
+// ============================================================================
+
+describe('small-scope exhaustive: computeSharedBindings', () => {
+  // Helper to generate a route file with specific binding configurations
+  function makeRouteCode(opts: {
+    bindings: Array<{ name: string; kind: 'const' | 'function' | 'class' }>
+    loaderRefs: Array<string>
+    componentRefs: Array<string>
+    errorComponentRefs?: Array<string>
+    beforeLoadRefs?: Array<string>
+  }): string {
+    const bindingDecls = opts.bindings
+      .map((b) => {
+        switch (b.kind) {
+          case 'const':
+            return `const ${b.name} = 42`
+          case 'function':
+            return `function ${b.name}() { return 42 }`
+          case 'class':
+            return `class ${b.name} { value = 42 }`
+        }
+      })
+      .join('\n')
+
+    const loaderBody =
+      opts.loaderRefs.length > 0
+        ? opts.loaderRefs.map((r) => `${r}`).join('; ')
+        : '42'
+
+    const componentBody =
+      opts.componentRefs.length > 0
+        ? opts.componentRefs.map((r) => `{${r}}`).join('')
+        : 'hello'
+
+    const props: Array<string> = [
+      `  loader: () => { return ${loaderBody} }`,
+      `  component: () => <div>${componentBody}</div>`,
+    ]
+
+    if (opts.errorComponentRefs) {
+      const body =
+        opts.errorComponentRefs.length > 0
+          ? opts.errorComponentRefs.map((r) => `{${r}}`).join('')
+          : 'error'
+      props.push(`  errorComponent: () => <div>${body}</div>`)
+    }
+
+    if (opts.beforeLoadRefs) {
+      const body =
+        opts.beforeLoadRefs.length > 0
+          ? opts.beforeLoadRefs.map((r) => `${r}`).join('; ')
+          : '42'
+      props.push(`  beforeLoad: () => { return ${body} }`)
+    }
+
+    return `
+import { createFileRoute } from '@tanstack/react-router'
+${bindingDecls}
+export const Route = createFileRoute('/')({
+${props.join(',\n')}
+})
+`
+  }
+
+  // Exhaustively test 1-binding scenarios with all grouping configs
+  const groupingConfigs: Array<{
+    name: string
+    groupings: CodeSplitGroupings
+  }> = [
+    { name: 'default', groupings: defaultCodeSplitGroupings },
+    {
+      name: 'loader+components-combined',
+      groupings: [
+        ['loader'],
+        [
+          'component',
+          'pendingComponent',
+          'errorComponent',
+          'notFoundComponent',
+        ],
+      ],
+    },
+  ]
+
+  const bindingKinds = ['const', 'function', 'class'] as const
+
+  describe('single binding × all property combinations', () => {
+    // For each binding kind × each grouping × each reference pattern,
+    // verify invariants hold
+    for (const kind of bindingKinds) {
+      for (const { name: groupName, groupings } of groupingConfigs) {
+        // Pattern: binding used only by loader (non-split) → never shared
+        it(`${kind} used only by loader [${groupName}] → not shared`, () => {
+          const code = makeRouteCode({
+            bindings: [{ name: 'x', kind }],
+            loaderRefs: ['x'],
+            componentRefs: [],
+          })
+          const result = computeSharedBindings({
+            code,
+            codeSplitGroupings: groupings,
+          })
+          expect(result.has('x')).toBe(false)
+        })
+
+        // Pattern: binding used only by component (split) → never shared
+        it(`${kind} used only by component [${groupName}] → not shared`, () => {
+          const code = makeRouteCode({
+            bindings: [{ name: 'x', kind }],
+            loaderRefs: [],
+            componentRefs: ['x'],
+          })
+          const result = computeSharedBindings({
+            code,
+            codeSplitGroupings: groupings,
+          })
+          expect(result.has('x')).toBe(false)
+        })
+
+        // Pattern: binding used by both loader AND component → shared
+        it(`${kind} used by loader+component [${groupName}] → shared`, () => {
+          const code = makeRouteCode({
+            bindings: [{ name: 'x', kind }],
+            loaderRefs: ['x'],
+            componentRefs: ['x'],
+          })
+          const result = computeSharedBindings({
+            code,
+            codeSplitGroupings: groupings,
+          })
+          expect(result.has('x')).toBe(true)
+        })
+
+        // Pattern: binding used by component AND beforeLoad (non-split) → shared
+        it(`${kind} used by component+beforeLoad [${groupName}] → shared`, () => {
+          const code = makeRouteCode({
+            bindings: [{ name: 'x', kind }],
+            loaderRefs: [],
+            componentRefs: ['x'],
+            beforeLoadRefs: ['x'],
+          })
+          const result = computeSharedBindings({
+            code,
+            codeSplitGroupings: groupings,
+          })
+          expect(result.has('x')).toBe(true)
+        })
+      }
+    }
+  })
+
+  describe('two bindings × cross-group references', () => {
+    for (const { name: groupName, groupings } of groupingConfigs) {
+      // Both bindings in same group → neither shared
+      it(`both in loader only [${groupName}] → neither shared`, () => {
+        const code = makeRouteCode({
+          bindings: [
+            { name: 'a', kind: 'const' },
+            { name: 'b', kind: 'const' },
+          ],
+          loaderRefs: ['a', 'b'],
+          componentRefs: [],
+        })
+        const result = computeSharedBindings({
+          code,
+          codeSplitGroupings: groupings,
+        })
+        expect(result.has('a')).toBe(false)
+        expect(result.has('b')).toBe(false)
+      })
+
+      // One binding per group → neither shared
+      it(`one per group, no overlap [${groupName}] → neither shared`, () => {
+        const code = makeRouteCode({
+          bindings: [
+            { name: 'a', kind: 'const' },
+            { name: 'b', kind: 'const' },
+          ],
+          loaderRefs: ['a'],
+          componentRefs: ['b'],
+        })
+        const result = computeSharedBindings({
+          code,
+          codeSplitGroupings: groupings,
+        })
+        expect(result.has('a')).toBe(false)
+        expect(result.has('b')).toBe(false)
+      })
+
+      // Both in both groups → both shared
+      it(`both in both groups [${groupName}] → both shared`, () => {
+        const code = makeRouteCode({
+          bindings: [
+            { name: 'a', kind: 'const' },
+            { name: 'b', kind: 'const' },
+          ],
+          loaderRefs: ['a', 'b'],
+          componentRefs: ['a', 'b'],
+        })
+        const result = computeSharedBindings({
+          code,
+          codeSplitGroupings: groupings,
+        })
+        expect(result.has('a')).toBe(true)
+        expect(result.has('b')).toBe(true)
+      })
+
+      // One shared, one not → exactly one shared
+      it(`one in both groups, one in one [${groupName}] → only cross-group is shared`, () => {
+        const code = makeRouteCode({
+          bindings: [
+            { name: 'a', kind: 'const' },
+            { name: 'b', kind: 'const' },
+          ],
+          loaderRefs: ['a'],
+          componentRefs: ['a', 'b'],
+        })
+        const result = computeSharedBindings({
+          code,
+          codeSplitGroupings: groupings,
+        })
+        expect(result.has('a')).toBe(true)
+        expect(result.has('b')).toBe(false)
+      })
+    }
+  })
+
+  describe('transitive dependency chains', () => {
+    it('A depends on B, both used by different groups → both shared', () => {
+      const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const BASE = 'https://api.example.com'
+const config = { url: BASE }
+export const Route = createFileRoute('/')({
+  loader: () => config.url,
+  component: () => <div>{config.url}</div>,
+})
+`
+      const result = computeSharedBindings({
+        code,
+        codeSplitGroupings: defaultCodeSplitGroupings,
+      })
+      // config is directly used by both groups → shared
+      expect(result.has('config')).toBe(true)
+      // BASE is a dep of config → also shared
+      expect(result.has('BASE')).toBe(true)
+    })
+
+    it('A depends on B depends on C, A used cross-group → all three shared', () => {
+      const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const c = 'deep'
+const b = c + '-value'
+const a = b + '-final'
+export const Route = createFileRoute('/')({
+  loader: () => a,
+  component: () => <div>{a}</div>,
+})
+`
+      const result = computeSharedBindings({
+        code,
+        codeSplitGroupings: defaultCodeSplitGroupings,
+      })
+      expect(result.has('a')).toBe(true)
+      expect(result.has('b')).toBe(true)
+      expect(result.has('c')).toBe(true)
+    })
+
+    it('diamond dependency: A→B, A→C, B→D, C→D → all shared when A is cross-group', () => {
+      const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const D = 42
+const B = D + 1
+const C = D + 2
+const A = B + C
+export const Route = createFileRoute('/')({
+  loader: () => A,
+  component: () => <div>{A}</div>,
+})
+`
+      const result = computeSharedBindings({
+        code,
+        codeSplitGroupings: defaultCodeSplitGroupings,
+      })
+      expect(result.has('A')).toBe(true)
+      expect(result.has('B')).toBe(true)
+      expect(result.has('C')).toBe(true)
+      expect(result.has('D')).toBe(true)
+    })
+  })
+
+  describe('meta-invariant: all fixture files satisfy core contracts', () => {
+    const sharedFixtures = [
+      'shared-variable.tsx',
+      'shared-class.tsx',
+      'shared-function.tsx',
+      'shared-exported.tsx',
+      'shared-indirect-ref.tsx',
+      'shared-none.tsx',
+      'shared-destructured.tsx',
+      'shared-destructured-export.tsx',
+      'shared-imported-binding.tsx',
+      'shared-jsx-component-ref.tsx',
+      'shared-referencing-route.tsx',
+      'shared-transitive.tsx',
+      'shared-with-side-effect.tsx',
+    ]
+
+    // Run invariants across ALL existing test fixtures — like a conformance suite
+    it.each(sharedFixtures)(
+      'fixture "%s" satisfies: Route excluded, results ⊆ localBindings',
+      async (filename) => {
+        const file = await readFile(
+          path.join(__dirname, `./code-splitter/test-files/react/${filename}`),
+        )
+        const code = file.toString()
+
+        const result = computeSharedBindings({
+          code,
+          codeSplitGroupings: defaultCodeSplitGroupings,
+        })
+
+        // Contract 1: Route is never shared
+        expect(result.has('Route')).toBe(false)
+
+        // Contract 2: all results are real local bindings
+        const ast = parseAst({ code })
+        const localBindings = new Set<string>()
+        for (const stmt of ast.program.body) {
+          collectLocalBindingsFromStatement(stmt, localBindings)
+        }
+        localBindings.delete('Route')
+
+        for (const name of result) {
+          expect(localBindings.has(name)).toBe(true)
+        }
+
+        // Contract 3: result is deterministic
+        const result2 = computeSharedBindings({
+          code,
+          codeSplitGroupings: defaultCodeSplitGroupings,
+        })
+        expect(result).toEqual(result2)
       },
     )
   })
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/arrow-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/arrow-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/boolean-null-literals@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/boolean-null-literals@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/chinese@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/chinese@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/circular-reference-arrow-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/circular-reference-arrow-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/circular-reference-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/circular-reference-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/conditional-properties@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/conditional-properties@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-multiple.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-multiple.tsx
new file mode 100644
index 0000000000..dcf67bfcb4
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-multiple.tsx
@@ -0,0 +1,15 @@
+const $$splitComponentImporter = () => import('destructured-export-multiple.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const getConfig = () => ({
+  baseUrl: 'https://api.example.com',
+  timeout: 5000
+});
+export const {
+  baseUrl,
+  timeout
+} = getConfig();
+export const [first, second] = [1, 2];
+export const Route = createFileRoute('/about')({
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-multiple@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-multiple@component.tsx
new file mode 100644
index 0000000000..9441b5a689
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-multiple@component.tsx
@@ -0,0 +1,8 @@
+import { baseUrl, timeout } from "destructured-export-multiple.tsx";
+function AboutComponent() {
+  return <div>
+      <p>Base URL: {baseUrl}</p>
+      <p>Timeout: {timeout}</p>
+    </div>;
+}
+export { AboutComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-multiple@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-multiple@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-multiple@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-multiple@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-multiple@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-multiple@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-nested.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-nested.tsx
new file mode 100644
index 0000000000..6793123b2f
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-nested.tsx
@@ -0,0 +1,19 @@
+const $$splitComponentImporter = () => import('destructured-export-nested.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+const getConfig = () => ({
+  api: {
+    baseUrl: 'https://api.example.com'
+  },
+  timeout: 5000,
+  extra: 'data'
+});
+export const {
+  api: {
+    baseUrl
+  },
+  ...rest
+} = getConfig();
+export const Route = createFileRoute('/about')({
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-nested@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-nested@component.tsx
new file mode 100644
index 0000000000..8ba46e33e1
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-nested@component.tsx
@@ -0,0 +1,7 @@
+import { baseUrl } from "destructured-export-nested.tsx";
+function AboutComponent() {
+  return <div>
+      <p>Base URL: {baseUrl}</p>
+    </div>;
+}
+export { AboutComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-nested@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-nested@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-nested@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-nested@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-nested@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export-nested@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export.tsx
new file mode 100644
index 0000000000..31b1bfbe8b
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export.tsx
@@ -0,0 +1,17 @@
+const $$splitComponentImporter = () => import('destructured-export.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export function getObjectCallback() {
+  return {
+    getObject: () => ({
+      constA: 10,
+      constB: 5
+    })
+  };
+}
+export const {
+  getObject
+} = getObjectCallback();
+export const Route = createFileRoute('/about')({
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export@component.tsx
new file mode 100644
index 0000000000..f58942d5af
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export@component.tsx
@@ -0,0 +1,14 @@
+export function getObjectCallback() {
+  return {
+    getObject: () => ({
+      constA: 10,
+      constB: 5
+    })
+  };
+}
+function AboutComponent() {
+  return <div className="p-2">
+      <h3>About</h3>
+    </div>;
+}
+export { AboutComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export@errorComponent.tsx
new file mode 100644
index 0000000000..45fb19eecd
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export@errorComponent.tsx
@@ -0,0 +1,8 @@
+export function getObjectCallback() {
+  return {
+    getObject: () => ({
+      constA: 10,
+      constB: 5
+    })
+  };
+}
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export@notFoundComponent.tsx
new file mode 100644
index 0000000000..45fb19eecd
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export@notFoundComponent.tsx
@@ -0,0 +1,8 @@
+export function getObjectCallback() {
+  return {
+    getObject: () => ({
+      constA: 10,
+      constB: 5
+    })
+  };
+}
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-export@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-react-memo-imported-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-react-memo-imported-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults.tsx
new file mode 100644
index 0000000000..7c54a2c145
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults.tsx
@@ -0,0 +1,8 @@
+import { loader } from "destructured-route-options-defaults.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('destructured-route-options-defaults.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/about')({
+  component: lazyRouteComponent($$splitComponentImporter, 'component'),
+  loader
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults@component.tsx
new file mode 100644
index 0000000000..c73696ff32
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults@component.tsx
@@ -0,0 +1,2 @@
+import { MyComponent } from "destructured-route-options-defaults.tsx?tsr-shared=1";
+export { MyComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults@shared.tsx
new file mode 100644
index 0000000000..fdc9acef5b
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructured-route-options-defaults@shared.tsx
@@ -0,0 +1,22 @@
+function defaultLoader() {
+  return {
+    message: 'default'
+  };
+}
+function DefaultComponent() {
+  return <div>Default</div>;
+}
+const createBits = () => ({
+  component: ActualComponent,
+  loader: () => ({
+    message: 'hello'
+  })
+});
+const {
+  component: MyComponent = DefaultComponent,
+  loader = defaultLoader
+} = createBits();
+function ActualComponent() {
+  return <div>About</div>;
+}
+export { ActualComponent, createBits, DefaultComponent, defaultLoader, loader, MyComponent };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructuring@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/destructuring@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue.tsx
new file mode 100644
index 0000000000..68f8be0364
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue.tsx
@@ -0,0 +1,8 @@
+'use client';
+
+const $$splitComponentImporter = () => import('directive-prologue.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/directive')({
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue@component.tsx
new file mode 100644
index 0000000000..ce7cd5e5ee
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue@component.tsx
@@ -0,0 +1,6 @@
+'use client';
+
+const SplitComponent = () => {
+  return <div>directive preserved</div>;
+};
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/directive-prologue@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/explicit-undefined-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/explicit-undefined-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/export-default-component-and-normal-notFound@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/export-default-component-and-normal-notFound@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/export-default-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/export-default-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/function-as-parameter@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/function-as-parameter@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/function-declaration@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/function-declaration@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/importAttribute@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/importAttribute@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported-default-component-destructured-loader@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported-default-component-destructured-loader@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported-default-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported-default-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported-errorComponent@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported-errorComponent@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported-notFoundComponent@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported-notFoundComponent@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported-pendingComponent@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported-pendingComponent@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/imported@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@component.tsx
index 4b18cae17a..58ccfb2903 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@component.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@component.tsx
@@ -7,7 +7,6 @@ const Button = (props: {
   return <button>{props.children}</button>;
 };
 import { Route } from "inline.tsx";
-Route.addChildren([]);
 import { test } from "inline.tsx";
 const SplitComponent = () => {
   return <div className="p-2">
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@errorComponent.tsx
index 4a822161e1..9236af6021 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@errorComponent.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@errorComponent.tsx
@@ -1,3 +1,2 @@
 import * as React from 'react';
-import { Route } from "inline.tsx";
-Route.addChildren([]);
\ No newline at end of file
+import { Route } from "inline.tsx";
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@notFoundComponent.tsx
index 4a822161e1..9236af6021 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@notFoundComponent.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@notFoundComponent.tsx
@@ -1,3 +1,2 @@
 import * as React from 'react';
-import { Route } from "inline.tsx";
-Route.addChildren([]);
\ No newline at end of file
+import { Route } from "inline.tsx";
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/inline@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/random-number@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/random-number@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/react-memo-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/react-memo-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/react-memo-imported-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/react-memo-imported-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-export-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-export-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-const@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-const@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-destructured.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-destructured.tsx
new file mode 100644
index 0000000000..0e3175116f
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-destructured.tsx
@@ -0,0 +1,19 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const createBits = () => ({
+  component: AboutComponentImpl,
+  loader: () => ({
+    message: 'hello',
+  }),
+})
+
+export const { component: AboutComponent, loader } = createBits()
+
+function AboutComponentImpl() {
+  return <div>About</div>
+}
+
+export const Route = createFileRoute('/about')({
+  component: AboutComponent,
+  loader,
+})
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-destructured@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-destructured@component.tsx
new file mode 100644
index 0000000000..a6d57afe77
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-destructured@component.tsx
@@ -0,0 +1,2 @@
+import { AboutComponent } from "retain-exports-destructured.tsx?tsr-shared=1";
+export { AboutComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-destructured@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-destructured@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-destructured@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-destructured@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-destructured@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-destructured@shared.tsx
new file mode 100644
index 0000000000..b03a4eb83a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-destructured@shared.tsx
@@ -0,0 +1,14 @@
+const createBits = () => ({
+  component: AboutComponentImpl,
+  loader: () => ({
+    message: 'hello'
+  })
+});
+const {
+  component: AboutComponent,
+  loader
+} = createBits();
+function AboutComponentImpl() {
+  return <div>About</div>;
+}
+export { AboutComponent, AboutComponentImpl, createBits, loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-loader@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/retain-exports-loader@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class.tsx
new file mode 100644
index 0000000000..6e2f0229e4
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class.tsx
@@ -0,0 +1,10 @@
+import { store } from "shared-class.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-class.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/store')({
+  loader: async () => {
+    store.set('items', await fetch('/api'));
+  },
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class@component.tsx
new file mode 100644
index 0000000000..6a38b10ff8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class@component.tsx
@@ -0,0 +1,3 @@
+import { store } from "shared-class.tsx?tsr-shared=1";
+const SplitComponent = () => <div>{store.get('items')}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class@shared.tsx
new file mode 100644
index 0000000000..18c40bafb6
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-class@shared.tsx
@@ -0,0 +1,11 @@
+class DataStore {
+  data = new Map();
+  get(k: string) {
+    return this.data.get(k);
+  }
+  set(k: string, v: unknown) {
+    this.data.set(k, v);
+  }
+}
+const store = new DataStore();
+export { DataStore, store };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export.tsx
new file mode 100644
index 0000000000..9453dbfbda
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export.tsx
@@ -0,0 +1,9 @@
+import { apiUrl } from "shared-destructured-export.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-destructured-export.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/config')({
+  loader: async () => fetch(apiUrl),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
+export { apiUrl, timeout } from "shared-destructured-export.tsx?tsr-shared=1";
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export@component.tsx
new file mode 100644
index 0000000000..16b288ac5f
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export@component.tsx
@@ -0,0 +1,3 @@
+import { timeout } from "shared-destructured-export.tsx?tsr-shared=1";
+const SplitComponent = () => <div>Timeout: {timeout}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export@shared.tsx
new file mode 100644
index 0000000000..f0bfd70add
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured-export@shared.tsx
@@ -0,0 +1,11 @@
+const {
+  apiUrl,
+  timeout
+} = getConfig();
+function getConfig() {
+  return {
+    apiUrl: '/api',
+    timeout: 5000
+  };
+}
+export { apiUrl, getConfig, timeout };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured.tsx
new file mode 100644
index 0000000000..3019454516
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured.tsx
@@ -0,0 +1,8 @@
+import { apiUrl } from "shared-destructured.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-destructured.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/config')({
+  loader: async () => fetch(apiUrl),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured@component.tsx
new file mode 100644
index 0000000000..5c0182e61a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured@component.tsx
@@ -0,0 +1,3 @@
+import { timeout } from "shared-destructured.tsx?tsr-shared=1";
+const SplitComponent = () => <div>Timeout: {timeout}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured@shared.tsx
new file mode 100644
index 0000000000..f0bfd70add
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-destructured@shared.tsx
@@ -0,0 +1,11 @@
+const {
+  apiUrl,
+  timeout
+} = getConfig();
+function getConfig() {
+  return {
+    apiUrl: '/api',
+    timeout: 5000
+  };
+}
+export { apiUrl, getConfig, timeout };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported.tsx
new file mode 100644
index 0000000000..c2eb8b1012
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported.tsx
@@ -0,0 +1,13 @@
+import { queryOptions } from "shared-exported.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-exported.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/query')({
+  loader: async () => {
+    return {
+      staleTime: queryOptions.staleTime
+    };
+  },
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
+export { queryOptions } from "shared-exported.tsx?tsr-shared=1";
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported@component.tsx
new file mode 100644
index 0000000000..b020b5cadf
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported@component.tsx
@@ -0,0 +1,3 @@
+import { queryOptions } from "shared-exported.tsx?tsr-shared=1";
+const SplitComponent = () => <div>GC: {queryOptions.gcTime}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported@shared.tsx
new file mode 100644
index 0000000000..a3f91b85bb
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-exported@shared.tsx
@@ -0,0 +1,5 @@
+const queryOptions = {
+  staleTime: 5000,
+  gcTime: 10000
+};
+export { queryOptions };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function.tsx
new file mode 100644
index 0000000000..7372ff4b07
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function.tsx
@@ -0,0 +1,14 @@
+import { getCached, cache } from "shared-function.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-function.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+function setCached(key: string, val: unknown) {
+  cache.set(key, val);
+}
+export const Route = createFileRoute('/cached')({
+  loader: async () => {
+    setCached('data', await fetch('/api').then(r => r.json()));
+    return getCached('data');
+  },
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function@component.tsx
new file mode 100644
index 0000000000..571bd9356a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function@component.tsx
@@ -0,0 +1,3 @@
+import { getCached } from "shared-function.tsx?tsr-shared=1";
+const SplitComponent = () => <div>{JSON.stringify(getCached('data'))}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function@shared.tsx
new file mode 100644
index 0000000000..27d2cf03f1
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-function@shared.tsx
@@ -0,0 +1,5 @@
+const cache = new Map();
+function getCached(key: string) {
+  return cache.get(key);
+}
+export { cache, getCached };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding.tsx
new file mode 100644
index 0000000000..c3e284c081
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding.tsx
@@ -0,0 +1,8 @@
+const $$splitComponentImporter = () => import('shared-imported-binding.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+import { sharedUtil } from '../utils';
+export const Route = createFileRoute('/imported')({
+  loader: async () => sharedUtil('load'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding@component.tsx
new file mode 100644
index 0000000000..0a835ae063
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding@component.tsx
@@ -0,0 +1,3 @@
+import { sharedUtil } from '../utils';
+const SplitComponent = () => <div>{sharedUtil('render')}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-imported-binding@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref.tsx
new file mode 100644
index 0000000000..889dd57cf0
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref.tsx
@@ -0,0 +1,13 @@
+import { state, getCount } from "shared-indirect-ref.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-indirect-ref.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/shared-indirect')({
+  loader: () => {
+    state.count++;
+    return {
+      count: getCount()
+    };
+  },
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref@component.tsx
new file mode 100644
index 0000000000..62995e7fd8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref@component.tsx
@@ -0,0 +1,7 @@
+import { state, getCount } from "shared-indirect-ref.tsx?tsr-shared=1";
+function SharedComponent() {
+  return <div>
+      {getCount()} - {state.count}
+    </div>;
+}
+export { SharedComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref@shared.tsx
new file mode 100644
index 0000000000..7e7e811ba8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-indirect-ref@shared.tsx
@@ -0,0 +1,7 @@
+const state = {
+  count: 0
+};
+function getCount() {
+  return state.count;
+}
+export { getCount, state };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref.tsx
new file mode 100644
index 0000000000..728caca361
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref.tsx
@@ -0,0 +1,9 @@
+import { shared } from "shared-jsx-component-ref.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-jsx-component-ref.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+// @ts-nocheck
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/jsx')({
+  loader: () => shared,
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref@component.tsx
new file mode 100644
index 0000000000..52ecb6d474
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref@component.tsx
@@ -0,0 +1,5 @@
+import { shared } from "shared-jsx-component-ref.tsx?tsr-shared=1"; // @ts-nocheck
+function SharedComponent() {
+  return <div>{shared}</div>;
+}
+export { SharedComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref@shared.tsx
new file mode 100644
index 0000000000..d5cc2cf990
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-jsx-component-ref@shared.tsx
@@ -0,0 +1,4 @@
+// @ts-nocheck
+
+const shared = 1;
+export { shared };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none.tsx
new file mode 100644
index 0000000000..dd352bfc41
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none.tsx
@@ -0,0 +1,8 @@
+const $$splitComponentImporter = () => import('shared-none.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+const loaderHelper = () => fetch('/api');
+export const Route = createFileRoute('/clean')({
+  loader: async () => loaderHelper(),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none@component.tsx
new file mode 100644
index 0000000000..701deeedeb
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none@component.tsx
@@ -0,0 +1,5 @@
+const ComponentHelper = () => <span>helper</span>;
+const SplitComponent = () => <div>
+      <ComponentHelper />
+    </div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-none@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route.tsx
new file mode 100644
index 0000000000..f82ac5b900
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route.tsx
@@ -0,0 +1,16 @@
+import { HEADER } from "shared-referencing-route.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-referencing-route.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+function usePageTitle() {
+  return `${HEADER} - ${Route.fullPath}`;
+}
+export const Route = createFileRoute('/about')({
+  loader: async () => {
+    const title = usePageTitle();
+    return {
+      title
+    };
+  },
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route@component.tsx
new file mode 100644
index 0000000000..2cb2cdb68c
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route@component.tsx
@@ -0,0 +1,10 @@
+import { HEADER } from "shared-referencing-route.tsx?tsr-shared=1";
+function usePageTitle() {
+  return `${HEADER} - ${Route.fullPath}`;
+}
+import { Route } from "shared-referencing-route.tsx";
+const SplitComponent = () => {
+  const title = usePageTitle();
+  return <div>{title}</div>;
+};
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route@shared.tsx
new file mode 100644
index 0000000000..cc2d01424c
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-referencing-route@shared.tsx
@@ -0,0 +1,2 @@
+const HEADER = 'Page';
+export { HEADER };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive.tsx
new file mode 100644
index 0000000000..ce5a10c47c
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive.tsx
@@ -0,0 +1,11 @@
+import { config } from "shared-transitive.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-transitive.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+const fetcher = (path: string) => fetch(`${config.url}${path}`);
+export const Route = createFileRoute('/api')({
+  loader: async () => {
+    return fetcher('/data');
+  },
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive@component.tsx
new file mode 100644
index 0000000000..7a3a74048e
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive@component.tsx
@@ -0,0 +1,3 @@
+import { config } from "shared-transitive.tsx?tsr-shared=1";
+const SplitComponent = () => <div>Timeout: {config.timeout}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive@shared.tsx
new file mode 100644
index 0000000000..8bec4a1d55
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-transitive@shared.tsx
@@ -0,0 +1,6 @@
+const BASE_URL = 'https://api.example.com';
+const config = {
+  url: BASE_URL,
+  timeout: 5000
+};
+export { BASE_URL, config };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable.tsx
new file mode 100644
index 0000000000..c0c02cec46
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable.tsx
@@ -0,0 +1,13 @@
+import { collection } from "shared-variable.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-variable.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/todos')({
+  loader: async () => {
+    await collection.preload();
+    return {
+      data: 'loaded'
+    };
+  },
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable@component.tsx
new file mode 100644
index 0000000000..d149922fbc
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable@component.tsx
@@ -0,0 +1,3 @@
+import { collection } from "shared-variable.tsx?tsr-shared=1";
+const SplitComponent = () => <div>{collection.name}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable@shared.tsx
new file mode 100644
index 0000000000..8a0560d5b9
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-variable@shared.tsx
@@ -0,0 +1,5 @@
+const collection = {
+  name: 'todos',
+  preload: async () => {}
+};
+export { collection };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect.tsx
new file mode 100644
index 0000000000..cba0c7770b
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect.tsx
@@ -0,0 +1,11 @@
+import { registry } from "shared-with-side-effect.tsx?tsr-shared=1";
+const $$splitComponentImporter = () => import('shared-with-side-effect.tsx?tsr-split=component');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+console.log('registry created');
+export const Route = createFileRoute('/fx')({
+  loader: async () => {
+    registry.set('loaded', true);
+  },
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect@component.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect@component.tsx
new file mode 100644
index 0000000000..d953af00fa
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect@component.tsx
@@ -0,0 +1,3 @@
+import { registry } from "shared-with-side-effect.tsx?tsr-shared=1";
+const SplitComponent = () => <div>{registry.size}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect@notFoundComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect@notFoundComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect@shared.tsx
new file mode 100644
index 0000000000..f26c656fdd
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/shared-with-side-effect@shared.tsx
@@ -0,0 +1,2 @@
+const registry = new Map();
+export { registry };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/undefined-literals@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/undefined-literals@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/useStateDestructure.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/useStateDestructure.tsx
index 8f79e69bf0..d0de09bf8b 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/useStateDestructure.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/useStateDestructure.tsx
@@ -188,7 +188,7 @@ export default function VersionIndex() {
         </div>
         <div className="flex items-center gap-2 flex-wrap justify-center">
           <a
-            href={`https://github.com/tanstack/tanstack.com`}
+            href={`https://github.com/TanStack/tanstack.com`}
             className={`flex items-center gap-2 py-2 px-4 bg-cyan-700 rounded text-white uppercase font-extrabold`}
           >
             <FaGithub /> View TanStack.com Source
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/useStateDestructure@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/useStateDestructure@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/using@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/1-default/using@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/arrow-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/arrow-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/boolean-null-literals@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/boolean-null-literals@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/chinese@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/chinese@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/circular-reference-arrow-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/circular-reference-arrow-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/circular-reference-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/circular-reference-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/conditional-properties@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/conditional-properties@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-multiple.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-multiple.tsx
new file mode 100644
index 0000000000..e411fd54d8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-multiple.tsx
@@ -0,0 +1,15 @@
+const $$splitComponentImporter = () => import('destructured-export-multiple.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const getConfig = () => ({
+  baseUrl: 'https://api.example.com',
+  timeout: 5000
+});
+export const {
+  baseUrl,
+  timeout
+} = getConfig();
+export const [first, second] = [1, 2];
+export const Route = createFileRoute('/about')({
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-multiple@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-multiple@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..9441b5a689
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-multiple@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,8 @@
+import { baseUrl, timeout } from "destructured-export-multiple.tsx";
+function AboutComponent() {
+  return <div>
+      <p>Base URL: {baseUrl}</p>
+      <p>Timeout: {timeout}</p>
+    </div>;
+}
+export { AboutComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-multiple@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-multiple@loader.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-multiple@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-multiple@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-nested.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-nested.tsx
new file mode 100644
index 0000000000..076c24b06f
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-nested.tsx
@@ -0,0 +1,19 @@
+const $$splitComponentImporter = () => import('destructured-export-nested.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+const getConfig = () => ({
+  api: {
+    baseUrl: 'https://api.example.com'
+  },
+  timeout: 5000,
+  extra: 'data'
+});
+export const {
+  api: {
+    baseUrl
+  },
+  ...rest
+} = getConfig();
+export const Route = createFileRoute('/about')({
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-nested@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-nested@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..8ba46e33e1
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-nested@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,7 @@
+import { baseUrl } from "destructured-export-nested.tsx";
+function AboutComponent() {
+  return <div>
+      <p>Base URL: {baseUrl}</p>
+    </div>;
+}
+export { AboutComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-nested@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-nested@loader.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-nested@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export-nested@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export.tsx
new file mode 100644
index 0000000000..3f79ca544b
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export.tsx
@@ -0,0 +1,17 @@
+const $$splitComponentImporter = () => import('destructured-export.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export function getObjectCallback() {
+  return {
+    getObject: () => ({
+      constA: 10,
+      constB: 5
+    })
+  };
+}
+export const {
+  getObject
+} = getObjectCallback();
+export const Route = createFileRoute('/about')({
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..f58942d5af
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,14 @@
+export function getObjectCallback() {
+  return {
+    getObject: () => ({
+      constA: 10,
+      constB: 5
+    })
+  };
+}
+function AboutComponent() {
+  return <div className="p-2">
+      <h3>About</h3>
+    </div>;
+}
+export { AboutComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export@loader.tsx
new file mode 100644
index 0000000000..45fb19eecd
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export@loader.tsx
@@ -0,0 +1,8 @@
+export function getObjectCallback() {
+  return {
+    getObject: () => ({
+      constA: 10,
+      constB: 5
+    })
+  };
+}
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-export@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-react-memo-imported-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-react-memo-imported-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults.tsx
new file mode 100644
index 0000000000..1759b05846
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults.tsx
@@ -0,0 +1,9 @@
+const $$splitLoaderImporter = () => import('destructured-route-options-defaults.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+const $$splitComponentImporter = () => import('destructured-route-options-defaults.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/about')({
+  component: lazyRouteComponent($$splitComponentImporter, 'component'),
+  loader: lazyFn($$splitLoaderImporter, 'loader')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..c73696ff32
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,2 @@
+import { MyComponent } from "destructured-route-options-defaults.tsx?tsr-shared=1";
+export { MyComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults@loader.tsx
new file mode 100644
index 0000000000..99d9619b91
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults@loader.tsx
@@ -0,0 +1,2 @@
+import { loader } from "destructured-route-options-defaults.tsx?tsr-shared=1";
+export { loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults@shared.tsx
new file mode 100644
index 0000000000..fdc9acef5b
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructured-route-options-defaults@shared.tsx
@@ -0,0 +1,22 @@
+function defaultLoader() {
+  return {
+    message: 'default'
+  };
+}
+function DefaultComponent() {
+  return <div>Default</div>;
+}
+const createBits = () => ({
+  component: ActualComponent,
+  loader: () => ({
+    message: 'hello'
+  })
+});
+const {
+  component: MyComponent = DefaultComponent,
+  loader = defaultLoader
+} = createBits();
+function ActualComponent() {
+  return <div>About</div>;
+}
+export { ActualComponent, createBits, DefaultComponent, defaultLoader, loader, MyComponent };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructuring@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/destructuring@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/directive-prologue.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/directive-prologue.tsx
new file mode 100644
index 0000000000..12d3529331
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/directive-prologue.tsx
@@ -0,0 +1,8 @@
+'use client';
+
+const $$splitComponentImporter = () => import('directive-prologue.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/directive')({
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/directive-prologue@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/directive-prologue@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..ce7cd5e5ee
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/directive-prologue@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,6 @@
+'use client';
+
+const SplitComponent = () => {
+  return <div>directive preserved</div>;
+};
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/directive-prologue@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/directive-prologue@loader.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/directive-prologue@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/directive-prologue@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/explicit-undefined-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/explicit-undefined-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/export-default-component-and-normal-notFound@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/export-default-component-and-normal-notFound@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/export-default-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/export-default-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/function-as-parameter@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/function-as-parameter@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/function-declaration@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/function-declaration@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/importAttribute@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/importAttribute@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported-default-component-destructured-loader@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported-default-component-destructured-loader@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported-default-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported-default-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported-errorComponent@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported-errorComponent@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported-notFoundComponent@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported-notFoundComponent@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported-pendingComponent@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported-pendingComponent@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/imported@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/inline@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/inline@component---errorComponent---notFoundComponent---pendingComponent.tsx
index 4b18cae17a..58ccfb2903 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/inline@component---errorComponent---notFoundComponent---pendingComponent.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/inline@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -7,7 +7,6 @@ const Button = (props: {
   return <button>{props.children}</button>;
 };
 import { Route } from "inline.tsx";
-Route.addChildren([]);
 import { test } from "inline.tsx";
 const SplitComponent = () => {
   return <div className="p-2">
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/inline@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/inline@loader.tsx
index 4a822161e1..9236af6021 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/inline@loader.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/inline@loader.tsx
@@ -1,3 +1,2 @@
 import * as React from 'react';
-import { Route } from "inline.tsx";
-Route.addChildren([]);
\ No newline at end of file
+import { Route } from "inline.tsx";
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/inline@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/inline@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/random-number@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/random-number@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/react-memo-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/react-memo-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/react-memo-imported-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/react-memo-imported-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-export-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-export-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-const@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-const@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured.tsx
new file mode 100644
index 0000000000..0e3175116f
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured.tsx
@@ -0,0 +1,19 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const createBits = () => ({
+  component: AboutComponentImpl,
+  loader: () => ({
+    message: 'hello',
+  }),
+})
+
+export const { component: AboutComponent, loader } = createBits()
+
+function AboutComponentImpl() {
+  return <div>About</div>
+}
+
+export const Route = createFileRoute('/about')({
+  component: AboutComponent,
+  loader,
+})
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..a6d57afe77
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,2 @@
+import { AboutComponent } from "retain-exports-destructured.tsx?tsr-shared=1";
+export { AboutComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured@loader.tsx
new file mode 100644
index 0000000000..e8d771ea44
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured@loader.tsx
@@ -0,0 +1,2 @@
+import { loader } from "retain-exports-destructured.tsx?tsr-shared=1";
+export { loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured@shared.tsx
new file mode 100644
index 0000000000..b03a4eb83a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-destructured@shared.tsx
@@ -0,0 +1,14 @@
+const createBits = () => ({
+  component: AboutComponentImpl,
+  loader: () => ({
+    message: 'hello'
+  })
+});
+const {
+  component: AboutComponent,
+  loader
+} = createBits();
+function AboutComponentImpl() {
+  return <div>About</div>;
+}
+export { AboutComponent, AboutComponentImpl, createBits, loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-loader@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/retain-exports-loader@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class.tsx
new file mode 100644
index 0000000000..da068daa17
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-class.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-class.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/store')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..6a38b10ff8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,3 @@
+import { store } from "shared-class.tsx?tsr-shared=1";
+const SplitComponent = () => <div>{store.get('items')}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class@loader.tsx
new file mode 100644
index 0000000000..f91799f3c8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class@loader.tsx
@@ -0,0 +1,5 @@
+import { store } from "shared-class.tsx?tsr-shared=1";
+const SplitLoader = async () => {
+  store.set('items', await fetch('/api'));
+};
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class@shared.tsx
new file mode 100644
index 0000000000..18c40bafb6
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-class@shared.tsx
@@ -0,0 +1,11 @@
+class DataStore {
+  data = new Map();
+  get(k: string) {
+    return this.data.get(k);
+  }
+  set(k: string, v: unknown) {
+    this.data.set(k, v);
+  }
+}
+const store = new DataStore();
+export { DataStore, store };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export.tsx
new file mode 100644
index 0000000000..7d0f0fcae1
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export.tsx
@@ -0,0 +1,10 @@
+const $$splitComponentImporter = () => import('shared-destructured-export.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-destructured-export.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/config')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
+export { apiUrl, timeout } from "shared-destructured-export.tsx?tsr-shared=1";
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..16b288ac5f
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,3 @@
+import { timeout } from "shared-destructured-export.tsx?tsr-shared=1";
+const SplitComponent = () => <div>Timeout: {timeout}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export@loader.tsx
new file mode 100644
index 0000000000..33d4b5aa43
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export@loader.tsx
@@ -0,0 +1,3 @@
+import { apiUrl } from "shared-destructured-export.tsx?tsr-shared=1";
+const SplitLoader = async () => fetch(apiUrl);
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export@shared.tsx
new file mode 100644
index 0000000000..f0bfd70add
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured-export@shared.tsx
@@ -0,0 +1,11 @@
+const {
+  apiUrl,
+  timeout
+} = getConfig();
+function getConfig() {
+  return {
+    apiUrl: '/api',
+    timeout: 5000
+  };
+}
+export { apiUrl, getConfig, timeout };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured.tsx
new file mode 100644
index 0000000000..8185738e9d
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-destructured.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-destructured.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/config')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..5c0182e61a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,3 @@
+import { timeout } from "shared-destructured.tsx?tsr-shared=1";
+const SplitComponent = () => <div>Timeout: {timeout}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured@loader.tsx
new file mode 100644
index 0000000000..94b0923079
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured@loader.tsx
@@ -0,0 +1,3 @@
+import { apiUrl } from "shared-destructured.tsx?tsr-shared=1";
+const SplitLoader = async () => fetch(apiUrl);
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured@shared.tsx
new file mode 100644
index 0000000000..f0bfd70add
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-destructured@shared.tsx
@@ -0,0 +1,11 @@
+const {
+  apiUrl,
+  timeout
+} = getConfig();
+function getConfig() {
+  return {
+    apiUrl: '/api',
+    timeout: 5000
+  };
+}
+export { apiUrl, getConfig, timeout };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported.tsx
new file mode 100644
index 0000000000..ce690311b2
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported.tsx
@@ -0,0 +1,10 @@
+const $$splitComponentImporter = () => import('shared-exported.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-exported.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/query')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
+export { queryOptions } from "shared-exported.tsx?tsr-shared=1";
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..b020b5cadf
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,3 @@
+import { queryOptions } from "shared-exported.tsx?tsr-shared=1";
+const SplitComponent = () => <div>GC: {queryOptions.gcTime}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported@loader.tsx
new file mode 100644
index 0000000000..332fa35079
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported@loader.tsx
@@ -0,0 +1,7 @@
+import { queryOptions } from "shared-exported.tsx?tsr-shared=1";
+const SplitLoader = async () => {
+  return {
+    staleTime: queryOptions.staleTime
+  };
+};
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported@shared.tsx
new file mode 100644
index 0000000000..a3f91b85bb
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-exported@shared.tsx
@@ -0,0 +1,5 @@
+const queryOptions = {
+  staleTime: 5000,
+  gcTime: 10000
+};
+export { queryOptions };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function.tsx
new file mode 100644
index 0000000000..b5bf41235e
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-function.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-function.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/cached')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..571bd9356a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,3 @@
+import { getCached } from "shared-function.tsx?tsr-shared=1";
+const SplitComponent = () => <div>{JSON.stringify(getCached('data'))}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function@loader.tsx
new file mode 100644
index 0000000000..f5f72ab014
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function@loader.tsx
@@ -0,0 +1,9 @@
+import { getCached, cache } from "shared-function.tsx?tsr-shared=1";
+function setCached(key: string, val: unknown) {
+  cache.set(key, val);
+}
+const SplitLoader = async () => {
+  setCached('data', await fetch('/api').then(r => r.json()));
+  return getCached('data');
+};
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function@shared.tsx
new file mode 100644
index 0000000000..27d2cf03f1
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-function@shared.tsx
@@ -0,0 +1,5 @@
+const cache = new Map();
+function getCached(key: string) {
+  return cache.get(key);
+}
+export { cache, getCached };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding.tsx
new file mode 100644
index 0000000000..d9ce6828fa
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-imported-binding.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-imported-binding.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/imported')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..0a835ae063
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,3 @@
+import { sharedUtil } from '../utils';
+const SplitComponent = () => <div>{sharedUtil('render')}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding@loader.tsx
new file mode 100644
index 0000000000..1b27de9093
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding@loader.tsx
@@ -0,0 +1,3 @@
+import { sharedUtil } from '../utils';
+const SplitLoader = async () => sharedUtil('load');
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-imported-binding@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref.tsx
new file mode 100644
index 0000000000..f4dfce52ba
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-indirect-ref.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-indirect-ref.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/shared-indirect')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..62995e7fd8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,7 @@
+import { state, getCount } from "shared-indirect-ref.tsx?tsr-shared=1";
+function SharedComponent() {
+  return <div>
+      {getCount()} - {state.count}
+    </div>;
+}
+export { SharedComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref@loader.tsx
new file mode 100644
index 0000000000..0625ac53f8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref@loader.tsx
@@ -0,0 +1,8 @@
+import { state, getCount } from "shared-indirect-ref.tsx?tsr-shared=1";
+const SplitLoader = () => {
+  state.count++;
+  return {
+    count: getCount()
+  };
+};
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref@shared.tsx
new file mode 100644
index 0000000000..7e7e811ba8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-indirect-ref@shared.tsx
@@ -0,0 +1,7 @@
+const state = {
+  count: 0
+};
+function getCount() {
+  return state.count;
+}
+export { getCount, state };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref.tsx
new file mode 100644
index 0000000000..8ac24d49cf
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref.tsx
@@ -0,0 +1,10 @@
+const $$splitComponentImporter = () => import('shared-jsx-component-ref.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-jsx-component-ref.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+// @ts-nocheck
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/jsx')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..52ecb6d474
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,5 @@
+import { shared } from "shared-jsx-component-ref.tsx?tsr-shared=1"; // @ts-nocheck
+function SharedComponent() {
+  return <div>{shared}</div>;
+}
+export { SharedComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref@loader.tsx
new file mode 100644
index 0000000000..f861dda436
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref@loader.tsx
@@ -0,0 +1,3 @@
+import { shared } from "shared-jsx-component-ref.tsx?tsr-shared=1"; // @ts-nocheck
+const SplitLoader = () => shared;
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref@shared.tsx
new file mode 100644
index 0000000000..d5cc2cf990
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-jsx-component-ref@shared.tsx
@@ -0,0 +1,4 @@
+// @ts-nocheck
+
+const shared = 1;
+export { shared };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none.tsx
new file mode 100644
index 0000000000..06e81042d6
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-none.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-none.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/clean')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..701deeedeb
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,5 @@
+const ComponentHelper = () => <span>helper</span>;
+const SplitComponent = () => <div>
+      <ComponentHelper />
+    </div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none@loader.tsx
new file mode 100644
index 0000000000..d0cfce36ee
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none@loader.tsx
@@ -0,0 +1,3 @@
+const loaderHelper = () => fetch('/api');
+const SplitLoader = async () => loaderHelper();
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-none@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route.tsx
new file mode 100644
index 0000000000..b62568c1fb
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-referencing-route.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-referencing-route.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/about')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..2cb2cdb68c
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,10 @@
+import { HEADER } from "shared-referencing-route.tsx?tsr-shared=1";
+function usePageTitle() {
+  return `${HEADER} - ${Route.fullPath}`;
+}
+import { Route } from "shared-referencing-route.tsx";
+const SplitComponent = () => {
+  const title = usePageTitle();
+  return <div>{title}</div>;
+};
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route@loader.tsx
new file mode 100644
index 0000000000..baedd53bd7
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route@loader.tsx
@@ -0,0 +1,12 @@
+import { HEADER } from "shared-referencing-route.tsx?tsr-shared=1";
+function usePageTitle() {
+  return `${HEADER} - ${Route.fullPath}`;
+}
+import { Route } from "shared-referencing-route.tsx";
+const SplitLoader = async () => {
+  const title = usePageTitle();
+  return {
+    title
+  };
+};
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route@shared.tsx
new file mode 100644
index 0000000000..cc2d01424c
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-referencing-route@shared.tsx
@@ -0,0 +1,2 @@
+const HEADER = 'Page';
+export { HEADER };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive.tsx
new file mode 100644
index 0000000000..869602e15b
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-transitive.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-transitive.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/api')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..7a3a74048e
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,3 @@
+import { config } from "shared-transitive.tsx?tsr-shared=1";
+const SplitComponent = () => <div>Timeout: {config.timeout}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive@loader.tsx
new file mode 100644
index 0000000000..8472eab295
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive@loader.tsx
@@ -0,0 +1,6 @@
+import { config } from "shared-transitive.tsx?tsr-shared=1";
+const fetcher = (path: string) => fetch(`${config.url}${path}`);
+const SplitLoader = async () => {
+  return fetcher('/data');
+};
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive@shared.tsx
new file mode 100644
index 0000000000..8bec4a1d55
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-transitive@shared.tsx
@@ -0,0 +1,6 @@
+const BASE_URL = 'https://api.example.com';
+const config = {
+  url: BASE_URL,
+  timeout: 5000
+};
+export { BASE_URL, config };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable.tsx
new file mode 100644
index 0000000000..42f68cce48
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-variable.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-variable.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/todos')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..d149922fbc
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,3 @@
+import { collection } from "shared-variable.tsx?tsr-shared=1";
+const SplitComponent = () => <div>{collection.name}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable@loader.tsx
new file mode 100644
index 0000000000..196a8e48a4
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable@loader.tsx
@@ -0,0 +1,8 @@
+import { collection } from "shared-variable.tsx?tsr-shared=1";
+const SplitLoader = async () => {
+  await collection.preload();
+  return {
+    data: 'loaded'
+  };
+};
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable@shared.tsx
new file mode 100644
index 0000000000..8a0560d5b9
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-variable@shared.tsx
@@ -0,0 +1,5 @@
+const collection = {
+  name: 'todos',
+  preload: async () => {}
+};
+export { collection };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect.tsx
new file mode 100644
index 0000000000..943cdf189c
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect.tsx
@@ -0,0 +1,10 @@
+const $$splitComponentImporter = () => import('shared-with-side-effect.tsx?tsr-split=component---errorComponent---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-with-side-effect.tsx?tsr-split=loader');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+console.log('registry created');
+export const Route = createFileRoute('/fx')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect@component---errorComponent---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect@component---errorComponent---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..d953af00fa
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect@component---errorComponent---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,3 @@
+import { registry } from "shared-with-side-effect.tsx?tsr-shared=1";
+const SplitComponent = () => <div>{registry.size}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect@loader.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect@loader.tsx
new file mode 100644
index 0000000000..a5f06a0a05
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect@loader.tsx
@@ -0,0 +1,5 @@
+import { registry } from "shared-with-side-effect.tsx?tsr-shared=1";
+const SplitLoader = async () => {
+  registry.set('loaded', true);
+};
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect@shared.tsx
new file mode 100644
index 0000000000..f26c656fdd
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/shared-with-side-effect@shared.tsx
@@ -0,0 +1,2 @@
+const registry = new Map();
+export { registry };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/undefined-literals@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/undefined-literals@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/useStateDestructure.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/useStateDestructure.tsx
index 8f79e69bf0..d0de09bf8b 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/useStateDestructure.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/useStateDestructure.tsx
@@ -188,7 +188,7 @@ export default function VersionIndex() {
         </div>
         <div className="flex items-center gap-2 flex-wrap justify-center">
           <a
-            href={`https://github.com/tanstack/tanstack.com`}
+            href={`https://github.com/TanStack/tanstack.com`}
             className={`flex items-center gap-2 py-2 px-4 bg-cyan-700 rounded text-white uppercase font-extrabold`}
           >
             <FaGithub /> View TanStack.com Source
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/useStateDestructure@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/useStateDestructure@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/using@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/2-components-combined-loader-separate/using@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/arrow-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/arrow-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/boolean-null-literals@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/boolean-null-literals@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/chinese@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/chinese@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/circular-reference-arrow-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/circular-reference-arrow-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/circular-reference-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/circular-reference-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/conditional-properties@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/conditional-properties@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-multiple.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-multiple.tsx
new file mode 100644
index 0000000000..8b823166e4
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-multiple.tsx
@@ -0,0 +1,15 @@
+const $$splitComponentImporter = () => import('destructured-export-multiple.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const getConfig = () => ({
+  baseUrl: 'https://api.example.com',
+  timeout: 5000
+});
+export const {
+  baseUrl,
+  timeout
+} = getConfig();
+export const [first, second] = [1, 2];
+export const Route = createFileRoute('/about')({
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-multiple@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-multiple@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..9441b5a689
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-multiple@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,8 @@
+import { baseUrl, timeout } from "destructured-export-multiple.tsx";
+function AboutComponent() {
+  return <div>
+      <p>Base URL: {baseUrl}</p>
+      <p>Timeout: {timeout}</p>
+    </div>;
+}
+export { AboutComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-multiple@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-multiple@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-multiple@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-multiple@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-nested.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-nested.tsx
new file mode 100644
index 0000000000..5920a891c0
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-nested.tsx
@@ -0,0 +1,19 @@
+const $$splitComponentImporter = () => import('destructured-export-nested.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+const getConfig = () => ({
+  api: {
+    baseUrl: 'https://api.example.com'
+  },
+  timeout: 5000,
+  extra: 'data'
+});
+export const {
+  api: {
+    baseUrl
+  },
+  ...rest
+} = getConfig();
+export const Route = createFileRoute('/about')({
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-nested@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-nested@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..8ba46e33e1
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-nested@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,7 @@
+import { baseUrl } from "destructured-export-nested.tsx";
+function AboutComponent() {
+  return <div>
+      <p>Base URL: {baseUrl}</p>
+    </div>;
+}
+export { AboutComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-nested@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-nested@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-nested@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export-nested@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export.tsx
new file mode 100644
index 0000000000..f573764824
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export.tsx
@@ -0,0 +1,17 @@
+const $$splitComponentImporter = () => import('destructured-export.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export function getObjectCallback() {
+  return {
+    getObject: () => ({
+      constA: 10,
+      constB: 5
+    })
+  };
+}
+export const {
+  getObject
+} = getObjectCallback();
+export const Route = createFileRoute('/about')({
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..f58942d5af
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,14 @@
+export function getObjectCallback() {
+  return {
+    getObject: () => ({
+      constA: 10,
+      constB: 5
+    })
+  };
+}
+function AboutComponent() {
+  return <div className="p-2">
+      <h3>About</h3>
+    </div>;
+}
+export { AboutComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export@errorComponent.tsx
new file mode 100644
index 0000000000..45fb19eecd
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export@errorComponent.tsx
@@ -0,0 +1,8 @@
+export function getObjectCallback() {
+  return {
+    getObject: () => ({
+      constA: 10,
+      constB: 5
+    })
+  };
+}
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-export@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-react-memo-imported-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-react-memo-imported-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-route-options-defaults.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-route-options-defaults.tsx
new file mode 100644
index 0000000000..6cac408c56
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-route-options-defaults.tsx
@@ -0,0 +1,9 @@
+const $$splitLoaderImporter = () => import('destructured-route-options-defaults.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+const $$splitComponentImporter = () => import('destructured-route-options-defaults.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/about')({
+  component: lazyRouteComponent($$splitComponentImporter, 'component'),
+  loader: lazyFn($$splitLoaderImporter, 'loader')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-route-options-defaults@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-route-options-defaults@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..2f8ef91c49
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-route-options-defaults@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,23 @@
+function defaultLoader() {
+  return {
+    message: 'default'
+  };
+}
+function DefaultComponent() {
+  return <div>Default</div>;
+}
+const createBits = () => ({
+  component: ActualComponent,
+  loader: () => ({
+    message: 'hello'
+  })
+});
+const {
+  component: MyComponent = DefaultComponent,
+  loader = defaultLoader
+} = createBits();
+function ActualComponent() {
+  return <div>About</div>;
+}
+export { loader };
+export { MyComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-route-options-defaults@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-route-options-defaults@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-route-options-defaults@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructured-route-options-defaults@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructuring@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/destructuring@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/directive-prologue.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/directive-prologue.tsx
new file mode 100644
index 0000000000..178bec9bf7
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/directive-prologue.tsx
@@ -0,0 +1,8 @@
+'use client';
+
+const $$splitComponentImporter = () => import('directive-prologue.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/directive')({
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/directive-prologue@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/directive-prologue@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..ce7cd5e5ee
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/directive-prologue@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,6 @@
+'use client';
+
+const SplitComponent = () => {
+  return <div>directive preserved</div>;
+};
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/directive-prologue@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/directive-prologue@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/directive-prologue@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/directive-prologue@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/explicit-undefined-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/explicit-undefined-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/export-default-component-and-normal-notFound@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/export-default-component-and-normal-notFound@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/export-default-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/export-default-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/function-as-parameter@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/function-as-parameter@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/function-declaration@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/function-declaration@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/importAttribute@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/importAttribute@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported-default-component-destructured-loader@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported-default-component-destructured-loader@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported-default-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported-default-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported-errorComponent@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported-errorComponent@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported-notFoundComponent@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported-notFoundComponent@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported-pendingComponent@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported-pendingComponent@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/imported@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/inline@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/inline@component---loader---notFoundComponent---pendingComponent.tsx
index 4b18cae17a..58ccfb2903 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/inline@component---loader---notFoundComponent---pendingComponent.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/inline@component---loader---notFoundComponent---pendingComponent.tsx
@@ -7,7 +7,6 @@ const Button = (props: {
   return <button>{props.children}</button>;
 };
 import { Route } from "inline.tsx";
-Route.addChildren([]);
 import { test } from "inline.tsx";
 const SplitComponent = () => {
   return <div className="p-2">
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/inline@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/inline@errorComponent.tsx
index 4a822161e1..9236af6021 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/inline@errorComponent.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/inline@errorComponent.tsx
@@ -1,3 +1,2 @@
 import * as React from 'react';
-import { Route } from "inline.tsx";
-Route.addChildren([]);
\ No newline at end of file
+import { Route } from "inline.tsx";
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/inline@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/inline@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/random-number@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/random-number@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/react-memo-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/react-memo-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/react-memo-imported-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/react-memo-imported-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-export-component@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-export-component@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-const@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-const@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-destructured.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-destructured.tsx
new file mode 100644
index 0000000000..0e3175116f
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-destructured.tsx
@@ -0,0 +1,19 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const createBits = () => ({
+  component: AboutComponentImpl,
+  loader: () => ({
+    message: 'hello',
+  }),
+})
+
+export const { component: AboutComponent, loader } = createBits()
+
+function AboutComponentImpl() {
+  return <div>About</div>
+}
+
+export const Route = createFileRoute('/about')({
+  component: AboutComponent,
+  loader,
+})
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-destructured@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-destructured@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..43108700f5
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-destructured@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1 @@
+export { SplitLoader as loader };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-destructured@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-destructured@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-destructured@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-destructured@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-loader@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/retain-exports-loader@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class.tsx
new file mode 100644
index 0000000000..48afc3f070
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class.tsx
@@ -0,0 +1,18 @@
+const $$splitComponentImporter = () => import('shared-class.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-class.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+class DataStore {
+  data = new Map();
+  get(k: string) {
+    return this.data.get(k);
+  }
+  set(k: string, v: unknown) {
+    this.data.set(k, v);
+  }
+}
+export const Route = createFileRoute('/store')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..10675b99ed
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,16 @@
+class DataStore {
+  data = new Map();
+  get(k: string) {
+    return this.data.get(k);
+  }
+  set(k: string, v: unknown) {
+    this.data.set(k, v);
+  }
+}
+const store = new DataStore();
+const SplitLoader = async () => {
+  store.set('items', await fetch('/api'));
+};
+export { SplitLoader as loader };
+const SplitComponent = () => <div>{store.get('items')}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class@errorComponent.tsx
new file mode 100644
index 0000000000..0a50638c6a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class@errorComponent.tsx
@@ -0,0 +1,9 @@
+class DataStore {
+  data = new Map();
+  get(k: string) {
+    return this.data.get(k);
+  }
+  set(k: string, v: unknown) {
+    this.data.set(k, v);
+  }
+}
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-class@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured-export.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured-export.tsx
new file mode 100644
index 0000000000..73f1b54389
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured-export.tsx
@@ -0,0 +1,19 @@
+const $$splitComponentImporter = () => import('shared-destructured-export.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-destructured-export.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const {
+  apiUrl,
+  timeout
+} = getConfig();
+export const Route = createFileRoute('/config')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
+function getConfig() {
+  return {
+    apiUrl: '/api',
+    timeout: 5000
+  };
+}
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured-export@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured-export@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..d48accf910
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured-export@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,5 @@
+import { apiUrl, timeout } from "shared-destructured-export.tsx";
+const SplitLoader = async () => fetch(apiUrl);
+export { SplitLoader as loader };
+const SplitComponent = () => <div>Timeout: {timeout}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured-export@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured-export@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured-export@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured-export@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured.tsx
new file mode 100644
index 0000000000..fbc4272c3e
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-destructured.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-destructured.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/config')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..e92f7dd7f8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,14 @@
+const {
+  apiUrl,
+  timeout
+} = getConfig();
+function getConfig() {
+  return {
+    apiUrl: '/api',
+    timeout: 5000
+  };
+}
+const SplitLoader = async () => fetch(apiUrl);
+export { SplitLoader as loader };
+const SplitComponent = () => <div>Timeout: {timeout}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-destructured@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-exported.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-exported.tsx
new file mode 100644
index 0000000000..76a5d29dc3
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-exported.tsx
@@ -0,0 +1,13 @@
+const $$splitComponentImporter = () => import('shared-exported.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-exported.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const queryOptions = {
+  staleTime: 5000,
+  gcTime: 10000
+};
+export const Route = createFileRoute('/query')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-exported@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-exported@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..f77f81cbdb
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-exported@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,9 @@
+import { queryOptions } from "shared-exported.tsx";
+const SplitLoader = async () => {
+  return {
+    staleTime: queryOptions.staleTime
+  };
+};
+export { SplitLoader as loader };
+const SplitComponent = () => <div>GC: {queryOptions.gcTime}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-exported@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-exported@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-exported@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-exported@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-function.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-function.tsx
new file mode 100644
index 0000000000..8a921d9640
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-function.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-function.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-function.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/cached')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-function@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-function@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..cfe519f47a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-function@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,14 @@
+const cache = new Map();
+function getCached(key: string) {
+  return cache.get(key);
+}
+function setCached(key: string, val: unknown) {
+  cache.set(key, val);
+}
+const SplitLoader = async () => {
+  setCached('data', await fetch('/api').then(r => r.json()));
+  return getCached('data');
+};
+export { SplitLoader as loader };
+const SplitComponent = () => <div>{JSON.stringify(getCached('data'))}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-function@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-function@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-imported-binding.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-imported-binding.tsx
new file mode 100644
index 0000000000..feb46cd789
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-imported-binding.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-imported-binding.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-imported-binding.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/imported')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-imported-binding@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-imported-binding@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..409e8d4023
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-imported-binding@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,5 @@
+import { sharedUtil } from '../utils';
+const SplitLoader = async () => sharedUtil('load');
+export { SplitLoader as loader };
+const SplitComponent = () => <div>{sharedUtil('render')}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-imported-binding@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-imported-binding@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-imported-binding@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-imported-binding@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-indirect-ref.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-indirect-ref.tsx
new file mode 100644
index 0000000000..4275e17e58
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-indirect-ref.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-indirect-ref.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-indirect-ref.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/shared-indirect')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-indirect-ref@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-indirect-ref@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..090f3b5c73
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-indirect-ref@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,19 @@
+const state = {
+  count: 0
+};
+function getCount() {
+  return state.count;
+}
+function SharedComponent() {
+  return <div>
+      {getCount()} - {state.count}
+    </div>;
+}
+const SplitLoader = () => {
+  state.count++;
+  return {
+    count: getCount()
+  };
+};
+export { SplitLoader as loader };
+export { SharedComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-indirect-ref@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-indirect-ref@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-indirect-ref@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-indirect-ref@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-jsx-component-ref.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-jsx-component-ref.tsx
new file mode 100644
index 0000000000..130c7ce120
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-jsx-component-ref.tsx
@@ -0,0 +1,10 @@
+const $$splitComponentImporter = () => import('shared-jsx-component-ref.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-jsx-component-ref.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+// @ts-nocheck
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/jsx')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-jsx-component-ref@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-jsx-component-ref@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..c5fd18664e
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-jsx-component-ref@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,9 @@
+// @ts-nocheck
+
+const shared = 1;
+function SharedComponent() {
+  return <div>{shared}</div>;
+}
+const SplitLoader = () => shared;
+export { SplitLoader as loader };
+export { SharedComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-jsx-component-ref@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-jsx-component-ref@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-jsx-component-ref@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-jsx-component-ref@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-none.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-none.tsx
new file mode 100644
index 0000000000..eac0f9ab0a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-none.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-none.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-none.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/clean')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-none@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-none@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..f9f52ba6be
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-none@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,8 @@
+const loaderHelper = () => fetch('/api');
+const ComponentHelper = () => <span>helper</span>;
+const SplitLoader = async () => loaderHelper();
+export { SplitLoader as loader };
+const SplitComponent = () => <div>
+      <ComponentHelper />
+    </div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-none@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-none@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-none@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-none@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-referencing-route.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-referencing-route.tsx
new file mode 100644
index 0000000000..9aebb45a95
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-referencing-route.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-referencing-route.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-referencing-route.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/about')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-referencing-route@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-referencing-route@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..9bcd130ea8
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-referencing-route@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,17 @@
+const HEADER = 'Page';
+function usePageTitle() {
+  return `${HEADER} - ${Route.fullPath}`;
+}
+import { Route } from "shared-referencing-route.tsx";
+const SplitLoader = async () => {
+  const title = usePageTitle();
+  return {
+    title
+  };
+};
+export { SplitLoader as loader };
+const SplitComponent = () => {
+  const title = usePageTitle();
+  return <div>{title}</div>;
+};
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-referencing-route@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-referencing-route@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-referencing-route@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-referencing-route@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-transitive.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-transitive.tsx
new file mode 100644
index 0000000000..67b0631b8e
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-transitive.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-transitive.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-transitive.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/api')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-transitive@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-transitive@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..662d7fd7aa
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-transitive@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,12 @@
+const BASE_URL = 'https://api.example.com';
+const config = {
+  url: BASE_URL,
+  timeout: 5000
+};
+const fetcher = (path: string) => fetch(`${config.url}${path}`);
+const SplitLoader = async () => {
+  return fetcher('/data');
+};
+export { SplitLoader as loader };
+const SplitComponent = () => <div>Timeout: {config.timeout}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-transitive@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-transitive@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-transitive@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-transitive@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-variable.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-variable.tsx
new file mode 100644
index 0000000000..48cdad100e
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-variable.tsx
@@ -0,0 +1,9 @@
+const $$splitComponentImporter = () => import('shared-variable.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-variable.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+export const Route = createFileRoute('/todos')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-variable@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-variable@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..daca782a6f
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-variable@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,13 @@
+const collection = {
+  name: 'todos',
+  preload: async () => {}
+};
+const SplitLoader = async () => {
+  await collection.preload();
+  return {
+    data: 'loaded'
+  };
+};
+export { SplitLoader as loader };
+const SplitComponent = () => <div>{collection.name}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-variable@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-variable@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-variable@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-variable@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-with-side-effect.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-with-side-effect.tsx
new file mode 100644
index 0000000000..c322746737
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-with-side-effect.tsx
@@ -0,0 +1,10 @@
+const $$splitComponentImporter = () => import('shared-with-side-effect.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyRouteComponent } from '@tanstack/react-router';
+const $$splitLoaderImporter = () => import('shared-with-side-effect.tsx?tsr-split=component---loader---notFoundComponent---pendingComponent');
+import { lazyFn } from '@tanstack/react-router';
+import { createFileRoute } from '@tanstack/react-router';
+console.log('registry created');
+export const Route = createFileRoute('/fx')({
+  loader: lazyFn($$splitLoaderImporter, 'loader'),
+  component: lazyRouteComponent($$splitComponentImporter, 'component')
+});
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-with-side-effect@component---loader---notFoundComponent---pendingComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-with-side-effect@component---loader---notFoundComponent---pendingComponent.tsx
new file mode 100644
index 0000000000..6c77f8b857
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-with-side-effect@component---loader---notFoundComponent---pendingComponent.tsx
@@ -0,0 +1,7 @@
+const registry = new Map();
+const SplitLoader = async () => {
+  registry.set('loaded', true);
+};
+export { SplitLoader as loader };
+const SplitComponent = () => <div>{registry.size}</div>;
+export { SplitComponent as component };
\ No newline at end of file
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-with-side-effect@errorComponent.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-with-side-effect@errorComponent.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-with-side-effect@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/shared-with-side-effect@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/undefined-literals@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/undefined-literals@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/useStateDestructure.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/useStateDestructure.tsx
index 8f79e69bf0..d0de09bf8b 100644
--- a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/useStateDestructure.tsx
+++ b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/useStateDestructure.tsx
@@ -188,7 +188,7 @@ export default function VersionIndex() {
         </div>
         <div className="flex items-center gap-2 flex-wrap justify-center">
           <a
-            href={`https://github.com/tanstack/tanstack.com`}
+            href={`https://github.com/TanStack/tanstack.com`}
             className={`flex items-center gap-2 py-2 px-4 bg-cyan-700 rounded text-white uppercase font-extrabold`}
           >
             <FaGithub /> View TanStack.com Source
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/useStateDestructure@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/useStateDestructure@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/using@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/react/3-all-combined-errorComponent-separate/using@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/solid/1-default/arrow-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/solid/1-default/arrow-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/solid/2-components-combined-loader-separate/arrow-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/solid/2-components-combined-loader-separate/arrow-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/snapshots/solid/3-all-combined-errorComponent-separate/arrow-function@shared.tsx b/packages/router-plugin/tests/code-splitter/snapshots/solid/3-all-combined-errorComponent-separate/arrow-function@shared.tsx
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/destructured-export-multiple.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/destructured-export-multiple.tsx
new file mode 100644
index 0000000000..aa87237670
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/destructured-export-multiple.tsx
@@ -0,0 +1,23 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+export const getConfig = () => ({
+  baseUrl: 'https://api.example.com',
+  timeout: 5000,
+})
+
+export const { baseUrl, timeout } = getConfig()
+
+export const [first, second] = [1, 2]
+
+export const Route = createFileRoute('/about')({
+  component: AboutComponent,
+})
+
+function AboutComponent() {
+  return (
+    <div>
+      <p>Base URL: {baseUrl}</p>
+      <p>Timeout: {timeout}</p>
+    </div>
+  )
+}
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/destructured-export-nested.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/destructured-export-nested.tsx
new file mode 100644
index 0000000000..1fa4121a7a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/destructured-export-nested.tsx
@@ -0,0 +1,26 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const getConfig = () => ({
+  api: {
+    baseUrl: 'https://api.example.com',
+  },
+  timeout: 5000,
+  extra: 'data',
+})
+
+export const {
+  api: { baseUrl },
+  ...rest
+} = getConfig()
+
+export const Route = createFileRoute('/about')({
+  component: AboutComponent,
+})
+
+function AboutComponent() {
+  return (
+    <div>
+      <p>Base URL: {baseUrl}</p>
+    </div>
+  )
+}
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/destructured-export.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/destructured-export.tsx
new file mode 100644
index 0000000000..525bb4e28d
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/destructured-export.tsx
@@ -0,0 +1,19 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+export function getObjectCallback() {
+  return { getObject: () => ({ constA: 10, constB: 5 }) }
+}
+
+export const { getObject } = getObjectCallback()
+
+export const Route = createFileRoute('/about')({
+  component: AboutComponent,
+})
+
+function AboutComponent() {
+  return (
+    <div className="p-2">
+      <h3>About</h3>
+    </div>
+  )
+}
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/destructured-route-options-defaults.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/destructured-route-options-defaults.tsx
new file mode 100644
index 0000000000..1cb5673aec
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/destructured-route-options-defaults.tsx
@@ -0,0 +1,28 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+function defaultLoader() {
+  return { message: 'default' }
+}
+
+function DefaultComponent() {
+  return <div>Default</div>
+}
+
+const createBits = () => ({
+  component: ActualComponent,
+  loader: () => ({
+    message: 'hello',
+  }),
+})
+
+const { component: MyComponent = DefaultComponent, loader = defaultLoader } =
+  createBits()
+
+function ActualComponent() {
+  return <div>About</div>
+}
+
+export const Route = createFileRoute('/about')({
+  component: MyComponent,
+  loader,
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/directive-prologue.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/directive-prologue.tsx
new file mode 100644
index 0000000000..59cad1d3da
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/directive-prologue.tsx
@@ -0,0 +1,9 @@
+'use client'
+
+import { createFileRoute } from '@tanstack/react-router'
+
+export const Route = createFileRoute('/directive')({
+  component: () => {
+    return <div>directive preserved</div>
+  },
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/retain-exports-destructured.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/retain-exports-destructured.tsx
new file mode 100644
index 0000000000..0e3175116f
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/retain-exports-destructured.tsx
@@ -0,0 +1,19 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const createBits = () => ({
+  component: AboutComponentImpl,
+  loader: () => ({
+    message: 'hello',
+  }),
+})
+
+export const { component: AboutComponent, loader } = createBits()
+
+function AboutComponentImpl() {
+  return <div>About</div>
+}
+
+export const Route = createFileRoute('/about')({
+  component: AboutComponent,
+  loader,
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-class.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-class.tsx
new file mode 100644
index 0000000000..87d2e15a63
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-class.tsx
@@ -0,0 +1,19 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+class DataStore {
+  data = new Map()
+  get(k: string) {
+    return this.data.get(k)
+  }
+  set(k: string, v: unknown) {
+    this.data.set(k, v)
+  }
+}
+const store = new DataStore()
+
+export const Route = createFileRoute('/store')({
+  loader: async () => {
+    store.set('items', await fetch('/api'))
+  },
+  component: () => <div>{store.get('items')}</div>,
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-destructured-export.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-destructured-export.tsx
new file mode 100644
index 0000000000..3004c667e3
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-destructured-export.tsx
@@ -0,0 +1,12 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+export const { apiUrl, timeout } = getConfig()
+
+export const Route = createFileRoute('/config')({
+  loader: async () => fetch(apiUrl),
+  component: () => <div>Timeout: {timeout}</div>,
+})
+
+function getConfig() {
+  return { apiUrl: '/api', timeout: 5000 }
+}
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-destructured.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-destructured.tsx
new file mode 100644
index 0000000000..6f45457189
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-destructured.tsx
@@ -0,0 +1,12 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const { apiUrl, timeout } = getConfig()
+
+export const Route = createFileRoute('/config')({
+  loader: async () => fetch(apiUrl),
+  component: () => <div>Timeout: {timeout}</div>,
+})
+
+function getConfig() {
+  return { apiUrl: '/api', timeout: 5000 }
+}
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-exported.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-exported.tsx
new file mode 100644
index 0000000000..acfd046964
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-exported.tsx
@@ -0,0 +1,10 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+export const queryOptions = { staleTime: 5000, gcTime: 10000 }
+
+export const Route = createFileRoute('/query')({
+  loader: async () => {
+    return { staleTime: queryOptions.staleTime }
+  },
+  component: () => <div>GC: {queryOptions.gcTime}</div>,
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-function.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-function.tsx
new file mode 100644
index 0000000000..45abe16e66
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-function.tsx
@@ -0,0 +1,17 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const cache = new Map()
+function getCached(key: string) {
+  return cache.get(key)
+}
+function setCached(key: string, val: unknown) {
+  cache.set(key, val)
+}
+
+export const Route = createFileRoute('/cached')({
+  loader: async () => {
+    setCached('data', await fetch('/api').then((r) => r.json()))
+    return getCached('data')
+  },
+  component: () => <div>{JSON.stringify(getCached('data'))}</div>,
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-imported-binding.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-imported-binding.tsx
new file mode 100644
index 0000000000..e46da7cd6a
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-imported-binding.tsx
@@ -0,0 +1,7 @@
+import { createFileRoute } from '@tanstack/react-router'
+import { sharedUtil } from '../utils'
+
+export const Route = createFileRoute('/imported')({
+  loader: async () => sharedUtil('load'),
+  component: () => <div>{sharedUtil('render')}</div>,
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-indirect-ref.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-indirect-ref.tsx
new file mode 100644
index 0000000000..f4f50318b7
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-indirect-ref.tsx
@@ -0,0 +1,23 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const state = { count: 0 }
+
+function getCount() {
+  return state.count
+}
+
+export const Route = createFileRoute('/shared-indirect')({
+  loader: () => {
+    state.count++
+    return { count: getCount() }
+  },
+  component: SharedComponent,
+})
+
+function SharedComponent() {
+  return (
+    <div>
+      {getCount()} - {state.count}
+    </div>
+  )
+}
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-jsx-component-ref.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-jsx-component-ref.tsx
new file mode 100644
index 0000000000..0eb8d4f166
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-jsx-component-ref.tsx
@@ -0,0 +1,13 @@
+// @ts-nocheck
+import { createFileRoute } from '@tanstack/react-router'
+
+const shared = 1
+
+function SharedComponent() {
+  return <div>{shared}</div>
+}
+
+export const Route = createFileRoute('/jsx')({
+  loader: () => shared,
+  component: SharedComponent,
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-none.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-none.tsx
new file mode 100644
index 0000000000..1b2c2c1244
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-none.tsx
@@ -0,0 +1,13 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const loaderHelper = () => fetch('/api')
+const ComponentHelper = () => <span>helper</span>
+
+export const Route = createFileRoute('/clean')({
+  loader: async () => loaderHelper(),
+  component: () => (
+    <div>
+      <ComponentHelper />
+    </div>
+  ),
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-referencing-route.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-referencing-route.tsx
new file mode 100644
index 0000000000..5bfbd85229
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-referencing-route.tsx
@@ -0,0 +1,18 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const HEADER = 'Page'
+
+function usePageTitle() {
+  return `${HEADER} - ${Route.fullPath}`
+}
+
+export const Route = createFileRoute('/about')({
+  loader: async () => {
+    const title = usePageTitle()
+    return { title }
+  },
+  component: () => {
+    const title = usePageTitle()
+    return <div>{title}</div>
+  },
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-transitive.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-transitive.tsx
new file mode 100644
index 0000000000..e1471305cb
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-transitive.tsx
@@ -0,0 +1,12 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const BASE_URL = 'https://api.example.com'
+const config = { url: BASE_URL, timeout: 5000 }
+const fetcher = (path: string) => fetch(`${config.url}${path}`)
+
+export const Route = createFileRoute('/api')({
+  loader: async () => {
+    return fetcher('/data')
+  },
+  component: () => <div>Timeout: {config.timeout}</div>,
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-variable.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-variable.tsx
new file mode 100644
index 0000000000..8cd7224e02
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-variable.tsx
@@ -0,0 +1,11 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const collection = { name: 'todos', preload: async () => {} }
+
+export const Route = createFileRoute('/todos')({
+  loader: async () => {
+    await collection.preload()
+    return { data: 'loaded' }
+  },
+  component: () => <div>{collection.name}</div>,
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/shared-with-side-effect.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/shared-with-side-effect.tsx
new file mode 100644
index 0000000000..b926dfe889
--- /dev/null
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/shared-with-side-effect.tsx
@@ -0,0 +1,11 @@
+import { createFileRoute } from '@tanstack/react-router'
+
+const registry = new Map()
+console.log('registry created')
+
+export const Route = createFileRoute('/fx')({
+  loader: async () => {
+    registry.set('loaded', true)
+  },
+  component: () => <div>{registry.size}</div>,
+})
diff --git a/packages/router-plugin/tests/code-splitter/test-files/react/useStateDestructure.tsx b/packages/router-plugin/tests/code-splitter/test-files/react/useStateDestructure.tsx
index 8f79e69bf0..d0de09bf8b 100644
--- a/packages/router-plugin/tests/code-splitter/test-files/react/useStateDestructure.tsx
+++ b/packages/router-plugin/tests/code-splitter/test-files/react/useStateDestructure.tsx
@@ -188,7 +188,7 @@ export default function VersionIndex() {
         </div>
         <div className="flex items-center gap-2 flex-wrap justify-center">
           <a
-            href={`https://github.com/tanstack/tanstack.com`}
+            href={`https://github.com/TanStack/tanstack.com`}
             className={`flex items-center gap-2 py-2 px-4 bg-cyan-700 rounded text-white uppercase font-extrabold`}
           >
             <FaGithub /> View TanStack.com Source
diff --git a/packages/router-plugin/tests/shared-bindings-helpers.test.ts b/packages/router-plugin/tests/shared-bindings-helpers.test.ts
new file mode 100644
index 0000000000..3198c15fb9
--- /dev/null
+++ b/packages/router-plugin/tests/shared-bindings-helpers.test.ts
@@ -0,0 +1,1040 @@
+import { describe, expect, it } from 'vitest'
+import * as t from '@babel/types'
+import { parseAst } from '@tanstack/router-utils'
+
+import {
+  addSharedSearchParamToFilename,
+  buildDeclarationMap,
+  buildDependencyGraph,
+  collectIdentifiersFromNode,
+  collectLocalBindingsFromStatement,
+  collectModuleLevelRefsFromNode,
+  computeSharedBindings,
+  expandDestructuredDeclarations,
+  expandTransitively,
+  removeBindingsDependingOnRoute,
+} from '../src/core/code-splitter/compilers'
+import { defaultCodeSplitGroupings } from '../src/core/constants'
+import type { CodeSplitGroupings } from '../src/core/constants'
+
+// ─── Test helpers ──────────────────────────────────────────
+
+function parse(code: string) {
+  return parseAst({ code })
+}
+
+function collectBindings(code: string): Set<string> {
+  const ast = parse(code)
+  const bindings = new Set<string>()
+  for (const node of ast.program.body) {
+    collectLocalBindingsFromStatement(node, bindings)
+  }
+  return bindings
+}
+
+/** Build a dep graph from code for convenience */
+function graphFromCode(code: string) {
+  const ast = parse(code)
+  const locals = new Set<string>()
+  for (const node of ast.program.body) {
+    collectLocalBindingsFromStatement(node, locals)
+  }
+  const declMap = buildDeclarationMap(ast)
+  return {
+    ast,
+    locals,
+    declMap,
+    depGraph: buildDependencyGraph(declMap, locals),
+  }
+}
+
+// ─── addSharedSearchParamToFilename ────────────────────────
+
+describe('addSharedSearchParamToFilename', () => {
+  it('should append tsr-shared=1 to bare filename', () => {
+    expect(addSharedSearchParamToFilename('src/routes/index.tsx')).toBe(
+      'src/routes/index.tsx?tsr-shared=1',
+    )
+  })
+
+  it('should strip existing query params', () => {
+    expect(
+      addSharedSearchParamToFilename(
+        'src/routes/index.tsx?tsr-split=component',
+      ),
+    ).toBe('src/routes/index.tsx?tsr-shared=1')
+  })
+})
+
+// ─── collectIdentifiersFromNode ───────────────────────────
+
+describe('collectIdentifiersFromNode', () => {
+  it('should collect from a simple identifier', () => {
+    const ast = parse('const x = foo')
+    const decl = ast.program.body[0] as t.VariableDeclaration
+    const init = decl.declarations[0]!.init!
+    expect(collectIdentifiersFromNode(init)).toEqual(new Set(['foo']))
+  })
+
+  it('should collect from a binary expression', () => {
+    const ast = parse('const x = a + b')
+    const decl = ast.program.body[0] as t.VariableDeclaration
+    const init = decl.declarations[0]!.init!
+    expect(collectIdentifiersFromNode(init)).toEqual(new Set(['a', 'b']))
+  })
+
+  it('should ignore object literal keys', () => {
+    const ast = parse('const x = { key: value }')
+    const decl = ast.program.body[0] as t.VariableDeclaration
+    const init = decl.declarations[0]!.init!
+    const ids = collectIdentifiersFromNode(init)
+    expect(ids).toContain('value')
+    expect(ids).not.toContain('key')
+  })
+
+  it('should ignore member expression properties', () => {
+    const ast = parse('const x = obj.prop + obj[dynamic]')
+    const decl = ast.program.body[0] as t.VariableDeclaration
+    const init = decl.declarations[0]!.init!
+    const ids = collectIdentifiersFromNode(init)
+    expect(ids).toContain('obj')
+    expect(ids).toContain('dynamic')
+    expect(ids).not.toContain('prop')
+  })
+
+  it('should collect from a call expression', () => {
+    const ast = parse('const x = foo(bar, baz)')
+    const decl = ast.program.body[0] as t.VariableDeclaration
+    const init = decl.declarations[0]!.init!
+    expect(collectIdentifiersFromNode(init)).toEqual(
+      new Set(['foo', 'bar', 'baz']),
+    )
+  })
+
+  it('should collect from arrow function body', () => {
+    const ast = parse('const x = () => a + b')
+    const decl = ast.program.body[0] as t.VariableDeclaration
+    const init = decl.declarations[0]!.init!
+    const ids = collectIdentifiersFromNode(init)
+    expect(ids).toContain('a')
+    expect(ids).toContain('b')
+  })
+
+  it('should collect from member expressions', () => {
+    const ast = parse('const x = obj.prop')
+    const decl = ast.program.body[0] as t.VariableDeclaration
+    const init = decl.declarations[0]!.init!
+    const ids = collectIdentifiersFromNode(init)
+    expect(ids).toContain('obj')
+    // property name is not a referenced identifier
+    expect(ids).not.toContain('prop')
+  })
+
+  it('should collect from nested structures', () => {
+    const ast = parse('const x = { key: fn(val) }')
+    const decl = ast.program.body[0] as t.VariableDeclaration
+    const init = decl.declarations[0]!.init!
+    const ids = collectIdentifiersFromNode(init)
+    expect(ids).toContain('fn')
+    expect(ids).toContain('val')
+    // object literal keys are not referenced identifiers
+    expect(ids).not.toContain('key')
+  })
+
+  it('should return empty set for a numeric literal', () => {
+    const ast = parse('const x = 42')
+    const decl = ast.program.body[0] as t.VariableDeclaration
+    const init = decl.declarations[0]!.init!
+    expect(collectIdentifiersFromNode(init).size).toBe(0)
+  })
+
+  it('should collect from function declaration body', () => {
+    const ast = parse('function foo() { return bar + baz }')
+    const fn = ast.program.body[0]!
+    const ids = collectIdentifiersFromNode(fn)
+    // function name is a binding, not a reference
+    expect(ids).not.toContain('foo')
+    expect(ids).toContain('bar')
+    expect(ids).toContain('baz')
+  })
+})
+
+// ─── collectLocalBindingsFromStatement ─────────────────────
+
+describe('collectLocalBindingsFromStatement', () => {
+  it('should collect from const declaration', () => {
+    expect(collectBindings('const x = 1')).toEqual(new Set(['x']))
+  })
+
+  it('should collect from let declaration', () => {
+    expect(collectBindings('let x = 1')).toEqual(new Set(['x']))
+  })
+
+  it('should collect from multiple declarators', () => {
+    expect(collectBindings('const x = 1, y = 2')).toEqual(new Set(['x', 'y']))
+  })
+
+  it('should collect from function declaration', () => {
+    expect(collectBindings('function foo() {}')).toEqual(new Set(['foo']))
+  })
+
+  it('should collect from class declaration', () => {
+    expect(collectBindings('class Foo {}')).toEqual(new Set(['Foo']))
+  })
+
+  it('should collect from exported variable declaration', () => {
+    expect(collectBindings('export const x = 1')).toEqual(new Set(['x']))
+  })
+
+  it('should collect from exported function declaration', () => {
+    expect(collectBindings('export function foo() {}')).toEqual(
+      new Set(['foo']),
+    )
+  })
+
+  it('should collect from exported class declaration', () => {
+    expect(collectBindings('export class Foo {}')).toEqual(new Set(['Foo']))
+  })
+
+  it('should collect from object destructuring', () => {
+    expect(collectBindings('const { a, b } = obj')).toEqual(new Set(['a', 'b']))
+  })
+
+  it('should collect from nested object destructuring', () => {
+    expect(collectBindings('const { a: { b, c } } = obj')).toEqual(
+      new Set(['b', 'c']),
+    )
+  })
+
+  it('should collect from array destructuring', () => {
+    expect(collectBindings('const [a, b] = arr')).toEqual(new Set(['a', 'b']))
+  })
+
+  it('should collect from destructuring with defaults', () => {
+    expect(collectBindings('const { a = 1, b = 2 } = obj')).toEqual(
+      new Set(['a', 'b']),
+    )
+  })
+
+  it('should collect from destructuring with rest', () => {
+    expect(collectBindings('const { a, ...rest } = obj')).toEqual(
+      new Set(['a', 'rest']),
+    )
+  })
+
+  it('should collect from exported destructuring', () => {
+    expect(collectBindings('export const { a, b } = fn()')).toEqual(
+      new Set(['a', 'b']),
+    )
+  })
+
+  it('should NOT collect from import declarations', () => {
+    expect(collectBindings("import { a } from './mod'")).toEqual(new Set())
+  })
+
+  it('should NOT collect from expression statements', () => {
+    expect(collectBindings('console.log("hello")')).toEqual(new Set())
+  })
+
+  it('should collect from renamed destructuring', () => {
+    expect(collectBindings('const { a: renamedA } = obj')).toEqual(
+      new Set(['renamedA']),
+    )
+  })
+
+  it('should collect from multiple statements', () => {
+    const code = `
+const x = 1
+function foo() {}
+class Bar {}
+`
+    expect(collectBindings(code)).toEqual(new Set(['x', 'foo', 'Bar']))
+  })
+})
+
+// ─── buildDeclarationMap ──────────────────────────────────
+
+describe('buildDeclarationMap', () => {
+  it('should map variable names to their declarator nodes', () => {
+    const ast = parse('const x = 1\nconst y = 2')
+    const map = buildDeclarationMap(ast)
+    expect(map.has('x')).toBe(true)
+    expect(map.has('y')).toBe(true)
+    expect(t.isVariableDeclarator(map.get('x'))).toBe(true)
+  })
+
+  it('should map function declarations', () => {
+    const ast = parse('function foo() {}')
+    const map = buildDeclarationMap(ast)
+    expect(map.has('foo')).toBe(true)
+    expect(t.isFunctionDeclaration(map.get('foo'))).toBe(true)
+  })
+
+  it('should map class declarations', () => {
+    const ast = parse('class Bar {}')
+    const map = buildDeclarationMap(ast)
+    expect(map.has('Bar')).toBe(true)
+    expect(t.isClassDeclaration(map.get('Bar'))).toBe(true)
+  })
+
+  it('should map exported declarations', () => {
+    const ast = parse('export const x = 1\nexport function foo() {}')
+    const map = buildDeclarationMap(ast)
+    expect(map.has('x')).toBe(true)
+    expect(map.has('foo')).toBe(true)
+  })
+
+  it('should map destructured bindings to same declarator', () => {
+    const ast = parse('const { a, b } = fn()')
+    const map = buildDeclarationMap(ast)
+    expect(map.has('a')).toBe(true)
+    expect(map.has('b')).toBe(true)
+    expect(map.get('a')).toBe(map.get('b'))
+  })
+
+  it('should not include imports', () => {
+    const ast = parse("import { x } from './mod'\nconst y = 1")
+    const map = buildDeclarationMap(ast)
+    expect(map.has('x')).toBe(false)
+    expect(map.has('y')).toBe(true)
+  })
+})
+
+// ─── buildDependencyGraph ─────────────────────────────────
+
+describe('buildDependencyGraph', () => {
+  it('should detect direct dependency', () => {
+    const { depGraph } = graphFromCode('const a = 1\nconst b = a + 1')
+    expect(depGraph.get('b')).toEqual(new Set(['a']))
+    expect(depGraph.get('a')).toEqual(new Set())
+  })
+
+  it('should not include self-references', () => {
+    const { depGraph } = graphFromCode('const a = () => a()')
+    expect(depGraph.get('a')!.has('a')).toBe(false)
+  })
+
+  it('should not include imported identifiers', () => {
+    const { depGraph } = graphFromCode(
+      "import { ext } from './mod'\nconst a = ext + 1",
+    )
+    // ext is not in locals, so not in deps
+    expect(depGraph.get('a')!.has('ext')).toBe(false)
+  })
+
+  it('should handle multiple deps', () => {
+    const { depGraph } = graphFromCode(
+      'const a = 1\nconst b = 2\nconst c = a + b',
+    )
+    expect(depGraph.get('c')).toEqual(new Set(['a', 'b']))
+  })
+
+  it('should handle function declaration deps', () => {
+    const { depGraph } = graphFromCode(
+      'const config = {}\nfunction init() { return config }',
+    )
+    expect(depGraph.get('init')).toEqual(new Set(['config']))
+  })
+
+  it('should handle chain deps (each link direct only)', () => {
+    const { depGraph } = graphFromCode('const a = 1\nconst b = a\nconst c = b')
+    expect(depGraph.get('c')).toEqual(new Set(['b']))
+    expect(depGraph.get('b')).toEqual(new Set(['a']))
+    expect(depGraph.get('a')).toEqual(new Set())
+  })
+})
+
+// ─── collectModuleLevelRefsFromNode ────────────────────────
+
+describe('collectModuleLevelRefsFromNode', () => {
+  it('should find identifier reference in expression', () => {
+    const code = 'const x = 1\nconst y = x + 1'
+    const ast = parse(code)
+    const locals = new Set(['x', 'y'])
+
+    const yDecl = ast.program.body[1] as t.VariableDeclaration
+    const valueNode = yDecl.declarations[0]!.init!
+
+    const refs = collectModuleLevelRefsFromNode(valueNode, locals)
+    expect(refs).toContain('x')
+    expect(refs).not.toContain('y')
+  })
+
+  it('should return empty set when no local bindings referenced', () => {
+    const code = "import { foo } from './mod'\nconst x = foo()"
+    const ast = parse(code)
+    const locals = new Set(['x']) // foo is imported, not local
+
+    const xDecl = ast.program.body[1] as t.VariableDeclaration
+    const valueNode = xDecl.declarations[0]!.init!
+
+    const refs = collectModuleLevelRefsFromNode(valueNode, locals)
+    expect(refs.size).toBe(0)
+  })
+
+  it('should find multiple references', () => {
+    const code = 'const a = 1\nconst b = 2\nconst c = a + b'
+    const ast = parse(code)
+    const locals = new Set(['a', 'b', 'c'])
+
+    const cDecl = ast.program.body[2] as t.VariableDeclaration
+    const valueNode = cDecl.declarations[0]!.init!
+
+    const refs = collectModuleLevelRefsFromNode(valueNode, locals)
+    expect(refs).toContain('a')
+    expect(refs).toContain('b')
+  })
+
+  it('should find refs inside function call arguments', () => {
+    const code = 'const config = {}\nconst result = process(config)'
+    const ast = parse(code)
+    const locals = new Set(['config', 'result'])
+
+    const resultDecl = ast.program.body[1] as t.VariableDeclaration
+    const valueNode = resultDecl.declarations[0]!.init!
+
+    const refs = collectModuleLevelRefsFromNode(valueNode, locals)
+    expect(refs).toContain('config')
+  })
+
+  it('should only return direct refs (not transitive)', () => {
+    const code = 'const a = 1\nconst b = a\nconst c = b'
+    const ast = parse(code)
+    const locals = new Set(['a', 'b', 'c'])
+
+    const cDecl = ast.program.body[2] as t.VariableDeclaration
+    const valueNode = cDecl.declarations[0]!.init!
+
+    const refs = collectModuleLevelRefsFromNode(valueNode, locals)
+    // Only b is directly referenced, NOT a (transitive expansion is separate)
+    expect(refs).toContain('b')
+    expect(refs).not.toContain('a')
+  })
+})
+
+// ─── expandTransitively ───────────────────────────────────
+
+describe('expandTransitively', () => {
+  it('should expand shared set with deps of shared bindings', () => {
+    const { depGraph } = graphFromCode('const dep = 1\nconst shared = dep + 1')
+    const shared = new Set(['shared'])
+
+    expandTransitively(shared, depGraph)
+    expect(shared).toContain('dep')
+  })
+
+  it('should handle multi-level transitive expansion', () => {
+    const { depGraph } = graphFromCode('const a = 1\nconst b = a\nconst c = b')
+    const shared = new Set(['c'])
+
+    expandTransitively(shared, depGraph)
+    expect(shared).toContain('b')
+    expect(shared).toContain('a')
+  })
+
+  it('should not expand bindings not in graph', () => {
+    const depGraph = new Map<string, Set<string>>()
+    depGraph.set('shared', new Set(['ext']))
+    // ext has no entry in graph
+    const shared = new Set(['shared'])
+
+    expandTransitively(shared, depGraph)
+    // ext added because it's a dep, even if it has no graph entry
+    expect(shared).toContain('ext')
+    expect(shared.size).toBe(2)
+  })
+
+  it('should not loop on circular references', () => {
+    const { depGraph } = graphFromCode(
+      'const a = () => b()\nconst b = () => a()',
+    )
+    const shared = new Set(['a'])
+
+    expandTransitively(shared, depGraph)
+    expect(shared).toContain('a')
+    expect(shared).toContain('b')
+  })
+
+  it('should leave shared untouched when binding has no deps', () => {
+    const depGraph = new Map<string, Set<string>>()
+    depGraph.set('x', new Set())
+    const shared = new Set(['x'])
+
+    expandTransitively(shared, depGraph)
+    expect(shared.size).toBe(1)
+    expect(shared).toContain('x')
+  })
+
+  it('should handle function declaration deps', () => {
+    const { depGraph } = graphFromCode(
+      'const config = {}\nfunction init() { return config }',
+    )
+    const shared = new Set(['init'])
+
+    expandTransitively(shared, depGraph)
+    expect(shared).toContain('config')
+  })
+
+  it('should handle empty graph', () => {
+    const depGraph = new Map<string, Set<string>>()
+    const shared = new Set(['x'])
+
+    expandTransitively(shared, depGraph)
+    expect(shared.size).toBe(1)
+  })
+})
+
+// ─── expandDestructuredDeclarations ───────────────────────
+
+describe('expandDestructuredDeclarations', () => {
+  it('should add all siblings when one destructured binding is shared', () => {
+    const ast = parse('const { a, b, c } = fn()')
+    const shared = new Set(['a'])
+
+    expandDestructuredDeclarations(ast, shared)
+    expect(shared).toContain('a')
+    expect(shared).toContain('b')
+    expect(shared).toContain('c')
+  })
+
+  it('should handle array destructuring', () => {
+    const ast = parse('const [x, y] = fn()')
+    const shared = new Set(['y'])
+
+    expandDestructuredDeclarations(ast, shared)
+    expect(shared).toContain('x')
+    expect(shared).toContain('y')
+  })
+
+  it('should not expand non-destructured declarations', () => {
+    const ast = parse('const a = 1\nconst b = 2')
+    const shared = new Set(['a'])
+
+    expandDestructuredDeclarations(ast, shared)
+    expect(shared).toContain('a')
+    expect(shared).not.toContain('b')
+  })
+
+  it('should handle exported destructured declarations', () => {
+    const ast = parse('export const { a, b } = fn()')
+    const shared = new Set(['b'])
+
+    expandDestructuredDeclarations(ast, shared)
+    expect(shared).toContain('a')
+    expect(shared).toContain('b')
+  })
+
+  it('should not touch declarations where no binding is shared', () => {
+    const ast = parse('const { a, b } = fn()\nconst { c, d } = other()')
+    const shared = new Set(['a'])
+
+    expandDestructuredDeclarations(ast, shared)
+    expect(shared).toContain('a')
+    expect(shared).toContain('b')
+    expect(shared).not.toContain('c')
+    expect(shared).not.toContain('d')
+  })
+
+  it('should handle nested destructuring', () => {
+    const ast = parse('const { a, b: { c } } = fn()')
+    const shared = new Set(['a'])
+
+    expandDestructuredDeclarations(ast, shared)
+    expect(shared).toContain('a')
+    expect(shared).toContain('c')
+  })
+
+  it('should handle destructuring with defaults', () => {
+    const ast = parse('const { a = 1, b = 2 } = fn()')
+    const shared = new Set(['a'])
+
+    expandDestructuredDeclarations(ast, shared)
+    expect(shared).toContain('b')
+  })
+
+  it('should handle destructuring with rest', () => {
+    const ast = parse('const { a, ...rest } = fn()')
+    const shared = new Set(['a'])
+
+    expandDestructuredDeclarations(ast, shared)
+    expect(shared).toContain('rest')
+  })
+})
+
+// ─── computeSharedBindings (integration) ──────────────────
+
+describe('computeSharedBindings', () => {
+  const defaultGroupings = defaultCodeSplitGroupings
+
+  it('should return empty set when no route options exist', () => {
+    const code = 'const x = 1'
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result.size).toBe(0)
+  })
+
+  it('should return empty set for root routes (unsplittable)', () => {
+    const code = `
+import { createRootRoute } from '@tanstack/react-router'
+const shared = 42
+export const Route = createRootRoute({
+  component: () => shared,
+  beforeLoad: () => shared,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result.size).toBe(0)
+  })
+
+  it('should detect binding shared between split and non-split properties', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const sharedValue = 42
+export const Route = createFileRoute('/')({
+  component: () => sharedValue,
+  beforeLoad: () => sharedValue,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result).toContain('sharedValue')
+  })
+
+  it('should NOT mark binding as shared if only used by split properties', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const myComponent = () => <div />
+export const Route = createFileRoute('/')({
+  component: myComponent,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result.size).toBe(0)
+  })
+
+  it('should NOT mark binding as shared if only used by non-split properties', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const validator = () => true
+export const Route = createFileRoute('/')({
+  component: () => <div />,
+  beforeLoad: validator,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result.size).toBe(0)
+  })
+
+  it('should detect shared function declaration', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+function helperFn() { return 42 }
+export const Route = createFileRoute('/')({
+  component: () => helperFn(),
+  beforeLoad: () => helperFn(),
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result).toContain('helperFn')
+  })
+
+  it('should mark shared when binding used by two different split groups', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+class Config { value = 1 }
+export const Route = createFileRoute('/')({
+  component: () => new Config(),
+  loader: () => new Config(),
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: [['component'], ['loader']],
+    })
+    // component and loader are in different split groups → Config is shared
+    expect(result).toContain('Config')
+  })
+
+  it('should detect shared class when used by split and non-split', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+class Config { value = 1 }
+export const Route = createFileRoute('/')({
+  component: () => new Config(),
+  beforeLoad: () => new Config(),
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result).toContain('Config')
+  })
+
+  it('should expand transitive deps into shared set', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const BASE = 10
+const multiplier = BASE * 2
+export const Route = createFileRoute('/')({
+  component: () => multiplier,
+  beforeLoad: () => multiplier,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result).toContain('multiplier')
+    expect(result).toContain('BASE')
+  })
+
+  it('should expand destructured declarations', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const { a, b } = getValues()
+export const Route = createFileRoute('/')({
+  component: () => a,
+  beforeLoad: () => a,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result).toContain('a')
+    expect(result).toContain('b')
+  })
+
+  it('should handle no local bindings gracefully', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+export const Route = createFileRoute('/')({
+  component: () => <div />,
+  beforeLoad: () => {},
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result.size).toBe(0)
+  })
+
+  it('should not include imported bindings as shared (bundlers dedupe them)', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+import { helper } from './utils'
+export const Route = createFileRoute('/')({
+  component: () => helper(),
+  beforeLoad: () => helper(),
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result).not.toContain('helper')
+    expect(result.size).toBe(0)
+  })
+
+  it('should handle multiple shared bindings', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const a = 1
+const b = 2
+export const Route = createFileRoute('/')({
+  component: () => a + b,
+  beforeLoad: () => a + b,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result).toContain('a')
+    expect(result).toContain('b')
+  })
+
+  it('should handle chained createFileRoute call pattern', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const data = { value: 42 }
+export const Route = createFileRoute('/')({
+  component: () => data.value,
+  validateSearch: () => data,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result).toContain('data')
+  })
+
+  it('should handle loader in default groupings (not split by default)', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const config = { key: 'value' }
+export const Route = createFileRoute('/')({
+  component: () => config.key,
+  loader: () => config,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    // In default groupings, loader is NOT split → non-split
+    // component IS split → config referenced by both → shared
+    expect(result).toContain('config')
+  })
+
+  it('should handle custom groupings where loader and component are in different split groups', () => {
+    const groupings: CodeSplitGroupings = [['component'], ['loader']]
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const config = { key: 'value' }
+export const Route = createFileRoute('/')({
+  component: () => config.key,
+  loader: () => config,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: groupings,
+    })
+    // component and loader are in different split groups → config is shared
+    expect(result).toContain('config')
+  })
+
+  it('should NOT mark shared when binding used by only one split group', () => {
+    const groupings: CodeSplitGroupings = [
+      ['loader', 'component'],
+      ['errorComponent'],
+    ]
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const config = { key: 'value' }
+export const Route = createFileRoute('/')({
+  component: () => config.key,
+  loader: () => config,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: groupings,
+    })
+    // component and loader are in the SAME split group → config only in one group → not shared
+    expect(result.size).toBe(0)
+  })
+
+  it('should handle custom groupings with non-split property referencing shared binding', () => {
+    const groupings: CodeSplitGroupings = [['component'], ['loader']]
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const config = { key: 'value' }
+export const Route = createFileRoute('/')({
+  component: () => config.key,
+  loader: () => config,
+  beforeLoad: () => config,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: groupings,
+    })
+    // config used by component (split), loader (split), beforeLoad (non-split)
+    // In both splitRefs and nonSplitRefs → shared
+    expect(result).toContain('config')
+  })
+
+  it('should handle deep transitive chain with destructuring', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const base = 10
+const { x, y } = compute(base)
+export const Route = createFileRoute('/')({
+  component: () => x,
+  beforeLoad: () => x,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    // x is shared → y must be shared (destructured together)
+    // base is a transitive dep of {x, y} declaration → also shared
+    expect(result).toContain('x')
+    expect(result).toContain('y')
+    expect(result).toContain('base')
+  })
+
+  it('should NOT include bindings that transitively depend on Route', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const HEADER = 'Page'
+function usePageTitle() { return HEADER + ' - ' + Route.fullPath }
+export const Route = createFileRoute('/about')({
+  loader: () => usePageTitle(),
+  component: () => usePageTitle(),
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    // usePageTitle references Route → cannot be shared
+    expect(result).not.toContain('usePageTitle')
+    // HEADER does NOT reference Route → still safe to share
+    expect(result).toContain('HEADER')
+    // Route must never be shared
+    expect(result).not.toContain('Route')
+  })
+
+  it('should remove entire transitive chain if it reaches Route', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const routeInfo = { path: '' }
+function initRouteInfo() { routeInfo.path = Route.fullPath }
+function getTitle() { initRouteInfo(); return routeInfo.path }
+export const Route = createFileRoute('/test')({
+  loader: () => getTitle(),
+  component: () => getTitle(),
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    // getTitle → initRouteInfo → Route: entire chain cannot be shared
+    expect(result).not.toContain('getTitle')
+    expect(result).not.toContain('initRouteInfo')
+    expect(result).not.toContain('Route')
+    // routeInfo doesn't reference Route directly, but initRouteInfo does
+    // routeInfo itself may or may not be shared depending on its own deps
+  })
+
+  it('should keep bindings that do NOT depend on Route alongside ones that do', () => {
+    const code = `
+import { createFileRoute } from '@tanstack/react-router'
+const safeConfig = { timeout: 5000 }
+function unsafeHelper() { return Route.fullPath }
+export const Route = createFileRoute('/mixed')({
+  loader: () => ({ config: safeConfig, path: unsafeHelper() }),
+  component: () => <div>{safeConfig.timeout} {unsafeHelper()}</div>,
+})
+`
+    const result = computeSharedBindings({
+      code,
+      codeSplitGroupings: defaultGroupings,
+    })
+    expect(result).toContain('safeConfig')
+    expect(result).not.toContain('unsafeHelper')
+    expect(result).not.toContain('Route')
+  })
+})
+
+// ─── removeBindingsDependingOnRoute ───────────────────────
+
+describe('removeBindingsDependingOnRoute', () => {
+  it('should remove a binding that directly depends on Route', () => {
+    const depGraph = new Map<string, Set<string>>()
+    depGraph.set('helper', new Set(['Route']))
+    depGraph.set('Route', new Set())
+    const shared = new Set(['helper'])
+
+    removeBindingsDependingOnRoute(shared, depGraph)
+    expect(shared).not.toContain('helper')
+  })
+
+  it('should remove a binding that transitively depends on Route', () => {
+    const depGraph = new Map<string, Set<string>>()
+    depGraph.set('a', new Set(['b']))
+    depGraph.set('b', new Set(['Route']))
+    depGraph.set('Route', new Set())
+    const shared = new Set(['a'])
+
+    removeBindingsDependingOnRoute(shared, depGraph)
+    expect(shared).not.toContain('a')
+  })
+
+  it('should keep a binding that does NOT depend on Route', () => {
+    const depGraph = new Map<string, Set<string>>()
+    depGraph.set('safe', new Set(['dep']))
+    depGraph.set('dep', new Set())
+    depGraph.set('Route', new Set())
+    const shared = new Set(['safe'])
+
+    removeBindingsDependingOnRoute(shared, depGraph)
+    expect(shared).toContain('safe')
+  })
+
+  it('should handle mixed: remove Route-dependent, keep safe bindings', () => {
+    const depGraph = new Map<string, Set<string>>()
+    depGraph.set('safe', new Set(['dep']))
+    depGraph.set('dep', new Set())
+    depGraph.set('unsafe', new Set(['Route']))
+    depGraph.set('Route', new Set())
+    const shared = new Set(['safe', 'unsafe'])
+
+    removeBindingsDependingOnRoute(shared, depGraph)
+    expect(shared).toContain('safe')
+    expect(shared).not.toContain('unsafe')
+  })
+
+  it('should handle empty shared set', () => {
+    const depGraph = new Map<string, Set<string>>()
+    const shared = new Set<string>()
+
+    removeBindingsDependingOnRoute(shared, depGraph)
+    expect(shared.size).toBe(0)
+  })
+
+  it('should handle binding with no graph entry', () => {
+    const depGraph = new Map<string, Set<string>>()
+    const shared = new Set(['orphan'])
+
+    removeBindingsDependingOnRoute(shared, depGraph)
+    // No deps found → does not depend on Route → keep
+    expect(shared).toContain('orphan')
+  })
+
+  it('should handle circular deps that do NOT reach Route', () => {
+    const depGraph = new Map<string, Set<string>>()
+    depGraph.set('a', new Set(['b']))
+    depGraph.set('b', new Set(['a']))
+    depGraph.set('Route', new Set())
+    const shared = new Set(['a'])
+
+    removeBindingsDependingOnRoute(shared, depGraph)
+    expect(shared).toContain('a')
+  })
+
+  it('should handle circular deps that DO reach Route', () => {
+    const depGraph = new Map<string, Set<string>>()
+    depGraph.set('a', new Set(['b']))
+    depGraph.set('b', new Set(['a', 'Route']))
+    depGraph.set('Route', new Set())
+    const shared = new Set(['a'])
+
+    removeBindingsDependingOnRoute(shared, depGraph)
+    expect(shared).not.toContain('a')
+  })
+})
diff --git a/packages/router-ssr-query-core/package.json b/packages/router-ssr-query-core/package.json
index 43b0442004..50b37d5818 100644
--- a/packages/router-ssr-query-core/package.json
+++ b/packages/router-ssr-query-core/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/router-ssr-query-core",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/router-vite-plugin/package.json b/packages/router-vite-plugin/package.json
index 69db253855..077cebad2c 100644
--- a/packages/router-vite-plugin/package.json
+++ b/packages/router-vite-plugin/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/router-vite-plugin",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/solid-router-devtools/package.json b/packages/solid-router-devtools/package.json
index e5ae79ce11..549aa94e6a 100644
--- a/packages/solid-router-devtools/package.json
+++ b/packages/solid-router-devtools/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/solid-router-devtools",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for Solid applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/solid-router-ssr-query/README.md b/packages/solid-router-ssr-query/README.md
index b79a5f964c..f7c1691123 100644
--- a/packages/solid-router-ssr-query/README.md
+++ b/packages/solid-router-ssr-query/README.md
@@ -1,4 +1,4 @@
-![TanStack Router Header](https://github.com/tanstack/router/raw/main/media/header_router.png)
+![TanStack Router Header](https://raw.githubusercontent.com/TanStack/router/main/media/header_router.png)
 
 # @tanstack/solid-router-ssr-query
 
diff --git a/packages/solid-router-ssr-query/package.json b/packages/solid-router-ssr-query/package.json
index 34e2319529..bf3e726231 100644
--- a/packages/solid-router-ssr-query/package.json
+++ b/packages/solid-router-ssr-query/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/solid-router-ssr-query",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for Solid applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/solid-router/README.md b/packages/solid-router/README.md
index ebe13ba29f..94a0f37468 100644
--- a/packages/solid-router/README.md
+++ b/packages/solid-router/README.md
@@ -2,7 +2,7 @@
 
 # TanStack Solid Router
 
-![TanStack Router Header](https://github.com/tanstack/router/raw/main/media/header_router.png)
+![TanStack Router Header](https://raw.githubusercontent.com/TanStack/router/main/media/header_router.png)
 
 🤖 Type-safe router w/ built-in caching & URL state management for Solid!
 
@@ -16,9 +16,9 @@
   <img alt="" src="https://badgen.net/bundlephobia/minzip/@tanstack/solid-router" />
 </a><a href="#badge">
     <img alt="semantic-release" src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg">
-  </a><a href="https://github.com/tanstack/router/discussions">
+  </a><a href="https://github.com/TanStack/router/discussions">
   <img alt="Join the discussion on Github" src="https://img.shields.io/badge/Github%20Discussions%20%26%20Support-Chat%20now!-blue" />
-</a><a href="https://bestofjs.org/projects/router"><img alt="Best of JS" src="https://img.shields.io/endpoint?url=https://bestofjs-serverless.now.sh/api/project-badge?fullName=tanstack%2Frouter%26since=daily" /></a><a href="https://github.com/tanstack/router" target="\_parent">
+</a><a href="https://bestofjs.org/projects/router"><img alt="Best of JS" src="https://img.shields.io/endpoint?url=https://bestofjs-serverless.now.sh/api/project-badge?fullName=tanstack%2Frouter%26since=daily" /></a><a href="https://github.com/TanStack/router" target="\_parent">
   <img alt="" src="https://img.shields.io/github/stars/tanstack/router.svg?style=social&label=Star" />
 </a><a href="https://twitter.com/tan_stack" target="\_parent">
   <img alt="" src="https://img.shields.io/twitter/follow/tan_stack.svg?style=social&label=Follow @TanStack" />
diff --git a/packages/solid-router/package.json b/packages/solid-router/package.json
index d5cffa33f4..4620a55842 100644
--- a/packages/solid-router/package.json
+++ b/packages/solid-router/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/solid-router",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for Solid applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/solid-router/src/Asset.tsx b/packages/solid-router/src/Asset.tsx
index 3d89c2e1d3..b762e7bb78 100644
--- a/packages/solid-router/src/Asset.tsx
+++ b/packages/solid-router/src/Asset.tsx
@@ -39,8 +39,15 @@ function Script({
   children?: string
 }): JSX.Element | null {
   const router = useRouter()
+  const dataScript =
+    typeof attrs?.type === 'string' &&
+    attrs.type !== '' &&
+    attrs.type !== 'text/javascript' &&
+    attrs.type !== 'module'
 
   onMount(() => {
+    if (dataScript) return
+
     if (attrs?.src) {
       const normSrc = (() => {
         try {
@@ -125,6 +132,10 @@ function Script({
   })
 
   if (!(isServer ?? router.isServer)) {
+    if (dataScript && typeof children === 'string') {
+      return <script {...attrs} innerHTML={children} />
+    }
+
     // render an empty script on the client just to avoid hydration errors
     return null
   }
diff --git a/packages/solid-router/src/index.tsx b/packages/solid-router/src/index.tsx
index b370c360a1..fa2fd40442 100644
--- a/packages/solid-router/src/index.tsx
+++ b/packages/solid-router/src/index.tsx
@@ -251,7 +251,11 @@ export { useMatch } from './useMatch'
 export { useLoaderDeps } from './useLoaderDeps'
 export { useLoaderData } from './useLoaderData'
 
-export { redirect, isRedirect } from '@tanstack/router-core'
+export {
+  redirect,
+  isRedirect,
+  DEFAULT_PROTOCOL_ALLOWLIST,
+} from '@tanstack/router-core'
 
 export {
   RouteApi,
diff --git a/packages/solid-router/src/link.tsx b/packages/solid-router/src/link.tsx
index 4c70bc15e7..4a807fd937 100644
--- a/packages/solid-router/src/link.tsx
+++ b/packages/solid-router/src/link.tsx
@@ -10,12 +10,15 @@ import {
   preloadWarning,
   removeTrailingSlash,
 } from '@tanstack/router-core'
+
+import { isServer } from '@tanstack/router-core/isServer'
 import { Dynamic } from 'solid-js/web'
 import { useRouterState } from './useRouterState'
 import { useRouter } from './useRouter'
 
 import { useIntersectionObserver } from './utils'
 
+import { useHydrated } from './ClientOnly'
 import type {
   AnyRouter,
   Constrain,
@@ -40,6 +43,9 @@ export function useLinkProps<
 ): Solid.ComponentProps<'a'> {
   const router = useRouter()
   const [isTransitioning, setIsTransitioning] = Solid.createSignal(false)
+  const shouldHydrateHash = !isServer && !!router.options.ssr
+  const hasHydrated = useHydrated()
+
   let hasRenderFetched = false
 
   const [local, rest] = Solid.splitProps(
@@ -115,6 +121,10 @@ export function useLinkProps<
     'unsafeRelative',
   ])
 
+  const currentLocation = useRouterState({
+    select: (s) => s.location,
+  })
+
   const currentSearch = useRouterState({
     select: (s) => s.location.searchStr,
   })
@@ -157,7 +167,7 @@ export function useLinkProps<
     const _href = hrefOption()
     if (_href?.external) {
       // Block dangerous protocols for external links
-      if (isDangerousProtocol(_href.href)) {
+      if (isDangerousProtocol(_href.href, router.protocolAllowlist)) {
         if (process.env.NODE_ENV !== 'production') {
           console.warn(`Blocked Link with dangerous protocol: ${_href.href}`)
         }
@@ -173,8 +183,8 @@ export function useLinkProps<
     if (isSafeInternal) return undefined
     try {
       new URL(to as any)
-      // Block dangerous protocols like javascript:, data:, vbscript:
-      if (isDangerousProtocol(to as string)) {
+      // Block dangerous protocols like javascript:, blob:, data:
+      if (isDangerousProtocol(to as string, router.protocolAllowlist)) {
         if (process.env.NODE_ENV !== 'production') {
           console.warn(`Blocked Link with dangerous protocol: ${to}`)
         }
@@ -194,51 +204,51 @@ export function useLinkProps<
   const preloadDelay = () =>
     local.preloadDelay ?? router.options.defaultPreloadDelay ?? 0
 
-  const isActive = useRouterState({
-    select: (s) => {
-      if (externalLink()) return false
-      if (local.activeOptions?.exact) {
-        const testExact = exactPathTest(
-          s.location.pathname,
-          next().pathname,
-          router.basepath,
-        )
-        if (!testExact) {
-          return false
-        }
-      } else {
-        const currentPathSplit = removeTrailingSlash(
-          s.location.pathname,
-          router.basepath,
-        ).split('/')
-        const nextPathSplit = removeTrailingSlash(
-          next()?.pathname,
-          router.basepath,
-        )?.split('/')
-
-        const pathIsFuzzyEqual = nextPathSplit?.every(
-          (d, i) => d === currentPathSplit[i],
-        )
-        if (!pathIsFuzzyEqual) {
-          return false
-        }
+  const isActive = Solid.createMemo(() => {
+    if (externalLink()) return false
+    if (local.activeOptions?.exact) {
+      const testExact = exactPathTest(
+        currentLocation().pathname,
+        next().pathname,
+        router.basepath,
+      )
+      if (!testExact) {
+        return false
       }
-
-      if (local.activeOptions?.includeSearch ?? true) {
-        const searchTest = deepEqual(s.location.search, next().search, {
-          partial: !local.activeOptions?.exact,
-          ignoreUndefined: !local.activeOptions?.explicitUndefined,
-        })
-        if (!searchTest) {
-          return false
-        }
+    } else {
+      const currentPathSplit = removeTrailingSlash(
+        currentLocation().pathname,
+        router.basepath,
+      ).split('/')
+      const nextPathSplit = removeTrailingSlash(
+        next()?.pathname,
+        router.basepath,
+      )?.split('/')
+
+      const pathIsFuzzyEqual = nextPathSplit?.every(
+        (d, i) => d === currentPathSplit[i],
+      )
+      if (!pathIsFuzzyEqual) {
+        return false
       }
+    }
 
-      if (local.activeOptions?.includeHash) {
-        return s.location.hash === next().hash
+    if (local.activeOptions?.includeSearch ?? true) {
+      const searchTest = deepEqual(currentLocation().search, next().search, {
+        partial: !local.activeOptions?.exact,
+        ignoreUndefined: !local.activeOptions?.explicitUndefined,
+      })
+      if (!searchTest) {
+        return false
       }
-      return true
-    },
+    }
+
+    if (local.activeOptions?.includeHash) {
+      const currentHash =
+        shouldHydrateHash && !hasHydrated() ? '' : currentLocation().hash
+      return currentHash === next().hash
+    }
+    return true
   })
 
   const doPreload = () =>
diff --git a/packages/solid-router/src/useMatch.tsx b/packages/solid-router/src/useMatch.tsx
index 40a99e1487..0ccccd2211 100644
--- a/packages/solid-router/src/useMatch.tsx
+++ b/packages/solid-router/src/useMatch.tsx
@@ -1,5 +1,6 @@
 import * as Solid from 'solid-js'
 import invariant from 'tiny-invariant'
+import { useRouter } from './useRouter'
 import { useRouterState } from './useRouterState'
 import { dummyMatchContext, matchContext } from './matchContext'
 import type {
@@ -69,6 +70,7 @@ export function useMatch<
 ): Solid.Accessor<
   ThrowOrOptional<UseMatchResult<TRouter, TFrom, TStrict, TSelected>, TThrow>
 > {
+  const router = useRouter<TRouter>()
   const nearestMatchId = Solid.useContext(
     opts.from ? dummyMatchContext : matchContext,
   )
@@ -84,14 +86,17 @@ export function useMatch<
       )
 
       if (match === undefined) {
-        // During navigation transitions, check if the match exists in pendingMatches
-        const pendingMatch = state.pendingMatches?.find((d: any) =>
-          opts.from ? opts.from === d.routeId : d.id === nearestMatchId(),
-        )
+        const hasPendingMatch =
+          state.status === 'pending' &&
+          router.matchRoutes(router.latestLocation).some((d: any) =>
+            opts.from ? opts.from === d.routeId : d.id === nearestMatchId(),
+          )
 
         // Determine if we should throw an error
         const shouldThrowError =
-          !pendingMatch && !state.isTransitioning && (opts.shouldThrow ?? true)
+          !hasPendingMatch &&
+          !state.isTransitioning &&
+          (opts.shouldThrow ?? true)
 
         return { match: undefined, shouldThrowError }
       }
diff --git a/packages/solid-router/tests/link.test.tsx b/packages/solid-router/tests/link.test.tsx
index a9edfd6ce5..5c7fc93d0f 100644
--- a/packages/solid-router/tests/link.test.tsx
+++ b/packages/solid-router/tests/link.test.tsx
@@ -775,7 +775,7 @@ describe('Link', () => {
       '/posts?page=2&filter=inactive',
     )
 
-    await fireEvent.click(updateSearchLink)
+    fireEvent.click(updateSearchLink)
 
     // Wait for navigation to complete and search params to update
     await waitFor(() => {
@@ -786,8 +786,11 @@ describe('Link', () => {
     const updatedFilter = await screen.findByTestId('current-filter')
 
     // Verify search was updated
-    expect(window.location.pathname).toBe('/posts')
-    expect(window.location.search).toBe('?page=2&filter=inactive')
+    // Wait for navigation to complete and search params to update
+    await waitFor(() => {
+      expect(window.location.pathname).toBe('/posts')
+      expect(window.location.search).toBe('?page=2&filter=inactive')
+    })
 
     expect(updatedPage).toHaveTextContent('Page: 2')
     expect(updatedFilter).toHaveTextContent('Filter: inactive')
diff --git a/packages/solid-router/tests/useMatch.test.tsx b/packages/solid-router/tests/useMatch.test.tsx
index f9c592601d..b860429490 100644
--- a/packages/solid-router/tests/useMatch.test.tsx
+++ b/packages/solid-router/tests/useMatch.test.tsx
@@ -9,6 +9,7 @@ import {
   createRoute,
   createRouter,
   useMatch,
+  useRouterState,
 } from '../src'
 import type { RouteComponent, RouterHistory } from '../src'
 
@@ -116,4 +117,129 @@ describe('useMatch', () => {
       })
     })
   })
+
+  describe('pending transitions', () => {
+    test('does not throw while transitioning to a pending matching route', async () => {
+      let resolvePostsLoader!: () => void
+      const postsLoaderPromise = new Promise<void>((resolve) => {
+        resolvePostsLoader = resolve
+      })
+
+      function PendingProbe() {
+        useMatch({ from: '/posts', shouldThrow: true })
+        return null
+      }
+
+      function RootComponent() {
+        const routerState = useRouterState()
+        return (
+          <>
+            {routerState().status === 'pending' ? <PendingProbe /> : null}
+            <Outlet />
+          </>
+        )
+      }
+
+      const rootRoute = createRootRoute({
+        component: RootComponent,
+      })
+      const indexRoute = createRoute({
+        getParentRoute: () => rootRoute,
+        path: '/',
+        component: () => <h1>IndexTitle</h1>,
+      })
+      const postsRoute = createRoute({
+        getParentRoute: () => rootRoute,
+        path: '/posts',
+        loader: async () => {
+          await postsLoaderPromise
+        },
+        component: () => <h1>PostsTitle</h1>,
+      })
+
+      const router = createRouter({
+        routeTree: rootRoute.addChildren([indexRoute, postsRoute]),
+        history: createMemoryHistory({ initialEntries: ['/'] }),
+      })
+
+      render(() => <RouterProvider router={router} />)
+      await screen.findByText('IndexTitle')
+
+      const navigation = router.navigate({ to: '/posts' })
+      await waitFor(() => {
+        expect(router.state.status).toBe('pending')
+      })
+
+      expect(
+        screen.queryByText(
+          'Invariant failed: Could not find an active match from "/posts"',
+        ),
+      ).not.toBeInTheDocument()
+
+      resolvePostsLoader()
+      await navigation
+      expect(await screen.findByText('PostsTitle')).toBeInTheDocument()
+    })
+
+    test('still throws during pending transition when route is not pending', async () => {
+      let resolveOtherLoader!: () => void
+      const otherLoaderPromise = new Promise<void>((resolve) => {
+        resolveOtherLoader = resolve
+      })
+
+      function PendingProbe() {
+        useMatch({ from: '/posts', shouldThrow: true })
+        return null
+      }
+
+      function RootComponent() {
+        const routerState = useRouterState()
+        return (
+          <>
+            {routerState().status === 'pending' ? <PendingProbe /> : null}
+            <Outlet />
+          </>
+        )
+      }
+
+      const rootRoute = createRootRoute({
+        component: RootComponent,
+      })
+      const indexRoute = createRoute({
+        getParentRoute: () => rootRoute,
+        path: '/',
+        component: () => <h1>IndexTitle</h1>,
+      })
+      const postsRoute = createRoute({
+        getParentRoute: () => rootRoute,
+        path: '/posts',
+        component: () => <h1>PostsTitle</h1>,
+      })
+      const otherRoute = createRoute({
+        getParentRoute: () => rootRoute,
+        path: '/other',
+        loader: async () => {
+          await otherLoaderPromise
+        },
+        component: () => <h1>OtherTitle</h1>,
+      })
+
+      const router = createRouter({
+        routeTree: rootRoute.addChildren([indexRoute, postsRoute, otherRoute]),
+        history: createMemoryHistory({ initialEntries: ['/'] }),
+      })
+
+      render(() => <RouterProvider router={router} />)
+      await screen.findByText('IndexTitle')
+
+      const navigation = router.navigate({ to: '/other' }).catch(() => {})
+      const errorText = await screen.findByText(
+        'Invariant failed: Could not find an active match from "/posts"',
+      )
+      expect(errorText).toBeInTheDocument()
+
+      resolveOtherLoader()
+      await navigation
+    })
+  })
 })
diff --git a/packages/solid-start-client/package.json b/packages/solid-start-client/package.json
index dbfa3ce539..0f21456b30 100644
--- a/packages/solid-start-client/package.json
+++ b/packages/solid-start-client/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/solid-start-client",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for Solid applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/solid-start-server/package.json b/packages/solid-start-server/package.json
index 52a2e39e4b..31913d6b0e 100644
--- a/packages/solid-start-server/package.json
+++ b/packages/solid-start-server/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/solid-start-server",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for Solid applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/solid-start/README.md b/packages/solid-start/README.md
index d265c1df34..26f6c4840c 100644
--- a/packages/solid-start/README.md
+++ b/packages/solid-start/README.md
@@ -2,7 +2,7 @@
 
 # TanStack Solid Start
 
-![TanStack Solid Start Header](https://github.com/tanstack/router/raw/main/media/header_start.png)
+![TanStack Solid Start Header](https://raw.githubusercontent.com/TanStack/router/main/media/header_start.png)
 
 SSR, Streaming, Server Functions, API Routes, bundling and more powered by [TanStack Router](https://tanstack.com/router) and Vite. Ready to deploy to your favorite hosting provider.
 
@@ -21,13 +21,13 @@ SSR, Streaming, Server Functions, API Routes, bundling and more powered by [TanS
 <a href="#badge">
   <img alt="semantic-release" src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg">
 </a>
-<a href="https://github.com/tanstack/router/discussions">
+<a href="https://github.com/TanStack/router/discussions">
   <img alt="Join the discussion on Github" src="https://img.shields.io/badge/Github%20Discussions%20%26%20Support-Chat%20now!-blue" />
 </a>
 <a href="https://bestofjs.org/projects/router">
   <img alt="Best of JS" src="https://img.shields.io/endpoint?url=https://bestofjs-serverless.now.sh/api/project-badge?fullName=tanstack%2Frouter%26since=daily" />
 </a>
-<a href="https://github.com/tanstack/router" target="\_parent">
+<a href="https://github.com/TanStack/router" target="\_parent">
   <img alt="" src="https://img.shields.io/github/stars/tanstack/router.svg?style=social&label=Star" />
 </a>
 <a href="https://twitter.com/tan_stack" target="\_parent">
@@ -37,6 +37,6 @@ SSR, Streaming, Server Functions, API Routes, bundling and more powered by [TanS
   <img alt="" src="https://img.shields.io/twitter/follow/tannerlinsley.svg?style=social&label=Follow @TannerLinsley" />
 </a>
 
-Enjoy this library? Try the entire [TanStack](https://tanstack.com)! [React Query](https://github.com/tannerlinsley/react-query), [React Table](https://github.com/tanstack/react-table), [React Charts](https://github.com/tannerlinsley/react-charts), [React Virtual](https://github.com/tannerlinsley/react-virtual)
+Enjoy this library? Try the entire [TanStack](https://tanstack.com)! [Solid Query](https://github.com/TanStack/query), [Solid Table](https://github.com/TanStack/table), [Solid Virtual](https://github.com/TanStack/virtual)
 
 Visit [tanstack.com/start](https://tanstack.com/start) for docs, guides, API and more!
diff --git a/packages/solid-start/package.json b/packages/solid-start/package.json
index b356e029f3..dbfbfb100a 100644
--- a/packages/solid-start/package.json
+++ b/packages/solid-start/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/solid-start",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for Solid applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/start-client-core/package.json b/packages/start-client-core/package.json
index b600e59e56..90d9554f2b 100644
--- a/packages/start-client-core/package.json
+++ b/packages/start-client-core/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/start-client-core",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/start-client-core/src/createServerFn.ts b/packages/start-client-core/src/createServerFn.ts
index 39542d1e2a..2f810f1b2f 100644
--- a/packages/start-client-core/src/createServerFn.ts
+++ b/packages/start-client-core/src/createServerFn.ts
@@ -140,7 +140,7 @@ export const createServerFn: CreateServerFn<Register> = (options, __opts) => {
           ...extractedFn,
           // The extracted function on the server-side calls
           // this function
-          __executeServer: async (opts: any, signal: AbortSignal) => {
+          __executeServer: async (opts: any) => {
             const startContext = getStartContextServerOnly()
             const serverContextAfterGlobalMiddlewares =
               startContext.contextAfterGlobalMiddlewares
@@ -157,7 +157,6 @@ export const createServerFn: CreateServerFn<Register> = (options, __opts) => {
                 serverContextAfterGlobalMiddlewares,
                 opts.context,
               ),
-              signal,
               request: startContext.request,
             }
 
@@ -350,7 +349,6 @@ export interface FetcherBase {
     data: unknown
     headers?: HeadersInit
     context?: any
-    signal: AbortSignal
   }) => Promise<unknown>
 }
 
@@ -429,7 +427,6 @@ export interface ServerFnCtx<
   serverFnMeta: ServerFnMeta
   context: Expand<AssignAllServerFnContext<TRegister, TMiddlewares, {}>>
   method: TMethod
-  signal: AbortSignal
 }
 
 export type CompiledFetcherFn<TRegister, TResponse> = {
diff --git a/packages/start-client-core/src/tests/createServerFn.test-d.ts b/packages/start-client-core/src/tests/createServerFn.test-d.ts
index f0cb181a43..f96e8e9de2 100644
--- a/packages/start-client-core/src/tests/createServerFn.test-d.ts
+++ b/packages/start-client-core/src/tests/createServerFn.test-d.ts
@@ -26,7 +26,6 @@ test('createServerFn without middleware', () => {
       context: undefined
       data: undefined
       method: 'GET'
-      signal: AbortSignal
       serverFnMeta: ServerFnMeta
     }>()
   })
@@ -50,7 +49,6 @@ test('createServerFn with validator function', () => {
         a: string
       }
       method: 'GET'
-      signal: AbortSignal
       serverFnMeta: ServerFnMeta
     }>()
   })
@@ -79,7 +77,6 @@ test('createServerFn with async validator function', () => {
       context: undefined
       data: string
       method: 'GET'
-      signal: AbortSignal
       serverFnMeta: ServerFnMeta
     }>()
   })
@@ -110,7 +107,6 @@ test('createServerFn with validator with parse method', () => {
       context: undefined
       data: string
       method: 'GET'
-      signal: AbortSignal
       serverFnMeta: ServerFnMeta
     }>()
   })
@@ -141,7 +137,6 @@ test('createServerFn with async validator with parse method', () => {
       context: undefined
       data: string
       method: 'GET'
-      signal: AbortSignal
       serverFnMeta: ServerFnMeta
     }>()
   })
@@ -189,7 +184,6 @@ test('createServerFn with standard validator', () => {
       context: undefined
       data: string
       method: 'GET'
-      signal: AbortSignal
       serverFnMeta: ServerFnMeta
     }>()
   })
@@ -238,7 +232,6 @@ test('createServerFn with async standard validator', () => {
       context: undefined
       data: string
       method: 'GET'
-      signal: AbortSignal
       serverFnMeta: ServerFnMeta
     }>()
   })
@@ -303,7 +296,6 @@ test('createServerFn with middleware and context', () => {
       }
       data: undefined
       method: 'GET'
-      signal: AbortSignal
       serverFnMeta: ServerFnMeta
     }>()
   })
@@ -347,7 +339,6 @@ describe('createServerFn with middleware and validator', () => {
             readonly outputC: 'outputC'
           }
           method: 'GET'
-          signal: AbortSignal
           serverFnMeta: ServerFnMeta
         }>()
 
@@ -446,7 +437,6 @@ test('createServerFn where validator is a primitive', () => {
         context: undefined
         data: 'c'
         method: 'GET'
-        signal: AbortSignal
         serverFnMeta: ServerFnMeta
       }>()
     })
@@ -460,7 +450,6 @@ test('createServerFn where validator is optional if object is optional', () => {
         context: undefined
         data: 'c' | undefined
         method: 'GET'
-        signal: AbortSignal
         serverFnMeta: ServerFnMeta
       }>()
     })
@@ -484,7 +473,6 @@ test('createServerFn where data is optional if there is no validator', () => {
       context: undefined
       data: undefined
       method: 'GET'
-      signal: AbortSignal
       serverFnMeta: ServerFnMeta
     }>()
   })
@@ -679,7 +667,6 @@ test('incrementally building createServerFn with multiple middleware calls', ()
       }
       data: undefined
       method: 'GET'
-      signal: AbortSignal
       serverFnMeta: ServerFnMeta
     }>()
   })
@@ -701,7 +688,6 @@ test('incrementally building createServerFn with multiple middleware calls', ()
       }
       data: undefined
       method: 'POST'
-      signal: AbortSignal
       serverFnMeta: ServerFnMeta
     }>()
   })
@@ -724,7 +710,7 @@ test('incrementally building createServerFn with multiple middleware calls', ()
       }
       data: undefined
       method: 'GET'
-      signal: AbortSignal
+
       serverFnMeta: ServerFnMeta
     }>()
   })
@@ -758,7 +744,6 @@ test('compose middlewares and server function factories', () => {
       }
       data: undefined
       method: 'GET'
-      signal: AbortSignal
       serverFnMeta: ServerFnMeta
     }>()
   })
diff --git a/packages/start-plugin-core/package.json b/packages/start-plugin-core/package.json
index 73e3fbcf72..bdcd28ca21 100644
--- a/packages/start-plugin-core/package.json
+++ b/packages/start-plugin-core/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/start-plugin-core",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
@@ -74,7 +74,7 @@
     "cheerio": "^1.0.0",
     "exsolve": "^1.0.7",
     "pathe": "^2.0.3",
-    "srvx": "^0.10.1",
+    "srvx": "^0.11.2",
     "tinyglobby": "^0.2.15",
     "ufo": "^1.5.4",
     "vitefu": "^1.1.1",
diff --git a/packages/start-plugin-core/src/prerender.ts b/packages/start-plugin-core/src/prerender.ts
index 3986873c66..46bfd618d0 100644
--- a/packages/start-plugin-core/src/prerender.ts
+++ b/packages/start-plugin-core/src/prerender.ts
@@ -144,6 +144,11 @@ export async function prerender({
 
     startConfig.pages.forEach((page) => addCrawlPageTask(page))
 
+    if (queue.isSettled()) {
+      logger.info('No pages matched prerender filter; skipping.')
+      return Array.from(prerendered)
+    }
+
     await queue.start()
 
     return Array.from(prerendered)
diff --git a/packages/start-plugin-core/src/start-compiler-plugin/compiler.ts b/packages/start-plugin-core/src/start-compiler-plugin/compiler.ts
index 21889ae1c1..dd22fd4a79 100644
--- a/packages/start-plugin-core/src/start-compiler-plugin/compiler.ts
+++ b/packages/start-plugin-core/src/start-compiler-plugin/compiler.ts
@@ -56,6 +56,10 @@ type DirectCallSetup = {
 }
 type JSXSetup = { type: 'jsx'; componentName: string }
 
+function isLookupKind(kind: Kind): kind is LookupKind {
+  return kind in LookupSetup
+}
+
 const LookupSetup: Record<
   LookupKind,
   MethodChainSetup | DirectCallSetup | JSXSetup
@@ -1120,32 +1124,25 @@ export class StartCompiler {
       fileId,
       visited,
     )
+    // When a var binding's init is a call to a directCall factory
+    // (e.g., `const myFn = createServerOnlyFn(() => ...)`), the binding holds
+    // the RESULT of the factory, not the factory itself. Clear the kind so
+    // `myFn()` isn't incorrectly matched as a directCall candidate.
+    // We only clear when the init is a CallExpression — an alias like
+    // `const createSO = createServerOnlyFn` should still propagate the kind.
+    if (
+      isLookupKind(resolvedKind) &&
+      LookupSetup[resolvedKind].type === 'directCall' &&
+      binding.init &&
+      t.isCallExpression(binding.init)
+    ) {
+      binding.resolvedKind = 'None'
+      return 'None'
+    }
     binding.resolvedKind = resolvedKind
     return resolvedKind
   }
 
-  /**
-   * Checks if an identifier is a direct import from a known factory library.
-   * Returns true for imports like `import { createServerOnlyFn } from '@tanstack/react-start'`
-   * or renamed imports like `import { createServerOnlyFn as myFn } from '...'`.
-   * Returns false for local variables that hold the result of calling a factory.
-   */
-  private async isKnownFactoryImport(
-    identName: string,
-    fileId: string,
-  ): Promise<boolean> {
-    const info = await this.getModuleInfo(fileId)
-    const binding = info.bindings.get(identName)
-
-    if (!binding || binding.type !== 'import') {
-      return false
-    }
-
-    // Check if it's imported from a known library
-    const knownExports = this.knownRootImports.get(binding.source)
-    return knownExports !== undefined && knownExports.has(binding.importedName)
-  }
-
   private async resolveExprKind(
     expr: t.Expression | null,
     fileId: string,
@@ -1185,19 +1182,14 @@ export class StartCompiler {
           return calleeKind
         }
       }
-      // For direct calls (callee is Identifier), only return the kind if the
-      // callee is a direct import from a known library (e.g., createServerOnlyFn).
-      // Calling a local variable that holds an already-built function (e.g., myServerOnlyFn())
-      // should NOT be treated as a transformation candidate.
+      // For direct calls (callee is Identifier like createServerOnlyFn()),
+      // trust calleeKind if it resolved to a valid LookupKind. This means
+      // resolveBindingKind successfully traced the import back to
+      // @tanstack/start-fn-stubs (via fast path or slow path through re-exports).
+      // This handles both direct imports from @tanstack/react-start and imports
+      // from intermediate packages that re-export from @tanstack/start-client-core.
       if (t.isIdentifier(expr.callee)) {
-        const isFactoryImport = await this.isKnownFactoryImport(
-          expr.callee.name,
-          fileId,
-        )
-        if (
-          isFactoryImport &&
-          this.validLookupKinds.has(calleeKind as LookupKind)
-        ) {
+        if (this.validLookupKinds.has(calleeKind as LookupKind)) {
           return calleeKind
         }
       }
diff --git a/packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts b/packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts
index a34ff28f21..ddad1cf061 100644
--- a/packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts
+++ b/packages/start-plugin-core/src/start-compiler-plugin/handleCreateServerFn.ts
@@ -328,16 +328,16 @@ export function handleCreateServerFn(
       // const extractedFn = createServerRpc({id, name, filename}, (opts) => varName.__executeServer(opts));
       // const varName = createServerFn().handler(extractedFn, originalHandler);
 
-      // Build the arrow function: (opts, signal) => varName.__executeServer(opts, signal)
+      // Build the arrow function: (opts) => varName.__executeServer(opts)
       // The signal parameter is passed through to allow abort signal propagation
       const executeServerArrowFn = t.arrowFunctionExpression(
-        [t.identifier('opts'), t.identifier('signal')],
+        [t.identifier('opts')],
         t.callExpression(
           t.memberExpression(
             t.identifier(existingVariableName),
             t.identifier('__executeServer'),
           ),
-          [t.identifier('opts'), t.identifier('signal')],
+          [t.identifier('opts')],
         ),
       )
 
diff --git a/packages/start-plugin-core/src/start-compiler-plugin/plugin.ts b/packages/start-plugin-core/src/start-compiler-plugin/plugin.ts
index 973b2b192b..ecb6ef2343 100644
--- a/packages/start-plugin-core/src/start-compiler-plugin/plugin.ts
+++ b/packages/start-plugin-core/src/start-compiler-plugin/plugin.ts
@@ -1,4 +1,6 @@
+import assert from 'node:assert'
 import { VIRTUAL_MODULES } from '@tanstack/start-server-core'
+import { resolve as resolvePath } from 'pathe'
 import { TRANSFORM_ID_REGEX, VITE_ENVIRONMENT_NAMES } from '../constants'
 import {
   KindDetectionPatterns,
@@ -355,12 +357,60 @@ export function startCompilerPlugin(
         filter: {
           id: new RegExp(resolveViteId(validateServerFnIdVirtualModule)),
         },
-        handler(id) {
+        async handler(id) {
           const parsed = parseIdQuery(id)
-          if (parsed.query.id && serverFnsById[parsed.query.id]) {
+          const fnId = parsed.query.id
+          if (fnId && serverFnsById[fnId]) {
             return `export {}`
           }
-          this.error(`Invalid server function ID: ${parsed.query.id}`)
+
+          // ID not yet registered — the source file may not have been
+          // transformed in this dev session yet (e.g. cold restart with
+          // cached client). Try to decode the ID, discover the source
+          // file, trigger its compilation, and re-check.
+          if (fnId) {
+            try {
+              const decoded = JSON.parse(
+                Buffer.from(fnId, 'base64url').toString('utf8'),
+              )
+              if (
+                typeof decoded.file === 'string' &&
+                typeof decoded.export === 'string'
+              ) {
+                // decoded.file looks like "/@id/src/foo.ts?tss-serverfn-split"
+                // Strip the /@id/ prefix and ?tss-serverfn-split suffix to
+                // get the original source file path that needs transforming.
+                let sourceFile = decoded.file
+                if (sourceFile.startsWith('/@id/')) {
+                  sourceFile = sourceFile.slice('/@id/'.length)
+                }
+                const qIdx = sourceFile.indexOf('?')
+                if (qIdx !== -1) {
+                  sourceFile = sourceFile.slice(0, qIdx)
+                }
+
+                // Resolve to absolute path
+                const absPath = resolvePath(root, sourceFile)
+
+                // Trigger transform of the source file in this environment,
+                // which will compile createServerFn calls and populate
+                // serverFnsById as a side effect.
+                // This plugin only runs in dev (apply: 'serve'), so mode
+                // must be 'dev' — assert to narrow to DevEnvironment.
+                assert(this.environment.mode === 'dev')
+                await this.environment.fetchModule(absPath)
+
+                // Re-check after lazy compilation
+                if (serverFnsById[fnId]) {
+                  return `export {}`
+                }
+              }
+            } catch {
+              // Decoding or fetching failed — fall through to error
+            }
+          }
+
+          this.error(`Invalid server function ID: ${fnId}`)
         },
       },
     },
diff --git a/packages/start-plugin-core/tests/compiler.test.ts b/packages/start-plugin-core/tests/compiler.test.ts
index 2678fc87cf..a063ea3ffe 100644
--- a/packages/start-plugin-core/tests/compiler.test.ts
+++ b/packages/start-plugin-core/tests/compiler.test.ts
@@ -454,3 +454,276 @@ test('ingestModule handles empty code gracefully', () => {
     compiler.ingestModule({ code: '   \n\t  ', id: 'whitespace.ts' })
   }).not.toThrow()
 })
+
+describe('calling result of createServerOnlyFn/createClientOnlyFn', () => {
+  // This tests the fix for https://github.com/TanStack/router/issues/6643
+  // When a file has both createServerFn and createServerOnlyFn, and the result
+  // of createServerOnlyFn is invoked (e.g., `const result = myServerOnlyFn()`),
+  // the compiler should NOT treat that invocation as a ServerOnlyFn candidate.
+  // The var binding holds the RESULT of the factory, not the factory itself.
+
+  test('invocation of createServerOnlyFn result is not treated as a candidate', async () => {
+    const compiler = createFullCompiler('server')
+
+    const code = `
+      import { createServerFn, createServerOnlyFn } from '@tanstack/react-start'
+
+      const createRandomNumber = createServerOnlyFn(() => Math.floor(Math.random() * 100))
+      const randomNumber = createRandomNumber()
+
+      export const personServerFn = createServerFn({ method: 'GET' })
+        .handler(({ data: name }) => {
+          return { name, randomNumber }
+        })
+    `
+
+    // Should NOT throw "createServerOnlyFn() must be called with a function!"
+    // The main file output is the split-file version (createServerFn splits the handler),
+    // so we just verify it compiles without error and produces valid output.
+    const result = await compiler.compile({ code, id: 'test-6643.ts' })
+    expect(result).not.toBeNull()
+    // The output should contain the personServerFn export (with SSR RPC reference)
+    expect(result!.code).toContain('personServerFn')
+  })
+
+  test('invocation of createClientOnlyFn result is not treated as a candidate', async () => {
+    const compiler = createFullCompiler('client')
+
+    const code = `
+      import { createClientOnlyFn, createServerFn } from '@tanstack/react-start'
+
+      const getWindowWidth = createClientOnlyFn(() => window.innerWidth)
+      const width = getWindowWidth()
+
+       export const personServerFn = createServerFn({ method: 'GET' })
+        .handler(({ data: name }) => {
+          return { name }
+        })
+    `
+
+    const result = await compiler.compile({ code, id: 'test-6643-client.ts' })
+    expect(result).not.toBeNull()
+    expect(result!.code).toContain('window.innerWidth')
+    expect(result!.code).toContain('getWindowWidth()')
+  })
+
+  test('re-exported createServerOnlyFn still resolves correctly', async () => {
+    // Ensure the fix doesn't break re-export chain resolution (issue #6583)
+    const virtualModules: Record<string, string> = {
+      '@tanstack/start-client-core': `
+        export { createServerOnlyFn } from '@tanstack/start-fn-stubs'
+      `,
+    }
+
+    const compiler: StartCompiler = new StartCompiler({
+      env: 'server',
+      envName: 'ssr',
+      root: '/test',
+      framework: 'react' as const,
+      providerEnvName: 'ssr',
+      lookupKinds: new Set(['ServerOnlyFn', 'ClientOnlyFn']),
+      lookupConfigurations: [],
+      loadModule: async (id) => {
+        const code = virtualModules[id]
+        if (code) {
+          compiler.ingestModule({ code, id })
+        }
+      },
+      resolveId: async (id) => {
+        return virtualModules[id] ? id : null
+      },
+    })
+
+    const code = `
+      import { createServerOnlyFn } from '@tanstack/start-client-core'
+      const myFn = createServerOnlyFn(() => 'server-only-value')
+    `
+
+    const result = await compiler.compile({ code, id: 'reexport-test.ts' })
+    expect(result).not.toBeNull()
+    expect(result!.code).toContain('server-only-value')
+  })
+
+  test('aliased factory is still detected as a candidate', async () => {
+    // `const createSO = createServerOnlyFn` is an alias, not an invocation.
+    // `createSO(() => ...)` should still be treated as ServerOnlyFn.
+    const compiler = createFullCompiler('server')
+
+    const code = `
+      import { createServerOnlyFn } from '@tanstack/react-start'
+
+      const createSO = createServerOnlyFn
+      const myFn = createSO(() => 'aliased-server-only')
+    `
+
+    const result = await compiler.compile({ code, id: 'alias-test.ts' })
+    expect(result).not.toBeNull()
+    // The factory should be unwrapped on server env
+    expect(result!.code).toContain('aliased-server-only')
+  })
+})
+
+describe('re-export chain resolution', () => {
+  // This tests the fix for https://github.com/TanStack/router/issues/6583
+  // Third-party packages may import from @tanstack/start-client-core (which re-exports
+  // from @tanstack/start-fn-stubs) rather than directly from @tanstack/react-start.
+  // The compiler should correctly resolve these imports via the slow path.
+
+  // Virtual module contents for simulating the re-export chain:
+  // @third-party/lib -> @tanstack/start-client-core -> @tanstack/start-fn-stubs
+  //
+  // Note: We don't need a virtual module for @tanstack/start-fn-stubs because
+  // init() hardcodes it in knownRootImports. When the slow path resolution reaches
+  // that package, it uses the fast path lookup and never needs to parse the module.
+  const virtualModules: Record<string, string> = {
+    // The client-core package that re-exports from stubs
+    '@tanstack/start-client-core': `
+      export { createIsomorphicFn, createServerOnlyFn, createClientOnlyFn } from '@tanstack/start-fn-stubs'
+    `,
+    // A third-party package that imports from start-client-core
+    '@third-party/lib': `
+      import { createIsomorphicFn, createClientOnlyFn } from '@tanstack/start-client-core'
+
+      export const getThemeData = createIsomorphicFn()
+        .client(() => 'client-theme')
+        .server(() => 'server-theme')
+
+      export const initClientFeature = createClientOnlyFn(() => {
+        console.log('client only initialization')
+        return 'initialized'
+      })
+    `,
+  }
+
+  function createCompilerWithVirtualModules(env: 'client' | 'server') {
+    const envName = env === 'client' ? 'client' : 'ssr'
+    const lookupKinds: Set<LookupKind> = new Set([
+      'IsomorphicFn',
+      'ServerOnlyFn',
+      'ClientOnlyFn',
+    ])
+
+    // Note: We use empty lookupConfigurations because this test is specifically
+    // testing the slow path resolution through re-export chains. The compiler
+    // should still work because @tanstack/start-fn-stubs is hardcoded in
+    // knownRootImports during init().
+    const compiler: StartCompiler = new StartCompiler({
+      env,
+      envName,
+      root: '/test',
+      framework: 'react' as const,
+      providerEnvName: 'ssr',
+      lookupKinds,
+      lookupConfigurations: [],
+      loadModule: async (id) => {
+        const code = virtualModules[id]
+        if (code) {
+          compiler.ingestModule({ code, id })
+        }
+      },
+      resolveId: async (id) => {
+        return virtualModules[id] ? id : null
+      },
+    })
+
+    return compiler
+  }
+
+  const testCases: Array<{
+    env: 'client' | 'server'
+    fn: string
+    shouldContain: Array<string>
+    shouldNotContain: Array<string>
+  }> = [
+    {
+      env: 'client',
+      fn: 'createIsomorphicFn',
+      shouldContain: ['client-theme'],
+      shouldNotContain: ['server-theme'],
+    },
+    {
+      env: 'server',
+      fn: 'createIsomorphicFn',
+      shouldContain: ['server-theme'],
+      shouldNotContain: ['client-theme'],
+    },
+    {
+      env: 'client',
+      fn: 'createClientOnlyFn',
+      shouldContain: ['client only initialization'],
+      shouldNotContain: [],
+    },
+    {
+      env: 'server',
+      fn: 'createClientOnlyFn',
+      shouldContain: ['throw new Error'],
+      shouldNotContain: ['client only initialization'],
+    },
+  ]
+
+  test.each(testCases)(
+    'resolves $fn via re-export chain on $env',
+    async ({ env, shouldContain, shouldNotContain }) => {
+      const compiler = createCompilerWithVirtualModules(env)
+      const code = virtualModules['@third-party/lib']!
+
+      const result = await compiler.compile({
+        code,
+        id: '@third-party/lib',
+      })
+
+      expect(result).not.toBeNull()
+      for (const str of shouldContain) {
+        expect(result!.code).toContain(str)
+      }
+      for (const str of shouldNotContain) {
+        expect(result!.code).not.toContain(str)
+      }
+    },
+  )
+
+  test('handles deeper re-export chains', async () => {
+    // Add another level to the chain
+    const deeperVirtualModules: Record<string, string> = {
+      ...virtualModules,
+      // Another intermediate package
+      '@another-intermediate/pkg': `
+        export { createIsomorphicFn } from '@tanstack/start-client-core'
+      `,
+      '@deep-third-party/lib': `
+        import { createIsomorphicFn } from '@another-intermediate/pkg'
+        export const deepFn = createIsomorphicFn()
+          .client(() => 'deep-client')
+          .server(() => 'deep-server')
+      `,
+    }
+
+    const compiler: StartCompiler = new StartCompiler({
+      env: 'client',
+      envName: 'client',
+      root: '/test',
+      framework: 'react' as const,
+      providerEnvName: 'ssr',
+      lookupKinds: new Set(['IsomorphicFn', 'ServerOnlyFn', 'ClientOnlyFn']),
+      lookupConfigurations: [],
+      loadModule: async (id) => {
+        const code = deeperVirtualModules[id]
+        if (code) {
+          compiler.ingestModule({ code, id })
+        }
+      },
+      resolveId: async (id) => {
+        return deeperVirtualModules[id] ? id : null
+      },
+    })
+
+    const result = await compiler.compile({
+      code: deeperVirtualModules['@deep-third-party/lib']!,
+      id: '@deep-third-party/lib',
+    })
+
+    expect(result).not.toBeNull()
+    expect(result!.code).toContain('deep-client')
+    expect(result!.code).not.toContain('deep-server')
+  })
+})
diff --git a/packages/start-plugin-core/tests/createServerFn/createServerFn.test.ts b/packages/start-plugin-core/tests/createServerFn/createServerFn.test.ts
index a861c51a82..a99eed371f 100644
--- a/packages/start-plugin-core/tests/createServerFn/createServerFn.test.ts
+++ b/packages/start-plugin-core/tests/createServerFn/createServerFn.test.ts
@@ -143,7 +143,7 @@ describe('createServerFn compiles correctly', async () => {
         id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJteVNlcnZlckZuX2NyZWF0ZVNlcnZlckZuX2hhbmRsZXIifQ",
         name: "myServerFn",
         filename: "src/test.ts"
-      }, (opts, signal) => myServerFn.__executeServer(opts, signal));
+      }, opts => myServerFn.__executeServer(opts));
       const myServerFn = createServerFn().handler(myServerFn_createServerFn_handler, myFunc);
       export { myServerFn_createServerFn_handler };"
     `)
@@ -204,7 +204,7 @@ describe('createServerFn compiles correctly', async () => {
         id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJleHBvcnRlZEZuX2NyZWF0ZVNlcnZlckZuX2hhbmRsZXIifQ",
         name: "exportedFn",
         filename: "src/test.ts"
-      }, (opts, signal) => exportedFn.__executeServer(opts, signal));
+      }, opts => exportedFn.__executeServer(opts));
       const exportedFn = createServerFn().handler(exportedFn_createServerFn_handler, async () => {
         return exportedVar;
       });
@@ -213,7 +213,7 @@ describe('createServerFn compiles correctly', async () => {
         id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJub25FeHBvcnRlZEZuX2NyZWF0ZVNlcnZlckZuX2hhbmRsZXIifQ",
         name: "nonExportedFn",
         filename: "src/test.ts"
-      }, (opts, signal) => nonExportedFn.__executeServer(opts, signal));
+      }, opts => nonExportedFn.__executeServer(opts));
       const nonExportedFn = createServerFn().handler(nonExportedFn_createServerFn_handler, async () => {
         return nonExportedVar;
       });
diff --git a/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructured.tsx b/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructured.tsx
index 4a5f22b80a..113c86dc5c 100644
--- a/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructured.tsx
+++ b/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructured.tsx
@@ -5,7 +5,7 @@ const withUseServer_createServerFn_handler = createServerRpc({
   id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJ3aXRoVXNlU2VydmVyX2NyZWF0ZVNlcnZlckZuX2hhbmRsZXIifQ",
   name: "withUseServer",
   filename: "src/test.ts"
-}, (opts, signal) => withUseServer.__executeServer(opts, signal));
+}, opts => withUseServer.__executeServer(opts));
 const withUseServer = createServerFn({
   method: 'GET'
 }).handler(withUseServer_createServerFn_handler, async function () {
@@ -17,7 +17,7 @@ const withArrowFunction_createServerFn_handler = createServerRpc({
   id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJ3aXRoQXJyb3dGdW5jdGlvbl9jcmVhdGVTZXJ2ZXJGbl9oYW5kbGVyIn0",
   name: "withArrowFunction",
   filename: "src/test.ts"
-}, (opts, signal) => withArrowFunction.__executeServer(opts, signal));
+}, opts => withArrowFunction.__executeServer(opts));
 const withArrowFunction = createServerFn({
   method: 'GET'
 }).handler(withArrowFunction_createServerFn_handler, async () => null);
@@ -25,7 +25,7 @@ const withArrowFunctionAndFunction_createServerFn_handler = createServerRpc({
   id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJ3aXRoQXJyb3dGdW5jdGlvbkFuZEZ1bmN0aW9uX2NyZWF0ZVNlcnZlckZuX2hhbmRsZXIifQ",
   name: "withArrowFunctionAndFunction",
   filename: "src/test.ts"
-}, (opts, signal) => withArrowFunctionAndFunction.__executeServer(opts, signal));
+}, opts => withArrowFunctionAndFunction.__executeServer(opts));
 const withArrowFunctionAndFunction = createServerFn({
   method: 'GET'
 }).handler(withArrowFunctionAndFunction_createServerFn_handler, async () => test());
@@ -33,7 +33,7 @@ const withoutUseServer_createServerFn_handler = createServerRpc({
   id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJ3aXRob3V0VXNlU2VydmVyX2NyZWF0ZVNlcnZlckZuX2hhbmRsZXIifQ",
   name: "withoutUseServer",
   filename: "src/test.ts"
-}, (opts, signal) => withoutUseServer.__executeServer(opts, signal));
+}, opts => withoutUseServer.__executeServer(opts));
 const withoutUseServer = createServerFn({
   method: 'GET'
 }).handler(withoutUseServer_createServerFn_handler, async () => {
@@ -45,7 +45,7 @@ const withVariable_createServerFn_handler = createServerRpc({
   id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJ3aXRoVmFyaWFibGVfY3JlYXRlU2VydmVyRm5faGFuZGxlciJ9",
   name: "withVariable",
   filename: "src/test.ts"
-}, (opts, signal) => withVariable.__executeServer(opts, signal));
+}, opts => withVariable.__executeServer(opts));
 const withVariable = createServerFn({
   method: 'GET'
 }).handler(withVariable_createServerFn_handler, abstractedFunction);
@@ -63,7 +63,7 @@ const withZodValidator_createServerFn_handler = createServerRpc({
   id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJ3aXRoWm9kVmFsaWRhdG9yX2NyZWF0ZVNlcnZlckZuX2hhbmRsZXIifQ",
   name: "withZodValidator",
   filename: "src/test.ts"
-}, (opts, signal) => withZodValidator.__executeServer(opts, signal));
+}, opts => withZodValidator.__executeServer(opts));
 const withZodValidator = createServerFn({
   method: 'GET'
 }).handler(withZodValidator_createServerFn_handler, zodValidator(z.number(), input => {
@@ -75,7 +75,7 @@ const withValidatorFn_createServerFn_handler = createServerRpc({
   id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJ3aXRoVmFsaWRhdG9yRm5fY3JlYXRlU2VydmVyRm5faGFuZGxlciJ9",
   name: "withValidatorFn",
   filename: "src/test.ts"
-}, (opts, signal) => withValidatorFn.__executeServer(opts, signal));
+}, opts => withValidatorFn.__executeServer(opts));
 const withValidatorFn = createServerFn({
   method: 'GET'
 }).inputValidator(z.number()).handler(withValidatorFn_createServerFn_handler, async ({
diff --git a/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructuredRename.tsx b/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructuredRename.tsx
index 0a88404f7d..69acc54cca 100644
--- a/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructuredRename.tsx
+++ b/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnDestructuredRename.tsx
@@ -5,7 +5,7 @@ const withUseServer_createServerFn_handler = createServerRpc({
   id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJ3aXRoVXNlU2VydmVyX2NyZWF0ZVNlcnZlckZuX2hhbmRsZXIifQ",
   name: "withUseServer",
   filename: "src/test.ts"
-}, (opts, signal) => withUseServer.__executeServer(opts, signal));
+}, opts => withUseServer.__executeServer(opts));
 const withUseServer = serverFn({
   method: 'GET'
 }).handler(withUseServer_createServerFn_handler, async function () {
@@ -17,7 +17,7 @@ const withoutUseServer_createServerFn_handler = createServerRpc({
   id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJ3aXRob3V0VXNlU2VydmVyX2NyZWF0ZVNlcnZlckZuX2hhbmRsZXIifQ",
   name: "withoutUseServer",
   filename: "src/test.ts"
-}, (opts, signal) => withoutUseServer.__executeServer(opts, signal));
+}, opts => withoutUseServer.__executeServer(opts));
 const withoutUseServer = serverFn({
   method: 'GET'
 }).handler(withoutUseServer_createServerFn_handler, async () => {
@@ -29,7 +29,7 @@ const withVariable_createServerFn_handler = createServerRpc({
   id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJ3aXRoVmFyaWFibGVfY3JlYXRlU2VydmVyRm5faGFuZGxlciJ9",
   name: "withVariable",
   filename: "src/test.ts"
-}, (opts, signal) => withVariable.__executeServer(opts, signal));
+}, opts => withVariable.__executeServer(opts));
 const withVariable = serverFn({
   method: 'GET'
 }).handler(withVariable_createServerFn_handler, abstractedFunction);
@@ -47,7 +47,7 @@ const withZodValidator_createServerFn_handler = createServerRpc({
   id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJ3aXRoWm9kVmFsaWRhdG9yX2NyZWF0ZVNlcnZlckZuX2hhbmRsZXIifQ",
   name: "withZodValidator",
   filename: "src/test.ts"
-}, (opts, signal) => withZodValidator.__executeServer(opts, signal));
+}, opts => withZodValidator.__executeServer(opts));
 const withZodValidator = serverFn({
   method: 'GET'
 }).handler(withZodValidator_createServerFn_handler, zodValidator(z.number(), input => {
diff --git a/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnStarImport.tsx b/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnStarImport.tsx
index 92e17b934e..b404a17c72 100644
--- a/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnStarImport.tsx
+++ b/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnStarImport.tsx
@@ -5,7 +5,7 @@ const withUseServer_createServerFn_handler = createServerRpc({
   id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJ3aXRoVXNlU2VydmVyX2NyZWF0ZVNlcnZlckZuX2hhbmRsZXIifQ",
   name: "withUseServer",
   filename: "src/test.ts"
-}, (opts, signal) => withUseServer.__executeServer(opts, signal));
+}, opts => withUseServer.__executeServer(opts));
 const withUseServer = TanStackStart.createServerFn({
   method: 'GET'
 }).handler(withUseServer_createServerFn_handler, async function () {
@@ -19,7 +19,7 @@ const withoutUseServer_createServerFn_handler = createServerRpc({
   id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJ3aXRob3V0VXNlU2VydmVyX2NyZWF0ZVNlcnZlckZuX2hhbmRsZXIifQ",
   name: "withoutUseServer",
   filename: "src/test.ts"
-}, (opts, signal) => withoutUseServer.__executeServer(opts, signal));
+}, opts => withoutUseServer.__executeServer(opts));
 const withoutUseServer = TanStackStart.createServerFn({
   method: 'GET'
 }).handler(withoutUseServer_createServerFn_handler, async () => {
@@ -31,7 +31,7 @@ const withVariable_createServerFn_handler = createServerRpc({
   id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJ3aXRoVmFyaWFibGVfY3JlYXRlU2VydmVyRm5faGFuZGxlciJ9",
   name: "withVariable",
   filename: "src/test.ts"
-}, (opts, signal) => withVariable.__executeServer(opts, signal));
+}, opts => withVariable.__executeServer(opts));
 const withVariable = TanStackStart.createServerFn({
   method: 'GET'
 }).handler(withVariable_createServerFn_handler, abstractedFunction);
@@ -49,7 +49,7 @@ const withZodValidator_createServerFn_handler = createServerRpc({
   id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJ3aXRoWm9kVmFsaWRhdG9yX2NyZWF0ZVNlcnZlckZuX2hhbmRsZXIifQ",
   name: "withZodValidator",
   filename: "src/test.ts"
-}, (opts, signal) => withZodValidator.__executeServer(opts, signal));
+}, opts => withZodValidator.__executeServer(opts));
 const withZodValidator = TanStackStart.createServerFn({
   method: 'GET'
 }).handler(withZodValidator_createServerFn_handler, zodValidator(z.number(), input => {
diff --git a/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnValidator.tsx b/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnValidator.tsx
index ae6c2eade6..4cd2ee74f2 100644
--- a/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnValidator.tsx
+++ b/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/createServerFnValidator.tsx
@@ -5,7 +5,7 @@ const withUseServer_createServerFn_handler = createServerRpc({
   id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJ3aXRoVXNlU2VydmVyX2NyZWF0ZVNlcnZlckZuX2hhbmRsZXIifQ",
   name: "withUseServer",
   filename: "src/test.ts"
-}, (opts, signal) => withUseServer.__executeServer(opts, signal));
+}, opts => withUseServer.__executeServer(opts));
 const withUseServer = createServerFn({
   method: 'GET'
 }).inputValidator(z.number()).handler(withUseServer_createServerFn_handler, ({
diff --git a/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/factory.tsx b/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/factory.tsx
index d906532e04..6041459061 100644
--- a/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/factory.tsx
+++ b/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/factory.tsx
@@ -28,7 +28,7 @@ const myAuthedFn_createServerFn_handler = createServerRpc({
   id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJteUF1dGhlZEZuX2NyZWF0ZVNlcnZlckZuX2hhbmRsZXIifQ",
   name: "myAuthedFn",
   filename: "src/test.ts"
-}, (opts, signal) => myAuthedFn.__executeServer(opts, signal));
+}, opts => myAuthedFn.__executeServer(opts));
 const myAuthedFn = createAuthServerFn().handler(myAuthedFn_createServerFn_handler, () => {
   return 'myAuthedFn';
 });
@@ -36,7 +36,7 @@ const deleteUserFn_createServerFn_handler = createServerRpc({
   id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJkZWxldGVVc2VyRm5fY3JlYXRlU2VydmVyRm5faGFuZGxlciJ9",
   name: "deleteUserFn",
   filename: "src/test.ts"
-}, (opts, signal) => deleteUserFn.__executeServer(opts, signal));
+}, opts => deleteUserFn.__executeServer(opts));
 const deleteUserFn = createAdminServerFn().handler(deleteUserFn_createServerFn_handler, () => {
   return 'deleteUserFn';
 });
diff --git a/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/isomorphic-fns.tsx b/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/isomorphic-fns.tsx
index e73d26d245..6ea0f20711 100644
--- a/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/isomorphic-fns.tsx
+++ b/packages/start-plugin-core/tests/createServerFn/snapshots/server-provider/isomorphic-fns.tsx
@@ -5,14 +5,14 @@ const getServerEnv_createServerFn_handler = createServerRpc({
   id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJnZXRTZXJ2ZXJFbnZfY3JlYXRlU2VydmVyRm5faGFuZGxlciJ9",
   name: "getServerEnv",
   filename: "src/test.ts"
-}, (opts, signal) => getServerEnv.__executeServer(opts, signal));
+}, opts => getServerEnv.__executeServer(opts));
 const getServerEnv = createServerFn().handler(getServerEnv_createServerFn_handler, () => getEnv());
 const getEcho = createIsomorphicFn().server((input: string) => 'server received ' + input).client(input => 'client received ' + input);
 const getServerEcho_createServerFn_handler = createServerRpc({
   id: "eyJmaWxlIjoiL0BpZC9zcmMvdGVzdC50cz90c3Mtc2VydmVyZm4tc3BsaXQiLCJleHBvcnQiOiJnZXRTZXJ2ZXJFY2hvX2NyZWF0ZVNlcnZlckZuX2hhbmRsZXIifQ",
   name: "getServerEcho",
   filename: "src/test.ts"
-}, (opts, signal) => getServerEcho.__executeServer(opts, signal));
+}, opts => getServerEcho.__executeServer(opts));
 const getServerEcho = createServerFn().inputValidator((input: string) => input).handler(getServerEcho_createServerFn_handler, ({
   data
 }) => getEcho(data));
diff --git a/packages/start-plugin-core/tests/prerender-ssrf.test.ts b/packages/start-plugin-core/tests/prerender-ssrf.test.ts
index 4a0551e8c3..397229f0f8 100644
--- a/packages/start-plugin-core/tests/prerender-ssrf.test.ts
+++ b/packages/start-plugin-core/tests/prerender-ssrf.test.ts
@@ -65,7 +65,11 @@ function resetFetch() {
 
 function makeStartConfig(pagePath: string) {
   return {
-    prerender: { enabled: true, autoStaticPathsDiscovery: false },
+    prerender: {
+      enabled: true,
+      autoStaticPathsDiscovery: false,
+      concurrency: 1,
+    },
     pages: [{ path: pagePath }],
     router: { basepath: '' },
     spa: {
@@ -97,4 +101,13 @@ describe('prerender pages validation', () => {
 
     await expect(prerender({ startConfig, builder })).resolves.not.toThrow()
   })
+
+  it('resolves when prerender filter matches no pages', async () => {
+    resetFetch()
+    const startConfig = makeStartConfig('/about')
+    startConfig.prerender.filter = () => false
+
+    await expect(prerender({ startConfig, builder })).resolves.not.toThrow()
+    expect(fetchMock).not.toHaveBeenCalled()
+  })
 })
diff --git a/packages/start-server-core/package.json b/packages/start-server-core/package.json
index 44826905bd..e11a8ee6d2 100644
--- a/packages/start-server-core/package.json
+++ b/packages/start-server-core/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/start-server-core",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
@@ -79,7 +79,7 @@
     "@tanstack/router-core": "workspace:*",
     "@tanstack/start-client-core": "workspace:*",
     "@tanstack/start-storage-context": "workspace:*",
-    "h3-v2": "npm:h3@2.0.1-rc.11",
+    "h3-v2": "npm:h3@2.0.1-rc.14",
     "seroval": "^1.4.2",
     "tiny-invariant": "^1.3.3"
   },
diff --git a/packages/start-server-core/src/createStartHandler.ts b/packages/start-server-core/src/createStartHandler.ts
index 7fa0e4a484..625e9cc487 100644
--- a/packages/start-server-core/src/createStartHandler.ts
+++ b/packages/start-server-core/src/createStartHandler.ts
@@ -19,6 +19,11 @@ import { runWithStartContext } from '@tanstack/start-storage-context'
 import { requestHandler } from './request-response'
 import { getStartManifest } from './router-manifest'
 import { handleServerAction } from './server-functions-handler'
+import {
+  buildManifestWithClientEntry,
+  resolveTransformConfig,
+  transformManifestUrls,
+} from './transformAssetUrls'
 
 import { HEADERS } from './constants'
 import { ServerFunctionSerializationAdapter } from './serializer/ServerFunctionSerializationAdapter'
@@ -39,6 +44,11 @@ import type {
   Register,
 } from '@tanstack/router-core'
 import type { HandlerCallback } from '@tanstack/router-core/ssr/server'
+import type {
+  StartManifestWithClientEntry,
+  TransformAssetUrls,
+  TransformAssetUrlsFn,
+} from './transformAssetUrls'
 
 type TODO = any
 
@@ -46,6 +56,61 @@ type AnyMiddlewareServerFn =
   | AnyRequestMiddleware['options']['server']
   | AnyFunctionMiddleware['options']['server']
 
+export interface CreateStartHandlerOptions {
+  handler: HandlerCallback<AnyRouter>
+  /**
+   * Transform asset URLs at runtime, e.g. to prepend a CDN prefix.
+   *
+   * **String** — a URL prefix prepended to every asset URL (cached by default):
+   * ```ts
+   * createStartHandler({
+   *   handler: defaultStreamHandler,
+   *   transformAssetUrls: 'https://cdn.example.com',
+   * })
+   * ```
+   *
+   * **Callback** — receives `{ url, type }` and returns a new URL
+   * (cached by default — runs once on first request):
+   * ```ts
+   * createStartHandler({
+   *   handler: defaultStreamHandler,
+   *   transformAssetUrls: ({ url, type }) => {
+   *     return `https://cdn.example.com${url}`
+   *   },
+   * })
+   * ```
+   *
+   * **Object** — for explicit cache control:
+   * ```ts
+   * createStartHandler({
+   *   handler: defaultStreamHandler,
+   *   transformAssetUrls: {
+   *     transform: ({ url }) => {
+   *       const region = getRequest().headers.get('x-region') || 'us'
+   *       return `https://cdn-${region}.example.com${url}`
+   *     },
+   *     cache: false, // transform per-request
+   *   },
+   * })
+   * ```
+   *
+   * `type` is one of `'modulepreload' | 'stylesheet' | 'clientEntry'`.
+   *
+   * By default, the transformed manifest is cached after the first request
+   * (`cache: true`). Set `cache: false` for per-request transforms.
+   *
+   * If you're using a cached transform, you can optionally set `warmup: true`
+   * (object form only) to compute the transformed manifest in the background at
+   * server startup.
+   *
+   * Note: This only transforms URLs managed by TanStack Start's manifest
+   * (JS preloads, CSS links, and the client entry script). For asset imports
+   * used directly in components (e.g. `import logo from './logo.svg'`),
+   * configure Vite's `experimental.renderBuiltUrl` in your vite.config.ts.
+   */
+  transformAssetUrls?: TransformAssetUrls
+}
+
 function getStartResponseHeaders(opts: { router: AnyRouter }) {
   const headers = mergeHeaders(
     {
@@ -66,7 +131,13 @@ let entriesPromise:
       routerEntry: RouterEntry
     }>
   | undefined
-let manifestPromise: Promise<Manifest> | undefined
+let baseManifestPromise: Promise<StartManifestWithClientEntry> | undefined
+
+/**
+ * Cached final manifest (with client entry script tag). In production,
+ * this is computed once and reused for every request when caching is enabled.
+ */
+let cachedFinalManifestPromise: Promise<Manifest> | undefined
 
 async function loadEntries() {
   // @ts-ignore when building, we currently don't respect tsconfig.ts' `include` so we are not picking up the .d.ts from start-client-core
@@ -83,16 +154,59 @@ function getEntries() {
   return entriesPromise
 }
 
-function getManifest(matchedRoutes?: ReadonlyArray<AnyRoute>) {
+/**
+ * Returns the raw manifest data (without client entry script tag baked in).
+ * In dev mode, always returns fresh data. In prod, cached.
+ */
+function getBaseManifest(
+  matchedRoutes?: ReadonlyArray<AnyRoute>,
+): Promise<StartManifestWithClientEntry> {
   // In dev mode, always get fresh manifest (no caching) to include route-specific dev styles
   if (process.env.TSS_DEV_SERVER === 'true') {
     return getStartManifest(matchedRoutes)
   }
-  // In prod, cache the manifest
-  if (!manifestPromise) {
-    manifestPromise = getStartManifest()
+  // In prod, cache the base manifest
+  if (!baseManifestPromise) {
+    baseManifestPromise = getStartManifest()
   }
-  return manifestPromise
+  return baseManifestPromise
+}
+
+/**
+ * Resolves a final Manifest for a given request.
+ *
+ * - No transform: builds client entry script tag and returns (cached in prod).
+ * - Cached transform: transforms all URLs + builds script tag, caches result.
+ * - Per-request transform: deep-clones base manifest, transforms per-request.
+ */
+async function resolveManifest(
+  matchedRoutes: ReadonlyArray<AnyRoute> | undefined,
+  transformFn: TransformAssetUrlsFn | undefined,
+  cache: boolean,
+): Promise<Manifest> {
+  const base = await getBaseManifest(matchedRoutes)
+
+  const computeFinalManifest = async () => {
+    return transformFn
+      ? await transformManifestUrls(base, transformFn, { clone: !cache })
+      : buildManifestWithClientEntry(base)
+  }
+
+  // In dev, always compute fresh to include route-specific dev styles.
+  if (process.env.TSS_DEV_SERVER === 'true') {
+    return computeFinalManifest()
+  }
+
+  // In prod, cache unless we're explicitly doing per-request transforms.
+  if (!transformFn || cache) {
+    if (!cachedFinalManifestPromise) {
+      cachedFinalManifestPromise = computeFinalManifest()
+    }
+    return cachedFinalManifestPromise
+  }
+
+  // Per-request transform — deep-clone and transform every time.
+  return computeFinalManifest()
 }
 
 // Pre-computed constants
@@ -206,9 +320,107 @@ function handlerToMiddleware(
   }
 }
 
+/**
+ * Creates the TanStack Start request handler.
+ *
+ * @example Backwards-compatible usage (handler callback only):
+ * ```ts
+ * export default createStartHandler(defaultStreamHandler)
+ * ```
+ *
+ * @example With CDN URL rewriting:
+ * ```ts
+ * export default createStartHandler({
+ *   handler: defaultStreamHandler,
+ *   transformAssetUrls: 'https://cdn.example.com',
+ * })
+ * ```
+ *
+ * @example With per-request URL rewriting:
+ * ```ts
+ * export default createStartHandler({
+ *   handler: defaultStreamHandler,
+ *   transformAssetUrls: {
+ *     transform: ({ url }) => {
+ *       const cdnBase = getRequest().headers.get('x-cdn-base') || ''
+ *       return `${cdnBase}${url}`
+ *     },
+ *     cache: false,
+ *   },
+ * })
+ * ```
+ */
 export function createStartHandler<TRegister = Register>(
-  cb: HandlerCallback<AnyRouter>,
+  cbOrOptions: HandlerCallback<AnyRouter> | CreateStartHandlerOptions,
 ): RequestHandler<TRegister> {
+  // Normalize the overloaded argument
+  const cb: HandlerCallback<AnyRouter> =
+    typeof cbOrOptions === 'function' ? cbOrOptions : cbOrOptions.handler
+  const transformAssetUrlsOption: TransformAssetUrls | undefined =
+    typeof cbOrOptions === 'function'
+      ? undefined
+      : cbOrOptions.transformAssetUrls
+
+  const warmupTransformManifest =
+    !!transformAssetUrlsOption &&
+    typeof transformAssetUrlsOption === 'object' &&
+    transformAssetUrlsOption.warmup === true
+
+  // Pre-resolve the transform function and cache flag
+  const resolvedTransformConfig = transformAssetUrlsOption
+    ? resolveTransformConfig(transformAssetUrlsOption)
+    : undefined
+  const cache = resolvedTransformConfig ? resolvedTransformConfig.cache : true
+
+  // Memoize a single createTransform() result when caching is enabled.
+  let cachedCreateTransformPromise: Promise<TransformAssetUrlsFn> | undefined
+
+  const getTransformFn = async (
+    opts: { warmup: true } | { warmup: false; request: Request },
+  ): Promise<TransformAssetUrlsFn | undefined> => {
+    if (!resolvedTransformConfig) return undefined
+    if (resolvedTransformConfig.type === 'createTransform') {
+      if (cache) {
+        if (!cachedCreateTransformPromise) {
+          cachedCreateTransformPromise = Promise.resolve(
+            resolvedTransformConfig.createTransform(opts),
+          )
+        }
+        return cachedCreateTransformPromise
+      }
+      return resolvedTransformConfig.createTransform(opts)
+    }
+    return resolvedTransformConfig.transformFn
+  }
+
+  // Background warmup for cached transforms (production only)
+  if (
+    warmupTransformManifest &&
+    cache &&
+    process.env.TSS_DEV_SERVER !== 'true' &&
+    !cachedFinalManifestPromise
+  ) {
+    // NOTE: Do not call resolveManifest() here.
+    // resolveManifest() reads from cachedFinalManifestPromise, and since we set
+    // cachedFinalManifestPromise to this warmup promise, that would create a
+    // self-referential promise and hang forever.
+    const warmupPromise = (async () => {
+      const base = await getBaseManifest(undefined)
+      const transformFn = await getTransformFn({ warmup: true })
+      return transformFn
+        ? await transformManifestUrls(base, transformFn, { clone: false })
+        : buildManifestWithClientEntry(base)
+    })()
+    cachedFinalManifestPromise = warmupPromise
+    warmupPromise.catch(() => {
+      // If warmup fails, allow the next request to retry.
+      if (cachedFinalManifestPromise === warmupPromise) {
+        cachedFinalManifestPromise = undefined
+      }
+      cachedCreateTransformPromise = undefined
+    })
+  }
+
   const startRequestResolver: RequestHandler<Register> = async (
     request,
     requestOpts,
@@ -218,10 +430,16 @@ export function createStartHandler<TRegister = Register>(
 
     try {
       // normalizing and sanitizing the pathname here for server, so we always deal with the same format during SSR.
-      const url = getNormalizedURL(request.url)
+      // during normalization paths like '//posts' are flattened to '/posts'.
+      // in these cases we would prefer to redirect to the new path
+      const { url, handledProtocolRelativeURL } = getNormalizedURL(request.url)
       const href = url.pathname + url.search + url.hash
       const origin = getOrigin(request)
 
+      if (handledProtocolRelativeURL) {
+        return Response.redirect(url, 308)
+      }
+
       const entries = await getEntries()
       const startOptions: AnyStartInstanceOptions =
         (await entries.startEntry.startInstance?.getOptions()) ||
@@ -313,6 +531,7 @@ export function createStartHandler<TRegister = Register>(
         )
         const ctx = await executeMiddleware([...middlewares, serverFnHandler], {
           request,
+          pathname: url.pathname,
           context: createNullProtoObject(requestOpts?.context),
         })
 
@@ -339,7 +558,11 @@ export function createStartHandler<TRegister = Register>(
           )
         }
 
-        const manifest = await getManifest(matchedRoutes)
+        const manifest = await resolveManifest(
+          matchedRoutes,
+          await getTransformFn({ warmup: false, request }),
+          cache,
+        )
         const routerInstance = await getRouter()
 
         attachRouterServerSsrUtils({
@@ -403,7 +626,11 @@ export function createStartHandler<TRegister = Register>(
       )
       const ctx = await executeMiddleware(
         [...middlewares, requestHandlerMiddleware],
-        { request, context: createNullProtoObject(requestOpts?.context) },
+        {
+          request,
+          pathname: url.pathname,
+          context: createNullProtoObject(requestOpts?.context),
+        },
       )
 
       return handleRedirectResponse(ctx.response, request, getRouter)
diff --git a/packages/start-server-core/src/index.tsx b/packages/start-server-core/src/index.tsx
index 5a4d633e5c..aafbab0002 100644
--- a/packages/start-server-core/src/index.tsx
+++ b/packages/start-server-core/src/index.tsx
@@ -1,4 +1,13 @@
 export { createStartHandler } from './createStartHandler'
+export type { CreateStartHandlerOptions } from './createStartHandler'
+
+export type {
+  TransformAssetUrls,
+  TransformAssetUrlsFn,
+  TransformAssetUrlsContext,
+  TransformAssetUrlsOptions,
+  AssetUrlType,
+} from './transformAssetUrls'
 
 export {
   attachRouterServerSsrUtils,
diff --git a/packages/start-server-core/src/router-manifest.ts b/packages/start-server-core/src/router-manifest.ts
index c31435fbf7..ceec7eaf4e 100644
--- a/packages/start-server-core/src/router-manifest.ts
+++ b/packages/start-server-core/src/router-manifest.ts
@@ -1,21 +1,25 @@
 import { buildDevStylesUrl, rootRouteId } from '@tanstack/router-core'
 import type { AnyRoute, RouterManagedTag } from '@tanstack/router-core'
+import type { StartManifestWithClientEntry } from './transformAssetUrls'
 
 // Pre-computed constant for dev styles URL
 const ROUTER_BASEPATH = process.env.TSS_ROUTER_BASEPATH || '/'
 
 /**
- * @description Returns the router manifest that should be sent to the client.
+ * @description Returns the router manifest data that should be sent to the client.
  * This includes only the assets and preloads for the current route and any
  * special assets that are needed for the client. It does not include relationships
  * between routes or any other data that is not needed for the client.
  *
+ * The client entry URL is returned separately so that it can be transformed
+ * (e.g. for CDN rewriting) before being embedded into the `<script>` tag.
+ *
  * @param matchedRoutes - In dev mode, the matched routes are used to build
  * the dev styles URL for route-scoped CSS collection.
  */
 export async function getStartManifest(
   matchedRoutes?: ReadonlyArray<AnyRoute>,
-) {
+): Promise<StartManifestWithClientEntry> {
   const { tsrStartManifest } = await import('tanstack-start-manifest:v')
   const startManifest = tsrStartManifest()
 
@@ -37,22 +41,15 @@ export async function getStartManifest(
     })
   }
 
-  let script = `import('${startManifest.clientEntry}')`
+  // Collect injected head scripts in dev mode (returned separately so we can
+  // build the client entry script tag after URL transforms are applied)
+  let injectedHeadScripts: string | undefined
   if (process.env.TSS_DEV_SERVER === 'true') {
-    const { injectedHeadScripts } =
-      await import('tanstack-start-injected-head-scripts:v')
-    if (injectedHeadScripts) {
-      script = `${injectedHeadScripts + ';'}${script}`
+    const mod = await import('tanstack-start-injected-head-scripts:v')
+    if (mod.injectedHeadScripts) {
+      injectedHeadScripts = mod.injectedHeadScripts
     }
   }
-  rootRoute.assets.push({
-    tag: 'script',
-    attrs: {
-      type: 'module',
-      async: true,
-    },
-    children: script,
-  })
 
   const manifest = {
     routes: Object.fromEntries(
@@ -78,6 +75,9 @@ export async function getStartManifest(
     ),
   }
 
-  // Strip out anything that isn't needed for the client
-  return manifest
+  return {
+    manifest,
+    clientEntry: startManifest.clientEntry,
+    injectedHeadScripts,
+  }
 }
diff --git a/packages/start-server-core/src/server-functions-handler.ts b/packages/start-server-core/src/server-functions-handler.ts
index 9333095e90..fdc6fb0672 100644
--- a/packages/start-server-core/src/server-functions-handler.ts
+++ b/packages/start-server-core/src/server-functions-handler.ts
@@ -44,11 +44,6 @@ export const handleServerAction = async ({
   context: any
   serverFnId: string
 }) => {
-  const controller = new AbortController()
-  const signal = controller.signal
-  const abort = () => controller.abort()
-  request.signal.addEventListener('abort', abort)
-
   const method = request.method
   const methodUpper = method.toUpperCase()
   const methodLower = method.toLowerCase()
@@ -116,7 +111,7 @@ export const handleServerAction = async ({
             }
           }
 
-          return await action(params, signal)
+          return await action(params)
         }
 
         // Get requests use the query string
@@ -134,7 +129,7 @@ export const handleServerAction = async ({
           payload.context = safeObjectMerge(context, payload.context)
           payload.method = methodUpper
           // Send it through!
-          return await action(payload, signal)
+          return await action(payload)
         }
 
         if (methodLower !== 'post') {
@@ -149,7 +144,7 @@ export const handleServerAction = async ({
         const payload = jsonPayload ? parsePayload(jsonPayload) : {}
         payload.context = safeObjectMerge(payload.context, context)
         payload.method = methodUpper
-        return await action(payload, signal)
+        return await action(payload)
       })()
 
       const unwrapped = res.result || res.error
@@ -356,8 +351,6 @@ export const handleServerAction = async ({
     }
   })()
 
-  request.signal.removeEventListener('abort', abort)
-
   return response
 }
 
diff --git a/packages/start-server-core/src/transformAssetUrls.ts b/packages/start-server-core/src/transformAssetUrls.ts
new file mode 100644
index 0000000000..50ab5f4dc9
--- /dev/null
+++ b/packages/start-server-core/src/transformAssetUrls.ts
@@ -0,0 +1,285 @@
+import { rootRouteId } from '@tanstack/router-core'
+
+import type {
+  Awaitable,
+  Manifest,
+  RouterManagedTag,
+} from '@tanstack/router-core'
+
+export type AssetUrlType = 'modulepreload' | 'stylesheet' | 'clientEntry'
+
+export interface TransformAssetUrlsContext {
+  url: string
+  type: AssetUrlType
+}
+
+export type TransformAssetUrlsFn = (
+  context: TransformAssetUrlsContext,
+) => Awaitable<string>
+
+export type CreateTransformAssetUrlsContext =
+  | {
+      /** True when the server is computing the cached manifest during startup warmup. */
+      warmup: true
+    }
+  | {
+      /**
+       * The current Request.
+       *
+       * Only available during request handling (i.e. when `warmup: false`).
+       */
+      request: Request
+      /** False when transforming URLs as part of request handling. */
+      warmup: false
+    }
+
+/**
+ * Async factory that runs once per manifest computation and returns the
+ * per-asset transform.
+ */
+export type CreateTransformAssetUrlsFn = (
+  ctx: CreateTransformAssetUrlsContext,
+) => Awaitable<TransformAssetUrlsFn>
+
+type TransformAssetUrlsOptionsBase = {
+  /**
+   * Whether to cache the transformed manifest after the first request.
+   *
+   * When `true` (default), the transform runs once on the first request and
+   * the resulting manifest is reused for all subsequent requests in production.
+   *
+   * Set to `false` for per-request transforms (e.g. geo-routing to different
+   * CDNs based on request headers).
+   *
+   * @default true
+   */
+  cache?: boolean
+
+  /**
+   * When `true`, warms up the cached transformed manifest in the background when
+   * the server starts (production only).
+   *
+   * This can reduce latency for the first request when `cache` is `true`.
+   * Has no effect when `cache: false` (per-request transforms) or in dev mode.
+   *
+   * @default false
+   */
+  warmup?: boolean
+}
+
+export type TransformAssetUrlsOptions =
+  | (TransformAssetUrlsOptionsBase & {
+      /**
+       * The transform to apply to asset URLs. Can be a string prefix or a callback.
+       *
+       * **String** — prepended to every asset URL.
+       * **Callback** — receives `{ url, type }` and returns a new URL.
+       */
+      transform: string | TransformAssetUrlsFn
+      createTransform?: never
+    })
+  | (TransformAssetUrlsOptionsBase & {
+      /**
+       * Create a per-asset transform function.
+       *
+       * This factory runs once per manifest computation (per request when
+       * `cache: false`, or once per server when `cache: true`). It can do async
+       * setup work (fetch config, read from a KV, etc.) and return a fast
+       * per-asset transformer.
+       */
+      createTransform: CreateTransformAssetUrlsFn
+      transform?: never
+    })
+
+export type TransformAssetUrls =
+  | string
+  | TransformAssetUrlsFn
+  | TransformAssetUrlsOptions
+
+export type ResolvedTransformAssetUrlsConfig =
+  | {
+      type: 'transform'
+      transformFn: TransformAssetUrlsFn
+      cache: boolean
+    }
+  | {
+      type: 'createTransform'
+      createTransform: CreateTransformAssetUrlsFn
+      cache: boolean
+    }
+
+/**
+ * Resolves a TransformAssetUrls value (string prefix, callback, or options
+ * object) into a concrete transform function and cache flag.
+ */
+export function resolveTransformConfig(
+  transform: TransformAssetUrls,
+): ResolvedTransformAssetUrlsConfig {
+  // String shorthand
+  if (typeof transform === 'string') {
+    const prefix = transform
+    return {
+      type: 'transform',
+      transformFn: ({ url }) => `${prefix}${url}`,
+      cache: true,
+    }
+  }
+
+  // Callback shorthand
+  if (typeof transform === 'function') {
+    return {
+      type: 'transform',
+      transformFn: transform,
+      cache: true,
+    }
+  }
+
+  // Options object
+  if ('createTransform' in transform && transform.createTransform) {
+    return {
+      type: 'createTransform',
+      createTransform: transform.createTransform,
+      cache: transform.cache !== false,
+    }
+  }
+
+  const transformFn =
+    typeof transform.transform === 'string'
+      ? ((({ url }: TransformAssetUrlsContext) =>
+          `${transform.transform}${url}`) as TransformAssetUrlsFn)
+      : transform.transform
+
+  return {
+    type: 'transform',
+    transformFn,
+    cache: transform.cache !== false,
+  }
+}
+
+export interface StartManifestWithClientEntry {
+  manifest: Manifest
+  clientEntry: string
+  /** Script content prepended before the client entry import (dev only) */
+  injectedHeadScripts?: string
+}
+
+/**
+ * Builds the client entry `<script>` tag from a (possibly transformed) client
+ * entry URL and optional injected head scripts.
+ */
+export function buildClientEntryScriptTag(
+  clientEntry: string,
+  injectedHeadScripts?: string,
+): RouterManagedTag {
+  const clientEntryLiteral = JSON.stringify(clientEntry)
+  let script = `import(${clientEntryLiteral})`
+  if (injectedHeadScripts) {
+    script = `${injectedHeadScripts};${script}`
+  }
+  return {
+    tag: 'script',
+    attrs: {
+      type: 'module',
+      async: true,
+    },
+    children: script,
+  }
+}
+
+/**
+ * Applies a URL transform to every asset URL in the manifest and returns a
+ * new manifest with a client entry script tag appended to the root route's
+ * assets.
+ *
+ * The source manifest is deep-cloned so the cached original is never mutated.
+ */
+export function transformManifestUrls(
+  source: StartManifestWithClientEntry,
+  transformFn: TransformAssetUrlsFn,
+  opts?: {
+    /** When true, clone the source manifest before mutating it. */
+    clone?: boolean
+  },
+): Promise<Manifest> {
+  return (async () => {
+    const manifest = opts?.clone
+      ? structuredClone(source.manifest)
+      : source.manifest
+
+    for (const route of Object.values(manifest.routes)) {
+      // Transform preload URLs (modulepreload)
+      if (route.preloads) {
+        route.preloads = await Promise.all(
+          route.preloads.map((url) =>
+            Promise.resolve(transformFn({ url, type: 'modulepreload' })),
+          ),
+        )
+      }
+
+      // Transform asset tag URLs
+      if (route.assets) {
+        for (const asset of route.assets) {
+          if (asset.tag === 'link' && asset.attrs?.href) {
+            asset.attrs.href = await Promise.resolve(
+              transformFn({
+                url: asset.attrs.href,
+                type: 'stylesheet',
+              }),
+            )
+          }
+        }
+      }
+    }
+
+    // Transform and append the client entry script tag
+    const transformedClientEntry = await Promise.resolve(
+      transformFn({
+        url: source.clientEntry,
+        type: 'clientEntry',
+      }),
+    )
+
+    const rootRoute = manifest.routes[rootRouteId]
+    if (rootRoute) {
+      rootRoute.assets = rootRoute.assets || []
+      rootRoute.assets.push(
+        buildClientEntryScriptTag(
+          transformedClientEntry,
+          source.injectedHeadScripts,
+        ),
+      )
+    }
+
+    return manifest
+  })()
+}
+
+/**
+ * Builds a final Manifest from a StartManifestWithClientEntry without any
+ * URL transforms. Used when no transformAssetUrls option is provided.
+ *
+ * Returns a new manifest object so the cached base manifest is never mutated.
+ */
+export function buildManifestWithClientEntry(
+  source: StartManifestWithClientEntry,
+): Manifest {
+  const scriptTag = buildClientEntryScriptTag(
+    source.clientEntry,
+    source.injectedHeadScripts,
+  )
+
+  const baseRootRoute = source.manifest.routes[rootRouteId]
+  const routes = {
+    ...source.manifest.routes,
+    ...(baseRootRoute
+      ? {
+          [rootRouteId]: {
+            ...baseRootRoute,
+            assets: [...(baseRootRoute.assets || []), scriptTag],
+          },
+        }
+      : {}),
+  }
+
+  return { routes }
+}
diff --git a/packages/start-static-server-functions/package.json b/packages/start-static-server-functions/package.json
index d11dee8fa5..6b30bdc54b 100644
--- a/packages/start-static-server-functions/package.json
+++ b/packages/start-static-server-functions/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/start-static-server-functions",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/start-storage-context/package.json b/packages/start-storage-context/package.json
index 6d3b90e431..d3d96be030 100644
--- a/packages/start-storage-context/package.json
+++ b/packages/start-storage-context/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/start-storage-context",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/valibot-adapter/package.json b/packages/valibot-adapter/package.json
index 7aca20ed1a..ae8d02e994 100644
--- a/packages/valibot-adapter/package.json
+++ b/packages/valibot-adapter/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/valibot-adapter",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/vue-router-devtools/package.json b/packages/vue-router-devtools/package.json
index b5ea02b9f8..b48e9eea2d 100644
--- a/packages/vue-router-devtools/package.json
+++ b/packages/vue-router-devtools/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/vue-router-devtools",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for Vue applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/vue-router-ssr-query/package.json b/packages/vue-router-ssr-query/package.json
index b85675647e..330a21d7aa 100644
--- a/packages/vue-router-ssr-query/package.json
+++ b/packages/vue-router-ssr-query/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/vue-router-ssr-query",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for Vue applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/vue-router/README.md b/packages/vue-router/README.md
index 25c561a896..383a15d84d 100644
--- a/packages/vue-router/README.md
+++ b/packages/vue-router/README.md
@@ -2,7 +2,7 @@
 
 # TanStack Vue Router
 
-![TanStack Router Header](https://github.com/tanstack/router/raw/main/media/header_router.png)
+![TanStack Router Header](https://raw.githubusercontent.com/TanStack/router/main/media/header_router.png)
 
 🤖 Type-safe router w/ built-in caching & URL state management for Vue!
 
@@ -16,9 +16,9 @@
   <img alt="" src="https://badgen.net/bundlephobia/minzip/@tanstack/vue-router" />
 </a><a href="#badge">
     <img alt="semantic-release" src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg">
-  </a><a href="https://github.com/tanstack/router/discussions">
+  </a><a href="https://github.com/TanStack/router/discussions">
   <img alt="Join the discussion on Github" src="https://img.shields.io/badge/Github%20Discussions%20%26%20Support-Chat%20now!-blue" />
-</a><a href="https://bestofjs.org/projects/router"><img alt="Best of JS" src="https://img.shields.io/endpoint?url=https://bestofjs-serverless.now.sh/api/project-badge?fullName=tanstack%2Frouter%26since=daily" /></a><a href="https://github.com/tanstack/router" target="\_parent">
+</a><a href="https://bestofjs.org/projects/router"><img alt="Best of JS" src="https://img.shields.io/endpoint?url=https://bestofjs-serverless.now.sh/api/project-badge?fullName=tanstack%2Frouter%26since=daily" /></a><a href="https://github.com/TanStack/router" target="\_parent">
   <img alt="" src="https://img.shields.io/github/stars/tanstack/router.svg?style=social&label=Star" />
 </a><a href="https://twitter.com/tan_stack" target="\_parent">
   <img alt="" src="https://img.shields.io/twitter/follow/tan_stack.svg?style=social&label=Follow @TanStack" />
diff --git a/packages/vue-router/package.json b/packages/vue-router/package.json
index cbe21aa280..5f0f7916aa 100644
--- a/packages/vue-router/package.json
+++ b/packages/vue-router/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/vue-router",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for Vue applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/vue-router/src/Asset.tsx b/packages/vue-router/src/Asset.tsx
index 80f61398f9..128ffa8ad3 100644
--- a/packages/vue-router/src/Asset.tsx
+++ b/packages/vue-router/src/Asset.tsx
@@ -54,9 +54,16 @@ const Script = Vue.defineComponent({
   },
   setup(props) {
     const router = useRouter()
+    const dataScript =
+      typeof props.attrs?.type === 'string' &&
+      props.attrs.type !== '' &&
+      props.attrs.type !== 'text/javascript' &&
+      props.attrs.type !== 'module'
 
     if (!(isServer ?? router.isServer)) {
       Vue.onMounted(() => {
+        if (dataScript) return
+
         const attrs = props.attrs
         const children = props.children
 
@@ -132,6 +139,14 @@ const Script = Vue.defineComponent({
 
     return () => {
       if (!(isServer ?? router.isServer)) {
+        if (dataScript && typeof props.children === 'string') {
+          return Vue.h('script', {
+            ...props.attrs,
+            'data-allow-mismatch': true,
+            innerHTML: props.children,
+          })
+        }
+
         const { src: _src, ...rest } = props.attrs || {}
         return Vue.h('script', {
           ...rest,
diff --git a/packages/vue-router/src/index.tsx b/packages/vue-router/src/index.tsx
index 61c15c53f6..9aaf0aca21 100644
--- a/packages/vue-router/src/index.tsx
+++ b/packages/vue-router/src/index.tsx
@@ -243,7 +243,12 @@ export { useMatch } from './useMatch'
 export { useLoaderDeps } from './useLoaderDeps'
 export { useLoaderData } from './useLoaderData'
 
-export { redirect, isRedirect, createRouterConfig } from '@tanstack/router-core'
+export {
+  redirect,
+  isRedirect,
+  createRouterConfig,
+  DEFAULT_PROTOCOL_ALLOWLIST,
+} from '@tanstack/router-core'
 
 export {
   RouteApi,
diff --git a/packages/vue-router/src/link.tsx b/packages/vue-router/src/link.tsx
index 43ed59bc33..d6ed9b1ca1 100644
--- a/packages/vue-router/src/link.tsx
+++ b/packages/vue-router/src/link.tsx
@@ -251,8 +251,8 @@ export function useLinkProps<
   }
 
   if (type.value === 'external') {
-    // Block dangerous protocols like javascript:, data:, vbscript:
-    if (isDangerousProtocol(options.to as string)) {
+    // Block dangerous protocols like javascript:, blob:, data:
+    if (isDangerousProtocol(options.to as string, router.protocolAllowlist)) {
       if (process.env.NODE_ENV !== 'production') {
         console.warn(`Blocked Link with dangerous protocol: ${options.to}`)
       }
diff --git a/packages/vue-router/src/useMatch.tsx b/packages/vue-router/src/useMatch.tsx
index 0c527f6681..7784f3018c 100644
--- a/packages/vue-router/src/useMatch.tsx
+++ b/packages/vue-router/src/useMatch.tsx
@@ -1,4 +1,5 @@
 import * as Vue from 'vue'
+import { useRouter } from './useRouter'
 import { useRouterState } from './useRouterState'
 import { injectDummyMatch, injectMatch } from './matchContext'
 import type {
@@ -68,6 +69,7 @@ export function useMatch<
 ): Vue.Ref<
   ThrowOrOptional<UseMatchResult<TRouter, TFrom, TStrict, TSelected>, TThrow>
 > {
+  const router = useRouter<TRouter>()
   const nearestMatchId = opts.from ? injectDummyMatch() : injectMatch()
 
   // Store to track pending error for deferred throwing
@@ -81,13 +83,14 @@ export function useMatch<
       )
 
       if (match === undefined) {
-        // During navigation transitions, check if the match exists in pendingMatches
-        const pendingMatch = state.pendingMatches?.find((d: any) =>
-          opts.from ? opts.from === d.routeId : d.id === nearestMatchId.value,
-        )
+        const hasPendingMatch =
+          state.status === 'pending' &&
+          router.matchRoutes(router.latestLocation).some((d: any) =>
+            opts.from ? opts.from === d.routeId : d.id === nearestMatchId.value,
+          )
 
         // If there's a pending match or we're transitioning, return undefined without throwing
-        if (pendingMatch || state.isTransitioning) {
+        if (hasPendingMatch || state.isTransitioning) {
           pendingError.value = null
           return undefined
         }
diff --git a/packages/vue-router/tests/link.test.tsx b/packages/vue-router/tests/link.test.tsx
index ca9a446f55..0165bbc092 100644
--- a/packages/vue-router/tests/link.test.tsx
+++ b/packages/vue-router/tests/link.test.tsx
@@ -5725,20 +5725,20 @@ describe('relative links to current route', () => {
       const searchButton = await screen.findByTestId('search-link')
       const searchButton2 = await screen.findByTestId('search2-link')
 
-      fireEvent.click(postButton)
+      await fireEvent.click(postButton)
 
       await waitFor(() => {
         expect(window.location.pathname).toBe(`/post${tail}`)
       })
 
-      fireEvent.click(searchButton)
+      await fireEvent.click(searchButton)
 
       await waitFor(() => {
         expect(router.state.location.pathname).toBe(`/post${tail}`)
         expect(router.state.location.search).toEqual({ param1: 'value1' })
       })
 
-      fireEvent.click(searchButton2)
+      await fireEvent.click(searchButton2)
 
       await waitFor(() => {
         expect(router.state.location.pathname).toBe(`/post${tail}`)
@@ -6003,7 +6003,7 @@ describe('relative links to from route', () => {
 
       const postButton = await screen.findByTestId('posts-link')
 
-      fireEvent.click(postButton)
+      await fireEvent.click(postButton)
 
       await waitFor(() => {
         expect(router.state.location.pathname).toBe(`/post${tail}`)
@@ -6011,7 +6011,7 @@ describe('relative links to from route', () => {
 
       const searchButton = await screen.findByTestId('search-link')
 
-      fireEvent.click(searchButton)
+      await fireEvent.click(searchButton)
 
       await waitFor(() => {
         expect(router.state.location.pathname).toBe(`/post${tail}`)
@@ -6020,7 +6020,7 @@ describe('relative links to from route', () => {
 
       const homeBtn = await screen.findByTestId('home-link')
 
-      fireEvent.click(homeBtn)
+      await fireEvent.click(homeBtn)
 
       await waitFor(() => {
         expect(router.state.location.pathname).toBe(`/`)
diff --git a/packages/vue-router/tests/useMatch.test.tsx b/packages/vue-router/tests/useMatch.test.tsx
index 2c3575f052..7bd18916ae 100644
--- a/packages/vue-router/tests/useMatch.test.tsx
+++ b/packages/vue-router/tests/useMatch.test.tsx
@@ -9,6 +9,7 @@ import {
   createRoute,
   createRouter,
   useMatch,
+  useRouterState,
 } from '../src'
 import type { RouteComponent, RouterHistory } from '../src'
 
@@ -116,4 +117,130 @@ describe('useMatch', () => {
       })
     })
   })
+
+  describe('pending transitions', () => {
+    test('does not throw while transitioning to a pending matching route', async () => {
+      let resolvePostsLoader!: () => void
+      const postsLoaderPromise = new Promise<void>((resolve) => {
+        resolvePostsLoader = resolve
+      })
+
+      function PendingProbe() {
+        useMatch({ from: '/posts', shouldThrow: true })
+        return null
+      }
+
+      function RootComponent() {
+        const routerState = useRouterState()
+        return (
+          <>
+            {routerState.value.status === 'pending' ? <PendingProbe /> : null}
+            <Outlet />
+          </>
+        )
+      }
+
+      const rootRoute = createRootRoute({
+        component: RootComponent,
+      })
+      const indexRoute = createRoute({
+        getParentRoute: () => rootRoute,
+        path: '/',
+        component: () => <h1>IndexTitle</h1>,
+      })
+      const postsRoute = createRoute({
+        getParentRoute: () => rootRoute,
+        path: '/posts',
+        loader: async () => {
+          await postsLoaderPromise
+        },
+        component: () => <h1>PostsTitle</h1>,
+      })
+
+      const router = createRouter({
+        routeTree: rootRoute.addChildren([indexRoute, postsRoute]),
+        history: createMemoryHistory({ initialEntries: ['/'] }),
+      })
+
+      render(<RouterProvider router={router} />)
+
+      await screen.findByText('IndexTitle')
+
+      const navigation = router.navigate({ to: '/posts' })
+      await waitFor(() => {
+        expect(router.state.status).toBe('pending')
+      })
+
+      expect(
+        screen.queryByText(
+          'Invariant failed: Could not find an active match from "/posts"',
+        ),
+      ).not.toBeInTheDocument()
+
+      resolvePostsLoader()
+      await navigation
+      expect(await screen.findByText('PostsTitle')).toBeInTheDocument()
+    })
+
+    test('still throws during pending transition when route is not pending', async () => {
+      let resolveOtherLoader!: () => void
+      const otherLoaderPromise = new Promise<void>((resolve) => {
+        resolveOtherLoader = resolve
+      })
+
+      function PendingProbe() {
+        useMatch({ from: '/posts', shouldThrow: true })
+        return null
+      }
+
+      function RootComponent() {
+        const routerState = useRouterState()
+        return (
+          <>
+            {routerState.value.status === 'pending' ? <PendingProbe /> : null}
+            <Outlet />
+          </>
+        )
+      }
+
+      const rootRoute = createRootRoute({
+        component: RootComponent,
+      })
+      const indexRoute = createRoute({
+        getParentRoute: () => rootRoute,
+        path: '/',
+        component: () => <h1>IndexTitle</h1>,
+      })
+      const postsRoute = createRoute({
+        getParentRoute: () => rootRoute,
+        path: '/posts',
+        component: () => <h1>PostsTitle</h1>,
+      })
+      const otherRoute = createRoute({
+        getParentRoute: () => rootRoute,
+        path: '/other',
+        loader: async () => {
+          await otherLoaderPromise
+        },
+        component: () => <h1>OtherTitle</h1>,
+      })
+
+      const router = createRouter({
+        routeTree: rootRoute.addChildren([indexRoute, postsRoute, otherRoute]),
+        history: createMemoryHistory({ initialEntries: ['/'] }),
+      })
+
+      render(<RouterProvider router={router} />)
+      await screen.findByText('IndexTitle')
+
+      const navigation = router.navigate({ to: '/other' }).catch(() => {})
+      const errorText = await screen.findByText(
+        'Invariant failed: Could not find an active match from "/posts"',
+      )
+      expect(errorText).toBeInTheDocument()
+
+      resolveOtherLoader()
+      await navigation
+    })
+  })
 })
diff --git a/packages/vue-start-client/package.json b/packages/vue-start-client/package.json
index 166c9c543c..2805e50af9 100644
--- a/packages/vue-start-client/package.json
+++ b/packages/vue-start-client/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/vue-start-client",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for Vue applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/vue-start-server/package.json b/packages/vue-start-server/package.json
index 407a1f55f8..acbe1417fe 100644
--- a/packages/vue-start-server/package.json
+++ b/packages/vue-start-server/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/vue-start-server",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for Vue applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/vue-start/package.json b/packages/vue-start/package.json
index 07052c049c..1ab2190f2d 100644
--- a/packages/vue-start/package.json
+++ b/packages/vue-start/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/vue-start",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for Vue applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/packages/zod-adapter/package.json b/packages/zod-adapter/package.json
index 6b7605b6f4..a123c65730 100644
--- a/packages/zod-adapter/package.json
+++ b/packages/zod-adapter/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@tanstack/zod-adapter",
-  "version": "1.158.0",
+  "version": "1.160.0",
   "description": "Modern and scalable routing for React applications",
   "author": "Tanner Linsley",
   "license": "MIT",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 73bb9516f5..ed22242280 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1144,8 +1144,8 @@ importers:
         specifier: ^1.1.11
         version: 1.1.11
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -1354,8 +1354,8 @@ importers:
         specifier: ^4.3.4
         version: 4.3.4(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -1449,8 +1449,8 @@ importers:
         specifier: ^19.2.3
         version: 19.2.3(@types/react@19.2.8)
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       typescript:
         specifier: ^5.7.2
         version: 5.8.2
@@ -1550,8 +1550,8 @@ importers:
         specifier: ^19.2.3
         version: 19.2.3(@types/react@19.2.8)
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       typescript:
         specifier: ^5.7.2
         version: 5.9.2
@@ -1599,8 +1599,8 @@ importers:
         specifier: ^1.97.2
         version: 1.97.2
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       typescript:
         specifier: ^5.7.2
         version: 5.9.2
@@ -1666,8 +1666,8 @@ importers:
         specifier: ^10.0.0
         version: 10.0.0
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -1904,8 +1904,8 @@ importers:
         specifier: ^1.1.11
         version: 1.1.11
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -1962,8 +1962,8 @@ importers:
         specifier: ^4.3.4
         version: 4.6.0(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -2017,8 +2017,8 @@ importers:
         specifier: ^4.3.4
         version: 4.6.0(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -2093,8 +2093,8 @@ importers:
         specifier: ^1.1.11
         version: 1.1.11
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -2145,8 +2145,8 @@ importers:
         specifier: ^4.3.4
         version: 4.7.0(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -2224,8 +2224,8 @@ importers:
         specifier: ^1.1.11
         version: 1.1.11
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -2276,8 +2276,8 @@ importers:
         specifier: ^4.3.4
         version: 4.7.0(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -2374,12 +2374,61 @@ importers:
         specifier: ^19.2.3
         version: 19.2.3(@types/react@19.2.8)
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       typescript:
         specifier: ^5.7.2
         version: 5.9.2
 
+  e2e/react-start/transform-asset-urls:
+    dependencies:
+      '@tanstack/react-router':
+        specifier: workspace:*
+        version: link:../../../packages/react-router
+      '@tanstack/react-start':
+        specifier: workspace:*
+        version: link:../../../packages/react-start
+      express:
+        specifier: ^5.1.0
+        version: 5.1.0
+      react:
+        specifier: ^19.2.3
+        version: 19.2.3
+      react-dom:
+        specifier: ^19.2.3
+        version: 19.2.3(react@19.2.3)
+    devDependencies:
+      '@playwright/test':
+        specifier: ^1.57.0
+        version: 1.57.0
+      '@tanstack/router-e2e-utils':
+        specifier: workspace:^
+        version: link:../../e2e-utils
+      '@types/node':
+        specifier: 25.0.9
+        version: 25.0.9
+      '@types/react':
+        specifier: ^19.2.8
+        version: 19.2.8
+      '@types/react-dom':
+        specifier: ^19.2.3
+        version: 19.2.3(@types/react@19.2.8)
+      '@vitejs/plugin-react':
+        specifier: ^4.3.4
+        version: 4.7.0(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+      srvx:
+        specifier: ^0.11.2
+        version: 0.11.2
+      typescript:
+        specifier: ^5.7.2
+        version: 5.9.3
+      vite:
+        specifier: ^7.3.1
+        version: 7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.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.3)(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
+
   e2e/react-start/virtual-routes:
     dependencies:
       '@tanstack/react-router':
@@ -2438,8 +2487,8 @@ importers:
         specifier: ^1.1.11
         version: 1.1.11
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -2499,8 +2548,8 @@ importers:
         specifier: ^4.3.4
         version: 4.3.4(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -3258,8 +3307,8 @@ importers:
         specifier: ^1.1.11
         version: 1.1.11
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -3325,8 +3374,8 @@ importers:
         specifier: ^7.0.0
         version: 7.0.0(@types/react@19.2.8)(magicast@0.3.5)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -3438,8 +3487,8 @@ importers:
         specifier: 25.0.9
         version: 25.0.9
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -3478,8 +3527,8 @@ importers:
         specifier: 25.0.9
         version: 25.0.9
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       typescript:
         specifier: ^5.7.2
         version: 5.8.2
@@ -3515,8 +3564,8 @@ importers:
         specifier: 25.0.9
         version: 25.0.9
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       typescript:
         specifier: ^5.7.2
         version: 5.9.2
@@ -3549,8 +3598,8 @@ importers:
         specifier: ^1.97.2
         version: 1.97.2
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       typescript:
         specifier: ^5.7.2
         version: 5.9.2
@@ -3604,8 +3653,8 @@ importers:
         specifier: ^10.0.0
         version: 10.0.0
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -3729,8 +3778,8 @@ importers:
         specifier: ^1.1.11
         version: 1.1.11
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -3766,8 +3815,8 @@ importers:
         specifier: workspace:^
         version: link:../../e2e-utils
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -3818,8 +3867,8 @@ importers:
         specifier: 25.0.9
         version: 25.0.9
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -3885,8 +3934,8 @@ importers:
         specifier: ^1.1.11
         version: 1.1.11
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -3955,8 +4004,8 @@ importers:
         specifier: ^1.1.11
         version: 1.1.11
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -4056,8 +4105,8 @@ importers:
         specifier: ^1.1.11
         version: 1.1.11
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -4111,8 +4160,8 @@ importers:
         specifier: 25.0.9
         version: 25.0.9
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -5074,8 +5123,8 @@ importers:
         specifier: ^1.1.11
         version: 1.1.11
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -5144,8 +5193,8 @@ importers:
         specifier: ^7.0.0
         version: 7.0.0(@types/react@19.2.8)(magicast@0.3.5)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2)
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -5239,8 +5288,8 @@ importers:
         specifier: ^5.1.2
         version: 5.1.2(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))(vue@3.5.25(typescript@5.9.2))
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       typescript:
         specifier: ^5.7.2
         version: 5.9.2
@@ -5303,8 +5352,8 @@ importers:
         specifier: ^5.1.2
         version: 5.1.2(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))(vue@3.5.25(typescript@5.9.2))
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -5343,8 +5392,8 @@ importers:
         specifier: ^1.97.2
         version: 1.97.2
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       typescript:
         specifier: ^5.7.2
         version: 5.9.2
@@ -5401,8 +5450,8 @@ importers:
         specifier: ^10.0.0
         version: 10.0.0
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -5532,8 +5581,8 @@ importers:
         specifier: ^1.1.11
         version: 1.1.11
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -5572,8 +5621,8 @@ importers:
         specifier: ^5.1.2
         version: 5.1.2(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))(vue@3.5.25(typescript@5.9.2))
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -5621,8 +5670,8 @@ importers:
         specifier: ^5.1.2
         version: 5.1.2(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))(vue@3.5.25(typescript@5.9.2))
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -5700,8 +5749,8 @@ importers:
         specifier: ^1.1.11
         version: 1.1.11
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -5773,8 +5822,8 @@ importers:
         specifier: ^1.1.11
         version: 1.1.11
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -5880,8 +5929,8 @@ importers:
         specifier: ^1.1.11
         version: 1.1.11
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -5938,8 +5987,8 @@ importers:
         specifier: ^5.1.2
         version: 5.1.2(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))(vue@3.5.25(typescript@5.9.2))
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwindcss:
         specifier: ^4.1.18
         version: 4.1.18
@@ -8368,8 +8417,8 @@ importers:
         specifier: ^0.5.1
         version: 0.5.1
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tailwind-merge:
         specifier: ^2.6.0
         version: 2.6.0
@@ -8915,8 +8964,8 @@ importers:
   examples/react/start-workos:
     dependencies:
       '@radix-ui/themes':
-        specifier: ^3.2.1
-        version: 3.2.1(@types/react-dom@19.2.3(@types/react@19.2.8))(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+        specifier: ^3.3.0
+        version: 3.3.0(@types/react-dom@19.2.3(@types/react@19.2.8))(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
       '@tanstack/react-router':
         specifier: workspace:*
         version: link:../../../packages/react-router
@@ -8926,15 +8975,9 @@ importers:
       '@tanstack/react-start':
         specifier: workspace:*
         version: link:../../../packages/react-start
-      '@workos-inc/node':
-        specifier: ^7.45.0
-        version: 7.46.0(express@5.1.0)
-      iron-session:
-        specifier: ^8.0.4
-        version: 8.0.4
-      jose:
-        specifier: ^6.0.10
-        version: 6.0.10
+      '@workos/authkit-tanstack-react-start':
+        specifier: ^0.5.0
+        version: 0.5.0(@tanstack/react-router@packages+react-router)(@tanstack/react-start@packages+react-start)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
       react:
         specifier: ^19.2.3
         version: 19.2.3
@@ -9187,7 +9230,7 @@ importers:
         specifier: workspace:*
         version: link:../../../packages/router-plugin
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -9224,7 +9267,7 @@ importers:
         specifier: workspace:*
         version: link:../../../packages/router-plugin
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -9264,7 +9307,7 @@ importers:
         specifier: ^4.1.18
         version: 4.1.18(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -9304,7 +9347,7 @@ importers:
         specifier: ^5.90.9
         version: 5.90.9(solid-js@1.9.10)
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -9338,7 +9381,7 @@ importers:
         specifier: ^4.1.18
         version: 4.1.18(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -9369,7 +9412,7 @@ importers:
         specifier: ^4.1.18
         version: 4.1.18(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -9406,7 +9449,7 @@ importers:
         specifier: ^4.1.18
         version: 4.1.18(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -9449,7 +9492,7 @@ importers:
         specifier: ^5.90.0
         version: 5.90.4(@tanstack/solid-query@5.90.9(solid-js@1.9.10))(solid-js@1.9.10)
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -9489,7 +9532,7 @@ importers:
         specifier: ^5.90.0
         version: 5.90.4(@tanstack/solid-query@5.90.9(solid-js@1.9.10))(solid-js@1.9.10)
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -9526,7 +9569,7 @@ importers:
         specifier: workspace:*
         version: link:../../../packages/router-plugin
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       compression:
         specifier: ^1.8.0
@@ -9566,7 +9609,7 @@ importers:
         specifier: ^4.1.18
         version: 4.1.18(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -9621,7 +9664,7 @@ importers:
         specifier: workspace:*
         version: link:../../../packages/router-plugin
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -9661,7 +9704,7 @@ importers:
         specifier: workspace:*
         version: link:../../../packages/router-plugin
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -9698,7 +9741,7 @@ importers:
         specifier: ^4.1.18
         version: 4.1.18(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -9735,7 +9778,7 @@ importers:
         specifier: workspace:*
         version: link:../../../packages/router-plugin
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       solid-js:
         specifier: 1.9.10
@@ -9766,7 +9809,7 @@ importers:
         specifier: ^4.1.18
         version: 4.1.18(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -9803,7 +9846,7 @@ importers:
         specifier: ^4.1.18
         version: 4.1.18(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -9849,7 +9892,7 @@ importers:
         specifier: ^5.90.0
         version: 5.90.4(@tanstack/solid-query@5.90.9(solid-js@1.9.10))(solid-js@1.9.10)
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -9895,7 +9938,7 @@ importers:
         specifier: ^5.90.0
         version: 5.90.4(@tanstack/solid-query@5.90.9(solid-js@1.9.10))(solid-js@1.9.10)
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -9938,7 +9981,7 @@ importers:
         specifier: ^5.90.9
         version: 5.90.9(solid-js@1.9.10)
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -9975,7 +10018,7 @@ importers:
         specifier: ^5.90.9
         version: 5.90.9(solid-js@1.9.10)
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10009,7 +10052,7 @@ importers:
         specifier: ^5.90.9
         version: 5.90.9(solid-js@1.9.10)
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10040,7 +10083,7 @@ importers:
         specifier: ^4.1.18
         version: 4.1.18(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10068,7 +10111,7 @@ importers:
         specifier: workspace:*
         version: link:../../../packages/router-plugin
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10099,7 +10142,7 @@ importers:
         specifier: ^4.1.18
         version: 4.1.18(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10136,7 +10179,7 @@ importers:
         specifier: ^4.1.18
         version: 4.1.18
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10170,7 +10213,7 @@ importers:
   examples/solid/quickstart-webpack-file-based:
     dependencies:
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10231,7 +10274,7 @@ importers:
         specifier: workspace:*
         version: link:../../../packages/router-plugin
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10265,7 +10308,7 @@ importers:
         specifier: workspace:*
         version: link:../../../packages/router-plugin
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10305,7 +10348,7 @@ importers:
         specifier: ^5.90.0
         version: 5.90.4(@tanstack/solid-query@5.90.9(solid-js@1.9.10))(solid-js@1.9.10)
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10339,7 +10382,7 @@ importers:
         specifier: ^4.1.18
         version: 4.1.18(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10379,7 +10422,7 @@ importers:
         specifier: ^5.90.9
         version: 5.90.9(solid-js@1.9.10)
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10425,7 +10468,7 @@ importers:
   examples/solid/start-basic:
     dependencies:
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10480,7 +10523,7 @@ importers:
         specifier: ^7.0.0
         version: 7.0.0(prisma@7.0.0(@types/react@19.2.8)(magicast@0.3.5)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.2))(typescript@5.9.2)
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10532,7 +10575,7 @@ importers:
         specifier: ^0.41.1
         version: 0.41.1
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10575,7 +10618,7 @@ importers:
   examples/solid/start-basic-cloudflare:
     dependencies:
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10618,7 +10661,7 @@ importers:
   examples/solid/start-basic-netlify:
     dependencies:
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10658,7 +10701,7 @@ importers:
   examples/solid/start-basic-nitro:
     dependencies:
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10704,7 +10747,7 @@ importers:
         specifier: ^5.90.0
         version: 5.90.4(@tanstack/solid-query@5.90.9(solid-js@1.9.10))(solid-js@1.9.10)
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10750,7 +10793,7 @@ importers:
   examples/solid/start-basic-static:
     dependencies:
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10805,7 +10848,7 @@ importers:
         specifier: ^0.7.0
         version: 0.7.14(csstype@3.2.3)(solid-js@1.9.10)
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10872,7 +10915,7 @@ importers:
         specifier: ^4.1.18
         version: 4.1.18(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10930,7 +10973,7 @@ importers:
   examples/solid/start-counter:
     dependencies:
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -10976,7 +11019,7 @@ importers:
         specifier: ^0.7.0
         version: 0.7.14(csstype@3.2.3)(solid-js@1.9.10)
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -11019,7 +11062,7 @@ importers:
         specifier: ^5.90.9
         version: 5.90.9(solid-js@1.9.10)
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -11065,7 +11108,7 @@ importers:
   examples/solid/start-streaming-data-from-server-functions:
     dependencies:
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -11105,7 +11148,7 @@ importers:
         specifier: ^2.48.1
         version: 2.48.1
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -11145,7 +11188,7 @@ importers:
   examples/solid/start-tailwind-v4:
     dependencies:
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -11194,7 +11237,7 @@ importers:
         specifier: workspace:*
         version: link:../../../packages/router-plugin
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -11228,7 +11271,7 @@ importers:
         specifier: ^4.1.18
         version: 4.1.18(vite@7.3.1(@types/node@25.0.9)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.2)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.8.1))
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -11268,7 +11311,7 @@ importers:
         specifier: workspace:*
         version: link:../../../packages/router-plugin
       '@tanstack/solid-router':
-        specifier: ^1.158.0
+        specifier: ^1.160.0
         version: link:../../../packages/solid-router
       '@tanstack/solid-router-devtools':
         specifier: workspace:^
@@ -12213,8 +12256,8 @@ importers:
         specifier: ^2.0.3
         version: 2.0.3
       srvx:
-        specifier: ^0.10.1
-        version: 0.10.1
+        specifier: ^0.11.2
+        version: 0.11.2
       tinyglobby:
         specifier: ^0.2.15
         version: 0.2.15
@@ -12256,8 +12299,8 @@ importers:
         specifier: workspace:*
         version: link:../start-storage-context
       h3-v2:
-        specifier: npm:h3@2.0.1-rc.11
-        version: h3@2.0.1-rc.11(crossws@0.4.3(srvx@0.10.1))
+        specifier: npm:h3@2.0.1-rc.14
+        version: h3@2.0.1-rc.14(crossws@0.4.3(srvx@0.11.2))
       seroval:
         specifier: ^1.4.2
         version: 1.4.2
@@ -15550,14 +15593,6 @@ packages:
   '@peculiar/asn1-x509@2.5.0':
     resolution: {integrity: sha512-CpwtMCTJvfvYTFMuiME5IH+8qmDe3yEWzKHe7OOADbGfq7ohxeLaXwQo0q4du3qs0AII3UbLCvb9NF/6q0oTKQ==}
 
-  '@peculiar/json-schema@1.1.12':
-    resolution: {integrity: sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==}
-    engines: {node: '>=8.0.0'}
-
-  '@peculiar/webcrypto@1.5.0':
-    resolution: {integrity: sha512-BRs5XUAwiyCDQMsVA9IDvDa7UBR9gAvPHgugOeGng3YN6vJ9JYonyDc0lNczErgtCWtucjR5N7VtaonboD/ezg==}
-    engines: {node: '>=10.12.0'}
-
   '@peculiar/x509@1.14.0':
     resolution: {integrity: sha512-Yc4PDxN3OrxUPiXgU63c+ZRXKGE8YKF2McTciYhUHFtHVB0KMnjeFSU0qpztGhsp4P0uKix4+J2xEpIEDu8oXg==}
 
@@ -16337,8 +16372,8 @@ packages:
   '@radix-ui/rect@1.1.1':
     resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==}
 
-  '@radix-ui/themes@3.2.1':
-    resolution: {integrity: sha512-WJL2YKAGItkunwm3O4cLTFKCGJTfAfF6Hmq7f5bCo1ggqC9qJQ/wfg/25AAN72aoEM1yqXZQ+pslsw48AFR0Xg==}
+  '@radix-ui/themes@3.3.0':
+    resolution: {integrity: sha512-I0/h2CRNTpYNB7Mi3xFIvSsQq5a108d7kK8dTO5zp5b9HR5QJXKag6B8tjpz2ITkVYkFdkGk45doNkSr7OxwNw==}
     peerDependencies:
       '@types/react': ^19.2.8
       '@types/react-dom': ^19.2.3
@@ -17637,9 +17672,6 @@ packages:
   '@tybys/wasm-util@0.9.0':
     resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==}
 
-  '@types/accepts@1.3.7':
-    resolution: {integrity: sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==}
-
   '@types/argparse@1.0.38':
     resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==}
 
@@ -17679,21 +17711,12 @@ packages:
   '@types/connect@3.4.38':
     resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==}
 
-  '@types/content-disposition@0.5.8':
-    resolution: {integrity: sha512-QVSSvno3dE0MgO76pJhmv4Qyi/j0Yk9pBp0Y7TJ2Tlj+KCgJWY6qX7nnxCOLkZ3VYRSIk1WTxCvwUSdx6CCLdg==}
-
   '@types/conventional-commits-parser@5.0.1':
     resolution: {integrity: sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==}
 
-  '@types/cookie@0.5.4':
-    resolution: {integrity: sha512-7z/eR6O859gyWIAjuvBWFzNURmf2oPBmJlfVWkwehU5nzIyjwBsTh7WMmEEV4JFnHuQ3ex4oyTvfKzcyJVDBNA==}
-
   '@types/cookie@0.6.0':
     resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
 
-  '@types/cookies@0.9.0':
-    resolution: {integrity: sha512-40Zk8qR147RABiQ7NQnBzWzDcjKzNrntB5BAmeGCb2p/MIyOE+4BVvc17wumsUqUw00bJYqoXFHYygQnEFh4/Q==}
-
   '@types/deep-eql@4.0.2':
     resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
 
@@ -17730,9 +17753,6 @@ packages:
   '@types/html-minifier-terser@6.1.0':
     resolution: {integrity: sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==}
 
-  '@types/http-assert@1.5.6':
-    resolution: {integrity: sha512-TTEwmtjgVbYAzZYWyeHPrrtWnfVkm8tQkP8P21uQifPgMRgjrow3XDEYqucuC8SKZJT7pUnhU/JymvjggxO9vw==}
-
   '@types/http-errors@2.0.4':
     resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==}
 
@@ -17748,15 +17768,6 @@ packages:
   '@types/json-schema@7.0.15':
     resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
 
-  '@types/keygrip@1.0.6':
-    resolution: {integrity: sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ==}
-
-  '@types/koa-compose@3.2.8':
-    resolution: {integrity: sha512-4Olc63RY+MKvxMwVknCUDhRQX1pFQoBZ/lXcRLP69PQkEpze/0cr8LNqJQe5NFb/b19DWi2a5bTi2VAlQzhJuA==}
-
-  '@types/koa@2.15.0':
-    resolution: {integrity: sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g==}
-
   '@types/mime@1.3.5':
     resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==}
 
@@ -18387,9 +18398,22 @@ packages:
     resolution: {integrity: sha512-Otmxo+0mp8az3B48pLI1I4msNOXPIoP7TLm6h5wOEQmynqHt8oP9nR6NJUeJk6iI5OtFpQtkbJFwfGkmplvc3Q==}
     engines: {node: '>=18.0.0'}
 
-  '@workos-inc/node@7.46.0':
-    resolution: {integrity: sha512-r/j+l/nlHkOqgIt0U70shZMKIQwLYFFU9aYmFW53l16+FwG+61SfldaK3ckjb3gscoGxWq+t7RlxcEe7Tz5eRA==}
-    engines: {node: '>=16'}
+  '@workos-inc/node@8.0.0':
+    resolution: {integrity: sha512-D8VDfx0GXeiVm8vccAl0rElW7taebRnrteKPJzZwehwzI9W/Usa4qKfmwxj+7Lh1Z1deEocDRCpZpV7ml4GpWQ==}
+    engines: {node: '>=20.15.0'}
+
+  '@workos/authkit-session@0.3.4':
+    resolution: {integrity: sha512-lbLP1y8MHWL1Op9athZ3SrzKLcL0+xBVpADCMQLI39mPgSQj+/lopVdOx0Cku96hYnJBOJTLVTK3Zox4FbZl4A==}
+    engines: {node: '>=20.0.0'}
+
+  '@workos/authkit-tanstack-react-start@0.5.0':
+    resolution: {integrity: sha512-W2Ot5QJLj1Kw2uzbs7VJk2vbkvwDXW9w7wLBFgUdmeu7JDmbW5VkI8tw4IU0fbA1PMBEt9ecj+h//B/BbKrPFg==}
+    engines: {node: '>=20.0.0'}
+    peerDependencies:
+      '@tanstack/react-router': workspace:*
+      '@tanstack/react-start': workspace:*
+      react: ^19.2.3
+      react-dom: ^19.2.3
 
   '@xtuc/ieee754@1.2.0':
     resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==}
@@ -18870,10 +18894,6 @@ packages:
     resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
     engines: {node: '>=8'}
 
-  call-bind-apply-helpers@1.0.1:
-    resolution: {integrity: sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==}
-    engines: {node: '>= 0.4'}
-
   call-bind-apply-helpers@1.0.2:
     resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
     engines: {node: '>= 0.4'}
@@ -18882,10 +18902,6 @@ packages:
     resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==}
     engines: {node: '>= 0.4'}
 
-  call-bound@1.0.3:
-    resolution: {integrity: sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==}
-    engines: {node: '>= 0.4'}
-
   call-bound@1.0.4:
     resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
     engines: {node: '>= 0.4'}
@@ -19273,10 +19289,6 @@ packages:
     resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==}
     engines: {node: '>=6.6.0'}
 
-  cookie@0.5.0:
-    resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==}
-    engines: {node: '>= 0.6'}
-
   cookie@0.7.1:
     resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==}
     engines: {node: '>= 0.6'}
@@ -20449,10 +20461,6 @@ packages:
     resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
     engines: {node: 6.* || 8.* || >= 10.*}
 
-  get-intrinsic@1.2.7:
-    resolution: {integrity: sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==}
-    engines: {node: '>= 0.4'}
-
   get-intrinsic@1.3.0:
     resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
     engines: {node: '>= 0.4'}
@@ -20581,6 +20589,16 @@ packages:
       crossws:
         optional: true
 
+  h3@2.0.1-rc.14:
+    resolution: {integrity: sha512-163qbGmTr/9rqQRNuqMqtgXnOUAkE4KTdauiC9y0E5iG1I65kte9NyfWvZw5RTDMt6eY+DtyoNzrQ9wA2BfvGQ==}
+    engines: {node: '>=20.11.1'}
+    hasBin: true
+    peerDependencies:
+      crossws: ^0.4.1
+    peerDependenciesMeta:
+      crossws:
+        optional: true
+
   handle-thing@2.0.1:
     resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==}
 
@@ -20873,30 +20891,12 @@ packages:
     resolution: {integrity: sha512-7Xnt54Dco7uYkfdAw0r2vCly3z0rSaVhEXMzPvl3FndsTVm5p26j+PO+gyinkYmcsEUvX2Rh7OGK7KzYWRu6BA==}
     hasBin: true
 
-  iron-session@6.3.1:
-    resolution: {integrity: sha512-3UJ7y2vk/WomAtEySmPgM6qtYF1cZ3tXuWX5GsVX4PJXAcs5y/sV9HuSfpjKS6HkTL/OhZcTDWJNLZ7w+Erx3A==}
-    engines: {node: '>=12'}
-    peerDependencies:
-      express: '>=4'
-      koa: '>=2'
-      next: '>=10'
-    peerDependenciesMeta:
-      express:
-        optional: true
-      koa:
-        optional: true
-      next:
-        optional: true
-
-  iron-session@8.0.4:
-    resolution: {integrity: sha512-9ivNnaKOd08osD0lJ3i6If23GFS2LsxyMU8Gf/uBUEgm8/8CC1hrrCHFDpMo3IFbpBgwoo/eairRsaD3c5itxA==}
-
-  iron-webcrypto@0.2.8:
-    resolution: {integrity: sha512-YPdCvjFMOBjXaYuDj5tiHst5CEk6Xw84Jo8Y2+jzhMceclAnb3+vNPP/CTtb5fO2ZEuXEaO4N+w62Vfko757KA==}
-
   iron-webcrypto@1.2.1:
     resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==}
 
+  iron-webcrypto@2.0.0:
+    resolution: {integrity: sha512-rtffZKDUHciZElM8mjFCufBC7nVhCxHYyWHESqs89OioEDz4parOofd8/uhrejh/INhQFfYQfByS22LlezR9sQ==}
+
   is-arguments@1.2.0:
     resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==}
     engines: {node: '>= 0.4'}
@@ -21152,15 +21152,12 @@ packages:
   jju@1.4.0:
     resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==}
 
-  jose@5.6.3:
-    resolution: {integrity: sha512-1Jh//hEEwMhNYPDDLwXHa2ePWgWiFNNUadVmguAAw2IJ6sj9mNxV5tGXJNqlMkJAybF6Lgw1mISDxTePP/187g==}
-
-  jose@6.0.10:
-    resolution: {integrity: sha512-skIAxZqcMkOrSwjJvplIPYrlXGpxTPnro2/QWTDCxAdWQrSTV5/KqspMWmi5WAx5+ULswASJiZ0a+1B/Lxt9cw==}
-
   jose@6.1.0:
     resolution: {integrity: sha512-TTQJyoEoKcC1lscpVDCSsVgYzUDg/0Bt3WE//WiTPK6uOCQC2KZS4MpugbMWt/zyjkopgZoXhZuCi00gLudfUA==}
 
+  jose@6.1.3:
+    resolution: {integrity: sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==}
+
   jpeg-js@0.4.4:
     resolution: {integrity: sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==}
 
@@ -21341,9 +21338,6 @@ packages:
     resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==}
     engines: {node: '>= 0.6.3'}
 
-  leb@1.0.0:
-    resolution: {integrity: sha512-Y3c3QZfvKWHX60BVOQPhLCvVGmDYWyJEiINE3drOog6KCyN2AOwvuQQzlS3uJg1J85kzpILXIUwRXULWavir+w==}
-
   leven@3.1.0:
     resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
     engines: {node: '>=6'}
@@ -22382,10 +22376,6 @@ packages:
     engines: {node: '>=18'}
     hasBin: true
 
-  pluralize@8.0.0:
-    resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
-    engines: {node: '>=4'}
-
   pngjs@7.0.0:
     resolution: {integrity: sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==}
     engines: {node: '>=14.19.0'}
@@ -23437,6 +23427,11 @@ packages:
     engines: {node: '>=20.16.0'}
     hasBin: true
 
+  srvx@0.11.2:
+    resolution: {integrity: sha512-u6NbjE84IJwm1XUnJ53WqylLTQ3BdWRw03lcjBNNeMBD+EFjkl0Cnw1RVaGSqRAo38pOHOPXJH30M6cuTINUxw==}
+    engines: {node: '>=20.16.0'}
+    hasBin: true
+
   stable-hash-x@0.2.0:
     resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==}
     engines: {node: '>=12.0.0'}
@@ -23993,6 +23988,10 @@ packages:
   ufo@1.6.3:
     resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==}
 
+  uint8array-extras@1.5.0:
+    resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==}
+    engines: {node: '>=18'}
+
   ulid@3.0.1:
     resolution: {integrity: sha512-dPJyqPzx8preQhqq24bBG1YNkvigm87K8kVEHCD+ruZg24t6IFEFv00xMWfxcC4djmFtiTLdFuADn4+DOz6R7Q==}
     hasBin: true
@@ -24583,9 +24582,6 @@ packages:
   web-vitals@5.1.0:
     resolution: {integrity: sha512-ArI3kx5jI0atlTtmV0fWU3fjpLmq/nD3Zr1iFFlJLaqa5wLBkUSzINwBPySCX/8jRyjlmy1Volw1kz1g9XE4Jg==}
 
-  webcrypto-core@1.8.1:
-    resolution: {integrity: sha512-P+x1MvlNCXlKbLSOY4cYrdreqPG5hbzkmawbcXLKN/mf6DZW0SdNNkZ+sjwsqVkI4A4Ko2sPZmkZtCKY58w83A==}
-
   webidl-conversions@3.0.1:
     resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
 
@@ -27978,18 +27974,6 @@ snapshots:
       pvtsutils: 1.3.6
       tslib: 2.8.1
 
-  '@peculiar/json-schema@1.1.12':
-    dependencies:
-      tslib: 2.8.1
-
-  '@peculiar/webcrypto@1.5.0':
-    dependencies:
-      '@peculiar/asn1-schema': 2.5.0
-      '@peculiar/json-schema': 1.1.12
-      pvtsutils: 1.3.6
-      tslib: 2.8.1
-      webcrypto-core: 1.8.1
-
   '@peculiar/x509@1.14.0':
     dependencies:
       '@peculiar/asn1-cms': 2.5.0
@@ -28882,7 +28866,7 @@ snapshots:
 
   '@radix-ui/rect@1.1.1': {}
 
-  '@radix-ui/themes@3.2.1(@types/react-dom@19.2.3(@types/react@19.2.8))(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+  '@radix-ui/themes@3.3.0(@types/react-dom@19.2.3(@types/react@19.2.8))(@types/react@19.2.8)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
     dependencies:
       '@radix-ui/colors': 3.0.0
       classnames: 2.5.1
@@ -30234,10 +30218,6 @@ snapshots:
     dependencies:
       tslib: 2.8.1
 
-  '@types/accepts@1.3.7':
-    dependencies:
-      '@types/node': 25.0.9
-
   '@types/argparse@1.0.38': {}
 
   '@types/aria-query@5.0.4': {}
@@ -30293,23 +30273,12 @@ snapshots:
     dependencies:
       '@types/node': 25.0.9
 
-  '@types/content-disposition@0.5.8': {}
-
   '@types/conventional-commits-parser@5.0.1':
     dependencies:
       '@types/node': 25.0.9
 
-  '@types/cookie@0.5.4': {}
-
   '@types/cookie@0.6.0': {}
 
-  '@types/cookies@0.9.0':
-    dependencies:
-      '@types/connect': 3.4.38
-      '@types/express': 5.0.3
-      '@types/keygrip': 1.0.6
-      '@types/node': 25.0.9
-
   '@types/deep-eql@4.0.2': {}
 
   '@types/diff@7.0.2': {}
@@ -30361,8 +30330,6 @@ snapshots:
 
   '@types/html-minifier-terser@6.1.0': {}
 
-  '@types/http-assert@1.5.6': {}
-
   '@types/http-errors@2.0.4': {}
 
   '@types/http-proxy@1.17.15':
@@ -30375,23 +30342,6 @@ snapshots:
 
   '@types/json-schema@7.0.15': {}
 
-  '@types/keygrip@1.0.6': {}
-
-  '@types/koa-compose@3.2.8':
-    dependencies:
-      '@types/koa': 2.15.0
-
-  '@types/koa@2.15.0':
-    dependencies:
-      '@types/accepts': 1.3.7
-      '@types/content-disposition': 0.5.8
-      '@types/cookies': 0.9.0
-      '@types/http-assert': 1.5.6
-      '@types/http-errors': 2.0.4
-      '@types/keygrip': 1.0.6
-      '@types/koa-compose': 3.2.8
-      '@types/node': 25.0.9
-
   '@types/mime@1.3.5': {}
 
   '@types/node-forge@1.3.11':
@@ -31505,16 +31455,24 @@ snapshots:
       '@whatwg-node/promise-helpers': 1.3.2
       tslib: 2.8.1
 
-  '@workos-inc/node@7.46.0(express@5.1.0)':
+  '@workos-inc/node@8.0.0':
     dependencies:
-      iron-session: 6.3.1(express@5.1.0)
-      jose: 5.6.3
-      leb: 1.0.0
-      pluralize: 8.0.0
-    transitivePeerDependencies:
-      - express
-      - koa
-      - next
+      iron-webcrypto: 2.0.0
+      jose: 6.1.3
+
+  '@workos/authkit-session@0.3.4':
+    dependencies:
+      '@workos-inc/node': 8.0.0
+      iron-webcrypto: 2.0.0
+      jose: 6.1.3
+
+  '@workos/authkit-tanstack-react-start@0.5.0(@tanstack/react-router@packages+react-router)(@tanstack/react-start@packages+react-start)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+    dependencies:
+      '@tanstack/react-router': link:packages/react-router
+      '@tanstack/react-start': link:packages/react-start
+      '@workos/authkit-session': 0.3.4
+      react: 19.2.3
+      react-dom: 19.2.3(react@19.2.3)
 
   '@xtuc/ieee754@1.2.0': {}
 
@@ -31727,7 +31685,7 @@ snapshots:
 
   array-buffer-byte-length@1.0.2:
     dependencies:
-      call-bound: 1.0.3
+      call-bound: 1.0.4
       is-array-buffer: 3.0.5
 
   array-flatten@1.1.1: {}
@@ -32055,11 +32013,6 @@ snapshots:
 
   cac@6.7.14: {}
 
-  call-bind-apply-helpers@1.0.1:
-    dependencies:
-      es-errors: 1.3.0
-      function-bind: 1.1.2
-
   call-bind-apply-helpers@1.0.2:
     dependencies:
       es-errors: 1.3.0
@@ -32067,16 +32020,11 @@ snapshots:
 
   call-bind@1.0.8:
     dependencies:
-      call-bind-apply-helpers: 1.0.1
+      call-bind-apply-helpers: 1.0.2
       es-define-property: 1.0.1
-      get-intrinsic: 1.2.7
+      get-intrinsic: 1.3.0
       set-function-length: 1.2.2
 
-  call-bound@1.0.3:
-    dependencies:
-      call-bind-apply-helpers: 1.0.1
-      get-intrinsic: 1.2.7
-
   call-bound@1.0.4:
     dependencies:
       call-bind-apply-helpers: 1.0.2
@@ -32458,8 +32406,6 @@ snapshots:
 
   cookie-signature@1.2.2: {}
 
-  cookie@0.5.0: {}
-
   cookie@0.7.1: {}
 
   cookie@0.7.2: {}
@@ -32526,6 +32472,11 @@ snapshots:
     optionalDependencies:
       srvx: 0.10.1
 
+  crossws@0.4.3(srvx@0.11.2):
+    optionalDependencies:
+      srvx: 0.11.2
+    optional: true
+
   css-loader@7.1.2(@rspack/core@1.2.2(@swc/helpers@0.5.15))(webpack@5.97.1):
     dependencies:
       icss-utils: 5.1.0(postcss@8.5.6)
@@ -32657,7 +32608,7 @@ snapshots:
       array-buffer-byte-length: 1.0.2
       call-bind: 1.0.8
       es-get-iterator: 1.1.3
-      get-intrinsic: 1.2.7
+      get-intrinsic: 1.3.0
       is-arguments: 1.2.0
       is-array-buffer: 3.0.5
       is-date-object: 1.1.0
@@ -32874,7 +32825,7 @@ snapshots:
 
   dunder-proto@1.0.1:
     dependencies:
-      call-bind-apply-helpers: 1.0.1
+      call-bind-apply-helpers: 1.0.2
       es-errors: 1.3.0
       gopd: 1.2.0
 
@@ -32977,7 +32928,7 @@ snapshots:
   es-get-iterator@1.1.3:
     dependencies:
       call-bind: 1.0.8
-      get-intrinsic: 1.2.7
+      get-intrinsic: 1.3.0
       has-symbols: 1.1.0
       is-arguments: 1.2.0
       is-map: 2.0.3
@@ -33923,19 +33874,6 @@ snapshots:
 
   get-caller-file@2.0.5: {}
 
-  get-intrinsic@1.2.7:
-    dependencies:
-      call-bind-apply-helpers: 1.0.1
-      es-define-property: 1.0.1
-      es-errors: 1.3.0
-      es-object-atoms: 1.1.1
-      function-bind: 1.1.2
-      get-proto: 1.0.1
-      gopd: 1.2.0
-      has-symbols: 1.1.0
-      hasown: 2.0.2
-      math-intrinsics: 1.1.0
-
   get-intrinsic@1.3.0:
     dependencies:
       call-bind-apply-helpers: 1.0.2
@@ -34078,6 +34016,13 @@ snapshots:
     optionalDependencies:
       crossws: 0.4.3(srvx@0.10.1)
 
+  h3@2.0.1-rc.14(crossws@0.4.3(srvx@0.11.2)):
+    dependencies:
+      rou3: 0.7.12
+      srvx: 0.11.2
+    optionalDependencies:
+      crossws: 0.4.3(srvx@0.11.2)
+
   handle-thing@2.0.1: {}
 
   has-async-hooks@1.0.0: {}
@@ -34402,40 +34347,22 @@ snapshots:
       - ioredis
       - uploadthing
 
-  iron-session@6.3.1(express@5.1.0):
-    dependencies:
-      '@peculiar/webcrypto': 1.5.0
-      '@types/cookie': 0.5.4
-      '@types/express': 4.17.23
-      '@types/koa': 2.15.0
-      '@types/node': 25.0.9
-      cookie: 0.5.0
-      iron-webcrypto: 0.2.8
-    optionalDependencies:
-      express: 5.1.0
-
-  iron-session@8.0.4:
-    dependencies:
-      cookie: 0.7.2
-      iron-webcrypto: 1.2.1
-      uncrypto: 0.1.3
+  iron-webcrypto@1.2.1: {}
 
-  iron-webcrypto@0.2.8:
+  iron-webcrypto@2.0.0:
     dependencies:
-      buffer: 6.0.3
-
-  iron-webcrypto@1.2.1: {}
+      uint8array-extras: 1.5.0
 
   is-arguments@1.2.0:
     dependencies:
-      call-bound: 1.0.3
+      call-bound: 1.0.4
       has-tostringtag: 1.0.2
 
   is-array-buffer@3.0.5:
     dependencies:
       call-bind: 1.0.8
-      call-bound: 1.0.3
-      get-intrinsic: 1.2.7
+      call-bound: 1.0.4
+      get-intrinsic: 1.3.0
 
   is-arrayish@0.2.1: {}
 
@@ -34451,7 +34378,7 @@ snapshots:
 
   is-boolean-object@1.2.2:
     dependencies:
-      call-bound: 1.0.3
+      call-bound: 1.0.4
       has-tostringtag: 1.0.2
 
   is-callable@1.2.7: {}
@@ -34462,7 +34389,7 @@ snapshots:
 
   is-date-object@1.1.0:
     dependencies:
-      call-bound: 1.0.3
+      call-bound: 1.0.4
       has-tostringtag: 1.0.2
 
   is-docker@2.2.1: {}
@@ -34507,7 +34434,7 @@ snapshots:
 
   is-number-object@1.1.1:
     dependencies:
-      call-bound: 1.0.3
+      call-bound: 1.0.4
       has-tostringtag: 1.0.2
 
   is-number@7.0.0: {}
@@ -34540,7 +34467,7 @@ snapshots:
 
   is-regex@1.2.1:
     dependencies:
-      call-bound: 1.0.3
+      call-bound: 1.0.4
       gopd: 1.2.0
       has-tostringtag: 1.0.2
       hasown: 2.0.2
@@ -34549,7 +34476,7 @@ snapshots:
 
   is-shared-array-buffer@1.0.4:
     dependencies:
-      call-bound: 1.0.3
+      call-bound: 1.0.4
 
   is-stream@2.0.1: {}
 
@@ -34559,12 +34486,12 @@ snapshots:
 
   is-string@1.1.1:
     dependencies:
-      call-bound: 1.0.3
+      call-bound: 1.0.4
       has-tostringtag: 1.0.2
 
   is-symbol@1.1.1:
     dependencies:
-      call-bound: 1.0.3
+      call-bound: 1.0.4
       has-symbols: 1.1.0
       safe-regex-test: 1.1.0
 
@@ -34584,8 +34511,8 @@ snapshots:
 
   is-weakset@2.0.4:
     dependencies:
-      call-bound: 1.0.3
-      get-intrinsic: 1.2.7
+      call-bound: 1.0.4
+      get-intrinsic: 1.3.0
 
   is-what@4.1.16: {}
 
@@ -34636,12 +34563,10 @@ snapshots:
 
   jju@1.4.0: {}
 
-  jose@5.6.3: {}
-
-  jose@6.0.10: {}
-
   jose@6.1.0: {}
 
+  jose@6.1.3: {}
+
   jpeg-js@0.4.4: {}
 
   js-base64@3.7.8: {}
@@ -34846,8 +34771,6 @@ snapshots:
     dependencies:
       readable-stream: 2.3.8
 
-  leb@1.0.0: {}
-
   leven@3.1.0: {}
 
   levn@0.4.1:
@@ -35806,7 +35729,7 @@ snapshots:
   object.assign@4.1.7:
     dependencies:
       call-bind: 1.0.8
-      call-bound: 1.0.3
+      call-bound: 1.0.4
       define-properties: 1.2.1
       es-object-atoms: 1.1.1
       has-symbols: 1.1.0
@@ -36144,8 +36067,6 @@ snapshots:
     optionalDependencies:
       fsevents: 2.3.2
 
-  pluralize@8.0.0: {}
-
   pngjs@7.0.0: {}
 
   possible-typed-array-names@1.1.0: {}
@@ -36889,7 +36810,7 @@ snapshots:
 
   safe-regex-test@1.1.0:
     dependencies:
-      call-bound: 1.0.3
+      call-bound: 1.0.4
       es-errors: 1.3.0
       is-regex: 1.2.1
 
@@ -37149,7 +37070,7 @@ snapshots:
       define-data-property: 1.1.4
       es-errors: 1.3.0
       function-bind: 1.1.2
-      get-intrinsic: 1.2.7
+      get-intrinsic: 1.3.0
       gopd: 1.2.0
       has-property-descriptors: 1.0.2
 
@@ -37240,16 +37161,16 @@ snapshots:
 
   side-channel-map@1.0.1:
     dependencies:
-      call-bound: 1.0.3
+      call-bound: 1.0.4
       es-errors: 1.3.0
-      get-intrinsic: 1.2.7
+      get-intrinsic: 1.3.0
       object-inspect: 1.13.3
 
   side-channel-weakmap@1.0.2:
     dependencies:
-      call-bound: 1.0.3
+      call-bound: 1.0.4
       es-errors: 1.3.0
-      get-intrinsic: 1.2.7
+      get-intrinsic: 1.3.0
       object-inspect: 1.13.3
       side-channel-map: 1.0.1
 
@@ -37397,6 +37318,8 @@ snapshots:
 
   srvx@0.10.1: {}
 
+  srvx@0.11.2: {}
+
   stable-hash-x@0.2.0: {}
 
   stack-trace@0.0.10: {}
@@ -37909,6 +37832,8 @@ snapshots:
 
   ufo@1.6.3: {}
 
+  uint8array-extras@1.5.0: {}
+
   ulid@3.0.1: {}
 
   ultrahtml@1.6.0: {}
@@ -38574,14 +38499,6 @@ snapshots:
 
   web-vitals@5.1.0: {}
 
-  webcrypto-core@1.8.1:
-    dependencies:
-      '@peculiar/asn1-schema': 2.5.0
-      '@peculiar/json-schema': 1.1.12
-      asn1js: 3.0.6
-      pvtsutils: 1.3.6
-      tslib: 2.8.1
-
   webidl-conversions@3.0.1: {}
 
   webidl-conversions@7.0.0: {}
diff --git a/scripts/llms-generate.mjs b/scripts/llms-generate.mjs
index 16129a8a4c..a6debd16d0 100755
--- a/scripts/llms-generate.mjs
+++ b/scripts/llms-generate.mjs
@@ -20,36 +20,36 @@ const RULES_DIR = './llms/rules'
 const packages = {
   'react-router': [
     {
-      paths: [`${DOCS_DIR}/router/framework/react/api/router`],
+      paths: [`${DOCS_DIR}/router/api/router`],
       description: 'TanStack Router: API',
       name: 'api',
       globs: ['src/**/*.ts', 'src/**/*.tsx'],
     },
     {
-      paths: [`${DOCS_DIR}/router/framework/react/guide`],
+      paths: [`${DOCS_DIR}/router/guide`],
       description: 'TanStack Router: Guide',
       name: 'guide',
       globs: ['src/**/*.ts', 'src/**/*.tsx'],
     },
     {
-      paths: [`${DOCS_DIR}/router/framework/react/routing`],
+      paths: [`${DOCS_DIR}/router/routing`],
       description: 'TanStack Router: Routing',
       name: 'routing',
       globs: ['src/**/*.ts', 'src/**/*.tsx'],
     },
     {
-      paths: [`${DOCS_DIR}/router/framework/react/installation`],
+      paths: [`${DOCS_DIR}/router/installation`],
       description: 'TanStack Router: Installation',
       name: 'installation',
       globs: ['src/**/*.ts', 'src/**/*.tsx'],
     },
     {
       paths: [
-        `${DOCS_DIR}/router/framework/react/overview.md`,
-        `${DOCS_DIR}/router/framework/react/quick-start.md`,
-        `${DOCS_DIR}/router/framework/react/decisions-on-dx.md`,
-        `${DOCS_DIR}/router/framework/react/devtools.md`,
-        `${DOCS_DIR}/router/framework/react/faq.md`,
+        `${DOCS_DIR}/router/overview.md`,
+        `${DOCS_DIR}/router/quick-start.md`,
+        `${DOCS_DIR}/router/decisions-on-dx.md`,
+        `${DOCS_DIR}/router/devtools.md`,
+        `${DOCS_DIR}/router/faq.md`,
       ],
       description: 'TanStack Router: Setup and Architecture',
       name: 'setup-and-architecture',
