King of Flavors docs

Loader UI

Frame-by-frame review of the splash-to-sign-in page transition and content loader behavior.

Loader UI

This review looks specifically at the maintenance splash to sign-in transition. The loader is intentionally a content-area loader: it should sit below the fixed header, cover the assembling page underneath it, and avoid turning the header itself into a full-screen loading state.

Current intent

The content loader exists for one narrow job: keep the user from seeing a destination page assemble in layers. For the splash pages, that means hiding the page until the logo images decode, the splash has non-zero layout, and the smoke shader has rendered or gracefully failed.

The loader should feel deliberate when it appears. A one-frame loader flash reads like a mistake, even if the app is technically doing the right thing.

Frame-by-frame transition

Frame 0: Maintenance splash is settled

The maintenance page is the starting state. The header reads Under maintenance, the action reads Sign in, and the page content is the full-viewport location splash.

The content loader should be absent here. The splash already owns its readiness and has revealed itself.

Frame 1: User activates sign-in

React Router begins moving from / to /login. The fixed header remains visible and should not be covered by the loader.

The content loader may appear below the header because the destination page is not ready yet. This is acceptable, but it needs to be visible long enough to feel intentional.

Frame 2: Auth page mounts behind the loader

The sign-in page is a simpler form page, not a layered splash. It can mark itself ready after mount.

This is where the previous flash came from: auth readiness could complete almost immediately, so the content loader entered and exited too quickly. The fix is a small minimum display duration after the loader appears.

Frame 3: Header text changes

The header changes from the maintenance variant to the auth variant. The label changes from Under maintenance to Member access, and the action changes from Sign in to Storefront.

The previous animated text swap made the two labels visually overlap and flicker. The fix is to render these labels as stable text inside fixed-size slots. The header can still layout-morph, but the words should not crossfade back and forth.

Frame 4: Loader exits

Once the auth page is mounted and the minimum loader duration has elapsed, the content loader fades out. The header remains visible above it for the whole transition.

This frame should feel like a short page handoff, not a full app reboot.

Frame 5: Sign-in is stable

The sign-in form is now the primary page. The content loader is removed, the header reads Member access, and the action reads Storefront.

At this point there should be no lingering loader, no old header text, and no splash artifacts.

Loader style options

The app now has two loader styles in apps/web/src/config/app-config.ts:

  • original: compact crown mark, subtle sheen, King of Flavors label.
  • branded: the newer large white location logo with progress bar.

The current default is original, because it is quieter and closer to the earlier app loader from commit 2671568.

visuals: {
  contentLoader: {
    style: "original",
    minDisplayMs: 420
  }
}

Use style: "branded" when the desired transition is closer to a full brand interstitial. Use style: "original" when the loader should read as a short content handoff beneath the persistent header.

Current recommendations

Keep the loader under the header. That preserves the app-shell feeling and avoids making sign-in feel like a separate site.

Keep the minimum display duration modest. Around 420ms is enough to prevent a flash without bringing back the old fixed 760-860ms wait.

Keep splash readiness owned by LocationSplash. The page shell should not guess how long the shader, image decode, or layout settle will take.

Keep header label changes non-animated for maintenance/auth. The nav container can still morph, but those two text labels should behave like state labels, not animated content.

On this page