React Holdbar

A loading bar at the top of the page that stays open while something is loading, with no start or done to call.

Usage

Mount the bar once. Then anything that is loading mounts a Holdbar.Hold, and the bar stays open until the last one is gone: a save, a mutation, a Suspense boundary, a navigation.

tsx
<Holdbar className="text-primary" height={3} />

{isSaving && <Holdbar.Hold />}

<Suspense fallback={<Holdbar.Hold />}>
  <Comments />
</Suspense>

Each button mounts its own Hold for a few seconds, on the same bar this site uses when you navigate. Press both: the bar waits for the slower one, and neither button knows the other exists.

What you get

  • No start, no done. There's nothing to call and nothing to forget to close. Loads that overlap don't need to agree on who closes the bar.
  • A bar before hydration. Whether the bar is open is plain CSS, so a Hold in a streamed Suspense fallback moves it while the JavaScript is still downloading.
  • A finish that never flickers. However short the load, the bar runs to the end at full colour, then fades out. minVisible keeps it filling for a while first, if you want it to.
  • Server Components. Holdbar and Holdbar.Hold both render from a Server Component, so a page can use a Hold as its Suspense fallback and stay on the server.
  • Styled like the rest of the page. Its colour is the color of the element, height and speed are props, and with reduced motion it fades instead of moving.

Limits

The bar shows that something is loading, not how much. It fills towards 90% on its own, slowing down as it goes, and it never knows the real progress of a load.