From 8c3b6415de5883d4b8f324a52a7e8ef262c425e0 Mon Sep 17 00:00:00 2001 From: Ignazio De Santis Date: Sun, 12 Jul 2026 16:47:04 +0800 Subject: [PATCH] fix(website-tanstack): stop the pending flash and make intent preloading effective Addresses the navigation half of #462. Two router options were fighting the framework: - defaultPendingMs: 0 entered the pending state on every navigation whose loader had not already resolved, and defaultPendingMinMs (500ms framework default) then held that blank pending frame for at least half a second - the black-screen flash on each route change. Removing the override restores the 1000ms threshold, so pending UI only appears for genuinely slow loads. - defaultPreloadStaleTime: 0 marked every intent/viewport preload stale by the time the user actually clicked, so the loader re-ran and blocked the transition. Hover preloading was effectively disabled. The 0 setting is meant for loaders that delegate caching to an external store (queryClient.ensureQueryData); the doc/blog loaders call server functions directly, so the framework default (30s) is the correct behavior here. Verified against @tanstack/router-core defaults (defaultPendingMs: 1000, defaultPendingMinMs: 500, preloadStaleTime default 30_000). --- apps/website-tanstack/src/router.tsx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/apps/website-tanstack/src/router.tsx b/apps/website-tanstack/src/router.tsx index 5ae142ef21..0ff2435bd9 100644 --- a/apps/website-tanstack/src/router.tsx +++ b/apps/website-tanstack/src/router.tsx @@ -13,9 +13,21 @@ export function getRouter() { }, scrollRestoration: true, defaultPreload: 'intent', - defaultPreloadStaleTime: 0, + // Preloaded loader data must stay fresh long enough to satisfy the + // navigation it was preloaded for (framework default: 30s). + // `defaultPreloadStaleTime: 0` marked every intent/viewport preload + // stale by click time, so the loader re-ran and blocked the + // transition — hover preloading was effectively disabled. 0 is only + // appropriate when loaders delegate caching to an external store + // (e.g. queryClient.ensureQueryData); these loaders call server + // functions directly. defaultStaleTime: Infinity, - defaultPendingMs: 0, + // `defaultPendingMs: 0` entered the pending state on EVERY navigation + // whose loader had not already resolved, and `defaultPendingMinMs` + // (500ms framework default) then held that blank pending frame for at + // least half a second — the "black screen flash" on each route + // change. The framework default (1000ms) only shows pending UI for + // genuinely slow loads. defaultNotFoundComponent: NotFoundComponent, });