You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In a SPA using the recommended TanStack Query integration, loaders typically call queryClient.ensureQueryData()without awaiting so navigation stays instant, and components read the data with useSuspenseQuery. In this setup head({ loaderData }) can't produce a dynamic title: loaderData is empty when head() runs, and head() is never re-invoked once the data lands in the cache.
Current options all have drawbacks:
Await the loader → blocks navigation, defeating the non-blocking pattern.
useEffect + document.title after Suspense resolves → works, but bypasses HeadContent, and only by relying on the (undocumented) fact that HeadContent won't rewrite an unchanged title.
React 19 <title> hoisting → conflicts with the <title> that HeadContent renders (duplicate tags, first-in-document wins).
Proposal
First-class support for a two-phase title: a static fallback shown at navigation, replaced when async data resolves. Possible shapes:
Re-run head() when an unawaited/deferred promise returned from the loader resolves (Await-aware head), or
A supported API for a route component to update its own match's head after data arrives — e.g. a useHead() hook or <RouteHead title={...} /> component that participates in HeadContent's dedupe/override chain.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Problem
In a SPA using the recommended TanStack Query integration, loaders typically call
queryClient.ensureQueryData()without awaiting so navigation stays instant, and components read the data withuseSuspenseQuery. In this setuphead({ loaderData })can't produce a dynamic title:loaderDatais empty whenhead()runs, andhead()is never re-invoked once the data lands in the cache.Current options all have drawbacks:
useEffect+document.titleafter Suspense resolves → works, but bypassesHeadContent, and only by relying on the (undocumented) fact thatHeadContentwon't rewrite an unchanged title.<title>hoisting → conflicts with the<title>thatHeadContentrenders (duplicate tags, first-in-document wins).Proposal
First-class support for a two-phase title: a static fallback shown at navigation, replaced when async data resolves. Possible shapes:
head()when an unawaited/deferred promise returned from the loader resolves (Await-awarehead), oruseHead()hook or<RouteHead title={...} />component that participates inHeadContent's dedupe/override chain.Related
document.titleworkaroundheadrunning before the loader finishes (the awaited case)All reactions