Streaming SSR & Skeleton Loading States
Streaming SSR & Skeleton Loading States
BlockManOS uses Next.js App Router's streaming SSR to display instant skeleton loading screens on every dashboard route navigation. This is implemented via the loading.tsx convention — no changes to page components are required.
How It Works
When a user navigates to a dashboard section:
- Next.js immediately renders the nearest
loading.tsxfile as a React Suspense fallback. - The real page component fetches its data in the background (server-side).
- Once data is ready, Next.js streams the complete page content to the client, replacing the skeleton.
Because skeletons are rendered at the route segment level, the sidebar and shell remain interactive during loading — only the main content area shows the placeholder.
Skeleton Component Library
All skeletons are defined in src/components/skeleton.tsx. The base Skeleton component is a simple animated pulse block:
import { Skeleton } from "@/components/skeleton";
// Any size via Tailwind classes
<Skeleton className="h-8 w-64" />
Five higher-level layout components are provided, each matching the visual shape of a group of pages:
PageSkeleton
A page heading and a single large content card. Used for pages with a single primary content area.
import { PageSkeleton } from "@/components/skeleton";
export default function Loading() {
return <PageSkeleton />;
}
Used by: Settings, Admin, Communications, Irish Legislation, Annual Plan, Owners Import
TablePageSkeleton
A toolbar row, a table header, and a configurable number of data rows. Accepts an optional rows prop (default: 6).
import { TablePageSkeleton } from "@/components/skeleton";
export default function Loading() {
return <TablePageSkeleton rows={8} />;
}
Used by: Maintenance, Owners, Developments, Compliance, OMC, CRO Compliance, Team, Activity, Jobs, GDPR, PSRA
FinancePageSkeleton
Four stat-cards arranged in a row above a main content area. Matches the layout of financial overview pages.
import { FinancePageSkeleton } from "@/components/skeleton";
export default function Loading() {
return <FinancePageSkeleton />;
}
Used by: Dashboard root, Budget, Service Charges, Reports, Bank Reconciliation, Sinking Fund
SchedulePageSkeleton
A filter/controls row above a card grid. Matches calendar and schedule-style pages.
import { SchedulePageSkeleton } from "@/components/skeleton";
export default function Loading() {
return <SchedulePageSkeleton />;
}
Used by: AGM, PPM
DocumentPageSkeleton
A search bar above a file/document grid.
import { DocumentPageSkeleton } from "@/components/skeleton";
export default function Loading() {
return <DocumentPageSkeleton />;
}
Used by: Documents
Adding a Skeleton to a New Route
To add streaming SSR loading to a new App Router route segment:
- Choose the skeleton layout that best matches the page's visual structure.
- Create a
loading.tsxfile in the route directory. - Export a default
Loadingcomponent that renders the chosen skeleton.
// src/app/dashboard/my-new-route/loading.tsx
import { TablePageSkeleton } from "@/components/skeleton";
export default function Loading() {
return <TablePageSkeleton rows={6} />;
}
Next.js will automatically use this file as the Suspense fallback — no further configuration is needed.
Route Coverage
All 26 current dashboard route directories have a loading.tsx file as of v1.0.51.
| Route | Skeleton | Rows |
|---|---|---|
dashboard/ | FinancePageSkeleton | — |
dashboard/activity | TablePageSkeleton | 8 |
dashboard/admin | PageSkeleton | — |
dashboard/agm | SchedulePageSkeleton | — |
dashboard/annual-plan | PageSkeleton | — |
dashboard/bank-reconciliation | FinancePageSkeleton | — |
dashboard/budget | FinancePageSkeleton | — |
dashboard/communications | PageSkeleton | — |
dashboard/compliance | TablePageSkeleton | 6 |
dashboard/developments | TablePageSkeleton | 8 |
dashboard/documents | DocumentPageSkeleton | — |
dashboard/gdpr | TablePageSkeleton | 5 |
dashboard/irish-legislation | PageSkeleton | — |
dashboard/jobs | TablePageSkeleton | 6 |
dashboard/maintenance | TablePageSkeleton | 8 |
dashboard/omc | TablePageSkeleton | 6 |
dashboard/omc/cro-compliance | TablePageSkeleton | 6 |
dashboard/owners | TablePageSkeleton | 7 |
dashboard/owners/import | PageSkeleton | — |
dashboard/ppm | SchedulePageSkeleton | — |
dashboard/psra | TablePageSkeleton | 6 |
dashboard/reports | FinancePageSkeleton | — |
dashboard/service-charges | FinancePageSkeleton | — |
dashboard/settings | PageSkeleton | — |
dashboard/sinking-fund | FinancePageSkeleton | — |
dashboard/team | TablePageSkeleton | 5 |