Possible to call loader without navigating to url?
Was wonder if it's possible with tanstack router to call the loader without triggering the navigation.
I.e. would like to overwrite the <Link /> component to "onMouseDown" load the loader, so all data can already be fetched. onClick it naviates to the page.
5 Replies
sensitive-blue•9mo ago
looks like you are looking for route preloading?
you can manually preload a route via
router.preloadRoute
but this shouldnt even necessary
"intent" preloading is the default in router
which means when hovering over a link, the route is preloadwddeep-jadeOP•6mo ago
@Manuel Schiller Hmm no, I think the "intent" is to agressive, also preloads on hover, just looking for a wrapper (with correct typing) that instead makes it so it preloads on mouse down
nvm, I now got this working:
sensitive-blue•6mo ago
we could maybe add this as another preload strategy. needs some more thinking about how to handle mobile maybe
@Sean Cassiere what do you think?
xenial-black•6mo ago
onMouseDown behaves pretty similarly to onClick. The only reason you don't see double navigations here is that we dedupe the navigation calls.
deep-jadeOP•6mo ago
@Sean Cassiere the onMouseDown triggers when the mouse click is down, while the onClick fires when the mouse is up again (on the same element). for normal users between mouse down and up is 150-200ms, e.g. we can trigger the loader 150-200ms earlier (on the mouse down already, and hence all fetching is done 150-200ms earlier. Include the react rendering etc and you get 250ms for free when the user made a ver serious intent (mouse down on that element), even slow request now look decently fast.
In our case there are also url's for images that need to be loaded on the page, normally for these to load we need to wait for react to render everything and wait for the url to be attached to the <img/> dom node before it's fetched. Instead we do the following in our loaders to preload the images:
This if very well possible in the 250ms that we get for free with onMouseDown (compared to onClick), e.g. relative slow response of 150ms with a slow cloudfront load of the images of 100ms, and the page load looks instant, without loading spinners or flashing images, as everything is already there and cached.
EDIT: maybe also good to make clear that I don't use the loader caches or return values, we always work with react-query and in loaders use client.queryClient.ensureQueryData(...). Feels like a very flexible way to load the data, and have it easily accessible via react-query in my components for if the data is not loaded yet. In the loader self I return a Promise.race(...) where it races between a 100ms promise or the promises returned from the ensureQueryData calls. His way the page will wait at maximum 100ms before loading the page (or earlier if all data is already fetched). If after 100ms the ensureQueryData(..) data is not yet fetched the page is loaded, and on the page itself it uses react-query to show relevant dummy data/spinners if needed.