Router

How this site shows the bar while a navigation is loading.

The component

TanStack Router announces a navigation with onBeforeNavigate and its end with onResolved. The component turns those two events into one boolean, and the boolean into a Hold.

tsx
// features/holdbar/holdbar_route.tsx
export const HoldbarRoute = () => {
  const router = useRouter();
  const [isLoading, setIsLoading] = useState(false);

  useEffect(() => {
    const unsubscribeNavigate = router.subscribe("onBeforeNavigate", () => setIsLoading(true));
    const unsubscribeResolved = router.subscribe("onResolved", () => setIsLoading(false));

    return () => {
      unsubscribeNavigate();
      unsubscribeResolved();
    };
  }, [router]);

  return (
    <Holdbar className="text-primary mix-blend-difference" height={3}>
      {isLoading && <Holdbar.Hold />}
    </Holdbar>
  );
};

Instant navigations

Moving between pages of the same section resolves almost instantly, and the bar still shows up for a moment. That's the finish: however short the load, the bar runs to the end at full colour and fades out. The component doesn't time anything, it only says when a navigation starts and ends.

Other routers

Nothing in the component depends on the library: any router that tells you when a navigation starts and ends works the same way. Where the router has no events, the component is the place to find them, and the bar still only needs a Hold.