Ominvo beta launches July 23, 2026 — only 10 spots remain Join the waitlist →
All posts
Building OminvoDay 59

We built loading skeletons before anyone paid us a dollar

June 23, 20264 min read

Nobody noticed the blank flash between navigating to the app and seeing actual content. There's no one to notice. We have zero paying customers.

We fixed it anyway.

What shipped today

Three loading skeletons — one for the dashboard, one for reviews, one for settings.

Each is a static server component that Next.js renders immediately while the real page fetches data. No client JavaScript. No external library. One CSS pattern repeated across all three:

bg-white/[0.06] animate-pulse

A dark, slightly translucent block that gently pulses. The size and shape of each block mirrors the real content it stands in for — four stat cards in a 2×4 grid on the dashboard, a filter bar and five review rows on reviews, four settings cards (business info, password, notifications, billing) on settings.

The settings skeleton is worth calling out separately. The real settings page shows different UI depending on your subscription tier. The skeleton shows the same four card outlines regardless. That's intentional. If the skeleton guessed your tier and got it wrong, you'd see one layout flash in and then shift to another as the real page loaded. Generic is the right call here — the goal is zero visible shift on hydration, and a tier-aware skeleton introduces the exact shift it's supposed to prevent.

Why we built this before anyone's watching

The honest reason: a blank screen during load is the kind of thing a skeptical small business owner clocks in the first few seconds and doesn't forget.

They're not beta testers. They're someone who runs a restaurant or a salon and is trying to decide in 30 seconds whether this tool is worth paying for. A blank white flash during navigation isn't a feature gap — it's a signal that the product wasn't tested by someone who actually uses it.

That signal is hard to un-send. Once the impression is set, you're working against it.

The counterargument we heard in our own heads

This is exactly the type of work founders defer until customers complain. It's invisible when it works. It takes effort to notice it's missing. There are always higher-priority items on the list.

We've been logging sixty days of this work on the changelog. Some of it is obviously critical — auth flows, Stripe webhooks, Supabase RLS. Some of it looks like polish. Yesterday it was a globe rolling between billing labels. Today it's placeholder blocks.

The line between polish and signal is thinner than it looks. At zero customers, polish is signal building. By the time someone's on the fence about upgrading, a dozen small impressions have already accumulated. Deferring the small things doesn't make them cost nothing — it means the cost shows up at the worst possible moment, during someone's first visit.

What it actually took

Three files. About 35 lines each.

The dashboard skeleton mirrors the outer structure of the real page — same header, same max-w-4xl wrapper, same title block — so when the real page loads, there's no layout shift. Reviews follows the same pattern. Settings uses max-w-2xl because the settings cards are narrower than the dashboard. Getting that detail right matters — if the skeleton is wider than the real content, the shift on hydration is visible.

TypeScript compiles clean across all three. No output from tsc --noEmit means no errors.

What this means if you sign up tomorrow

You probably won't see the skeletons. On a normal connection, with our server at normal load, the pages load fast enough that they never appear. The whole point of a skeleton is that it's invisible when things go right.

But if your connection is slow, or you're on a mobile network that hiccups, or our server is briefly under load — you won't see a blank page. You'll see a structured placeholder that tells you the content is coming. That's the difference between a product that feels tested and one that wasn't.

We'd rather build the former, even before there's anyone watching.

Tagged

#ui#building#performance

Written by

The founder of Ominvo

Building review management for single-location small businesses. Join the waitlist →