T
TanStack13mo ago
flat-fuchsia

Are there workarounds for using validateSearch with lazy file routes?

Looking to reap the benefits of validateSearch alongside lazy-loaded routes (createLazyFileRoute). I get why it's not possible, but, wondering if there's a preferred work-around or some magic cooking to make validation possible once a lazy route file has loaded. 🙏 Thanks all!
No description
24 Replies
like-gold
like-gold13mo ago
Uhm, you just need to create 2 files, one <your_route>.tsx which contains only the route settings (including validateSearch) and the other one <your_route>.lazy.tsx that only contains the component for code splitting and lazy loading
wise-white
wise-white13mo ago
If you are using a bundler (like Vite, Webpack, Rspack), then you can get the benefits of automatic code-splitting without having to create both files. https://tanstack.com/router/latest/docs/framework/react/guide/code-splitting#using-automatic-code-splitting
Code Splitting | TanStack Router React Docs
Code splitting and lazy loading is a powerful technique for improving the bundle size and load performance of an application. Reduces the amount of code that needs to be loaded on initial page load
flat-fuchsia
flat-fuchsiaOP13mo ago
Using Vite over here. Interesting ... so I can most likely yank the "lazy" part of all my routes and let vite automagically code split. Part of this is carry-over from migrating off react-router where I was previously doing stuff like: const Access = lazy(() => import('@/routes/Access')); const IdeaPublic = lazy(() => import('@/routes/IdeaPublic')); const Landing = lazy(() => import('@/routes/Landing')); const router = createBrowserRouter([ { element: <Root />, children: [ { path: '/', element: <Landing />, }, { path: 'login', element: <Access />, }, { path: '/id/:id', element: <IdeaPublic />, ...
wise-white
wise-white13mo ago
Assuming, this was from your react-router config, then yes. Just create you routes like:
src/routes/
__root.tsx
index.tsx
posts.tsx
posts.index.tsx
posts.$postId/
index.tsx
...
src/routes/
__root.tsx
index.tsx
posts.tsx
posts.index.tsx
posts.$postId/
index.tsx
...
And turn on the autoCodeSplitting flag in your TanStackRouterVite plugin config.
flat-fuchsia
flat-fuchsiaOP13mo ago
Gave this a shot — Removed .lazy from all routes, updated vite config with plugin plugins: [TanStackRouterVite({ autoCodeSplitting: true }), react()],, and it throws an error at runtime on my main layout file. I'm defining a Layout function right inside _layout.tsx ... it's almost as though it's not getting compiled. I'll try moving it to a separate file outside of src/routes and will import it into src/routes/_layout.tsx to see if that helps (Edit: No dice, same result). Appreciate all the help (happy to provide additional info), love the package so far! ❤️
No description
like-gold
like-gold13mo ago
Do you export your route components? The only thing that should be exported from a page file is the Route object.
flat-fuchsia
flat-fuchsiaOP13mo ago
There we go! I removed all default exports, only have named Route exports and splitting is now working 🙌 . Thanks all!
rising-crimson
rising-crimson13mo ago
could you please share the original file so we can handle this better in the code splitter? either fix this fully or at least give a descriptive error
flat-fuchsia
flat-fuchsiaOP13mo ago
@Manuel Schiller
rising-crimson
rising-crimson13mo ago
thanks, I will make sure this will be a nicer experience
flat-fuchsia
flat-fuchsiaOP12mo ago
Is the “preload” option on <Link> expected to work with autoCodeSplitting enabled?
wise-white
wise-white12mo ago
Yes, preload='intent' | 'viewport' would with the code-splitting option. The automatic code-splitting is more of a bundler side integration, that essentially generates what's there in the .lazy.tsx file in a virtual file-system. Since the component is being exported, we shouldn't be code-splitting it. This is because, if it were to be code-split, it'd be moved to the file?tsr-split (a virtual route), which would break other imports. Therefore, we should retain the export in the same compiled file and not do any code-splitting on that export.
wise-white
wise-white12mo ago
@Manuel Schiller I've opened a fix for this. https://github.com/TanStack/router/pull/2334 @TrappedInABasement with this fix, you'll be able to import the Layout component, but you'll have a console.warning telling you that you aren't going to benefit from code-splitting.
GitHub
fix(router-plugin): do not split if known ident is exported by Sean...
From https://discord.com/channels/719702312431386674/1283438765817331712 When using autoCodeSplitting, we need to take into account the scenario where the user is exporting their component or loade...
flat-fuchsia
flat-fuchsiaOP12mo ago
For sanity’s sake, I’m also no longer seeing lazy-loaded routes prefetch with “intent” set on respective <Links> after switching to autoCodeSplitting. I’ll give that a more thorough look to ensure it’s not operator error. I'm stepping through the Link component in debugger, will report back :D. Interesting — with or without autoCodeSplitting, I have to add .lazy back into my route filename for preload="intent" and preload="viewport" on links to work.
wise-white
wise-white12mo ago
Just rechecked, preloading DOES work with autoCodeSplitting.
wise-white
wise-white12mo ago
Can confirm that preloading works by observing the split bundle being loaded in with the suffix of ?tsr-split For example, it'd look like http://localhost:3001/src/routes/index.tsx?tsr-split
wise-white
wise-white12mo ago
Can also confirm that preloading works, by observing a loader firing on another route with preload='intent' when hovering on a link targeting that route.
wise-white
wise-white12mo ago
@TrappedInABasement your methodology for testing may be wrong, or you might not actually have the autoCodeSplitting flag turned on.
flat-fuchsia
flat-fuchsiaOP12mo ago
Thanks for the example, mind linking the above repo? I'll record a video of what's going on over here in a few. Attached a screenshot, I'm definitely splitting. Started stepping through router.ts last night and the callstack for the mouseenter handler to walk the flow of doPreload. It does trigger when I hover on my <Link preload="intent> ... </Link>. Started digging for why it doesn't actually perform the loading. If anything, I want to help ensure it's operator error so others can avoid the same thing 😅 .
No description
No description
rising-crimson
rising-crimson12mo ago
GitHub
router/examples/react/quickstart-file-based at main · TanStack/router
🤖 Fully typesafe Router for React (and friends) w/ built-in caching, 1st class search-param APIs, client-side cache integration and isomorphic rendering. - TanStack/router
rising-crimson
rising-crimson12mo ago
is it possible that you share your app with us?
flat-fuchsia
flat-fuchsiaOP12mo ago
@Manuel Schiller Happy to hop on a Google meet and screenshare/walkthrough my setup. Additional notes: - _layout.tsx is my core layout file, _ideas.tsx and _groups.tsx are the respective tabbed layouts for each of their nested routes (individual tab content resides inside _ideas and _groups folders. - On latest package version 1.57.15 - Setting true/false on autoCodeSplitting does correctly work, it's just preload="intent" does nothing. - Running on tRPC + tanstack-query for data-fetching — I haven't started playing with loader options (yet), I did yank all <Suspense> implementations to see if that made any difference during preloading — no such luck. - I'm in your shoes most days (debugging client issues), I'll keep digging but LMK if you want to block off 15-20 min to 👀 on a screenshare. Another option, DM me and I can provide steps for logging in to the deployed environment.
No description
flat-fuchsia
flat-fuchsiaOP12mo ago
Interesting, I'm able to replicate what I'm seeing in my project starting with the example from https://github.com/TanStack/router/tree/main/examples/react/quickstart-file-based. I enabled autoCodeSplitting in the example's vite config. Code properly splits but hovering over the links does not preload on intent until I add .lazy to the filename. I guess I was under the impression routes would be defined with createLazyFileRoute under the hood when code-split.
flat-fuchsia
flat-fuchsiaOP12mo ago
Added a "Hover me" example in the video above that behaves how I'd expect.

Did you find this page helpful?