Dashboard WorkQueue Skeleton Loading — What Changed and Why
Dashboard WorkQueue Skeleton Loading — What Changed and Why
Release: v0.1.265
Overview
The dashboard has been updated to use a full skeleton loading state for the WorkQueue component, replacing the previous spinner fallback. This is a targeted UI/UX improvement that affects every dashboard page load.
Background
The WorkQueue is the most important above-the-fold component on the dashboard. It lists active tenancy cases and is the first thing landlords, agents, and tenants interact with after logging in.
Because WorkQueue is loaded via Next.js dynamic() (code-split for performance), it requires a loading fallback while the component bundle fetches and renders. Previously, that fallback was a centred <Loader2> spinner inside a padded <div>:
// Before — dashboard-tabs.tsx
const WorkQueue = dynamic(() => import('./work-queue'), {
loading: () => (
<div className="flex justify-center py-12">
<Loader2 className="animate-spin" />
</div>
),
});
This caused two problems:
- Layout shift — The spinner
<div>is much shorter than the realWorkQueue, which can be hundreds of pixels tall. When the real component mounted, the entire page jumped. - Visual inconsistency — Every other dashboard component (summary cards, stats panels, etc.) used rich skeleton cards. The spinner was the only outlier.
What Changed
The loading fallback is now a WorkQueue-shaped skeleton — 3–4 rows of TenancyCard-sized placeholder blocks that match the real component's dimensions:
// After — dashboard-tabs.tsx
const WorkQueue = dynamic(() => import('./work-queue'), {
loading: () => <WorkQueueSkeleton />,
});
The skeleton rows mirror the height, spacing, and structure of real TenancyCard items, so the page layout does not shift when the live data loads in.
User-Facing Impact
| Before | After |
|---|---|
Small spinner shown in a short <div> | Full-height skeleton matching the WorkQueue layout |
| Page jumps when WorkQueue mounts | No layout shift — page is stable from first paint |
| Inconsistent loading UI across dashboard | Uniform skeleton loading across all dashboard components |
Technical Details
- File changed:
src/app/dashboard/dashboard-tabs.tsx - Mechanism: Next.js
dynamic()loadingprop replacement - Skeleton shape: 3–4
TenancyCard-sized skeleton rows - No behavioural changes — only the loading fallback UI is affected; data fetching, routing, and WorkQueue functionality are unchanged
Related Concepts
- Next.js Dynamic Imports —
loadingoption - Cumulative Layout Shift (CLS) — the Core Web Vital this change directly improves