From efdebf214715aa4ae0b46c525de5c99c30aa31c2 Mon Sep 17 00:00:00 2001 From: unpunnyfuns Date: Sat, 25 Jul 2026 13:54:52 +0200 Subject: [PATCH 1/2] fix(tanstack-react): carry lazy route bindings onto clones .lazy() bindings live on the route instance as lazyFn, not in options, so carry them over for both nested clones and the rebuilt root, or clones lose their lazily-loaded component. --- .../src/routing/duplicate-tree.test.ts | 35 +++++++++++++++++++ .../src/routing/duplicate-tree.ts | 9 +++++ 2 files changed, 44 insertions(+) diff --git a/code/frameworks/tanstack-react/src/routing/duplicate-tree.test.ts b/code/frameworks/tanstack-react/src/routing/duplicate-tree.test.ts index 3def5470c75b..6b6034b51ab2 100644 --- a/code/frameworks/tanstack-react/src/routing/duplicate-tree.test.ts +++ b/code/frameworks/tanstack-react/src/routing/duplicate-tree.test.ts @@ -1,5 +1,6 @@ import { describe, expect, it, vi } from 'vitest'; import { + createLazyRoute, createMemoryHistory, createRootRoute, createRoute, @@ -233,4 +234,38 @@ describe('duplicateRouteTree matrix (code-based and file-based trees)', () => { expect(override).toHaveBeenCalled(); expect(original).not.toHaveBeenCalled(); }); + + it('carries lazy route bindings onto clones', async () => { + const marker = () => null; + const root = createRootRoute(); + const page = createRoute({ path: '/lazy', getParentRoute: () => root }); + page.lazy(() => Promise.resolve(createLazyRoute('/lazy')({ component: marker }))); + root.addChildren([page]); + + const { root: cloned } = duplicateRouteTree(root as any); + const router = createRouter({ + routeTree: cloned, + history: createMemoryHistory({ initialEntries: ['/lazy'] }), + }); + await router.load(); + + expect((router.routesById['/lazy'] as any).options.component).toBe(marker); + }); + + it('carries a lazy binding on the root route onto the clone', async () => { + const marker = () => null; + const root = createRootRoute(); + (root as any).lazy(() => Promise.resolve(createLazyRoute('__root__')({ component: marker }))); + const child = createRoute({ path: '/child', getParentRoute: () => root }); + root.addChildren([child]); + + const { root: cloned } = duplicateRouteTree(root as any); + const router = createRouter({ + routeTree: cloned as any, + history: createMemoryHistory({ initialEntries: ['/child'] }), + }); + await router.load(); + + expect((router.routesById['__root__'] as any).options.component).toBe(marker); + }); }); diff --git a/code/frameworks/tanstack-react/src/routing/duplicate-tree.ts b/code/frameworks/tanstack-react/src/routing/duplicate-tree.ts index eec3c46c3c26..30f2e4bd1b20 100644 --- a/code/frameworks/tanstack-react/src/routing/duplicate-tree.ts +++ b/code/frameworks/tanstack-react/src/routing/duplicate-tree.ts @@ -96,6 +96,11 @@ function cloneChild( (cloned as any).update({ id: explicitId }); } + const lazyFn = (oldRoute as any).lazyFn; + if (lazyFn) { + (cloned as any).lazy(lazyFn); + } + byId.set(oldRoute.id, cloned as unknown as AnyRoute); const children = (oldRoute as any).children as AnyRoute[] | undefined; @@ -150,6 +155,10 @@ export function duplicateRouteTree( ...restRoot, ...rootOverride, } as any); + const rootLazyFn = (rootRoute as any).lazyFn; + if (rootLazyFn) { + (newRoot as any).lazy(rootLazyFn); + } byId.set('__root__', newRoot as unknown as AnyRoute); const children = (rootRoute as any).children as AnyRoute[] | undefined; From 158e9db159aba5a0a67f96d43db9274d5b0c1606 Mon Sep 17 00:00:00 2001 From: unpunnyfuns Date: Tue, 28 Jul 2026 07:50:54 +0200 Subject: [PATCH 2/2] test(tanstack-react): cast the router before indexing routesById --- .../tanstack-react/src/routing/duplicate-tree.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/frameworks/tanstack-react/src/routing/duplicate-tree.test.ts b/code/frameworks/tanstack-react/src/routing/duplicate-tree.test.ts index 6b6034b51ab2..197ccf7a71d7 100644 --- a/code/frameworks/tanstack-react/src/routing/duplicate-tree.test.ts +++ b/code/frameworks/tanstack-react/src/routing/duplicate-tree.test.ts @@ -249,7 +249,7 @@ describe('duplicateRouteTree matrix (code-based and file-based trees)', () => { }); await router.load(); - expect((router.routesById['/lazy'] as any).options.component).toBe(marker); + expect((router as any).routesById['/lazy'].options.component).toBe(marker); }); it('carries a lazy binding on the root route onto the clone', async () => { @@ -266,6 +266,6 @@ describe('duplicateRouteTree matrix (code-based and file-based trees)', () => { }); await router.load(); - expect((router.routesById['__root__'] as any).options.component).toBe(marker); + expect((router as any).routesById['__root__'].options.component).toBe(marker); }); });