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!
24 Replies
like-gold•13mo 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 loadingwise-white•13mo 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-fuchsiaOP•13mo 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•13mo ago
Assuming, this was from your react-router config, then yes.
Just create you routes like:
And turn on the
autoCodeSplitting
flag in your TanStackRouterVite
plugin config.flat-fuchsiaOP•13mo 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! ❤️
like-gold•13mo ago
Do you export your route components? The only thing that should be exported from a page file is the
Route
object.flat-fuchsiaOP•13mo ago
There we go! I removed all default exports, only have named Route exports and splitting is now working 🙌 . Thanks all!
rising-crimson•13mo 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-fuchsiaOP•13mo ago
@Manuel Schiller
rising-crimson•13mo ago
thanks, I will make sure this will be a nicer experience
flat-fuchsiaOP•12mo ago
Is the “preload” option on <Link> expected to work with autoCodeSplitting enabled?
wise-white•12mo 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•12mo 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-fuchsiaOP•12mo 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•12mo ago
Just rechecked, preloading DOES work with
autoCodeSplitting
.wise-white•12mo 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•12mo 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•12mo ago
@TrappedInABasement your methodology for testing may be wrong, or you might not actually have the
autoCodeSplitting
flag turned on.flat-fuchsiaOP•12mo 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 😅 .

rising-crimson•12mo ago
this looks like the quick start example
https://github.com/TanStack/router/tree/main/examples%2Freact%2Fquickstart-file-based
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•12mo ago
is it possible that you share your app with us?
flat-fuchsiaOP•12mo 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.
flat-fuchsiaOP•12mo 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-fuchsiaOP•12mo ago
Added a "Hover me" example in the video above that behaves how I'd expect.