Dashboard Loading States (Suspense Boundaries)
Dashboard Loading States (Suspense Boundaries)
BlockManOS uses Next.js App Router's streaming SSR to show instant skeleton UIs whenever you navigate between dashboard sections. Instead of a blank content area while data loads, each route displays a placeholder that closely matches the shape of the real page.
How It Works
Next.js automatically wraps a route segment in a <Suspense> boundary when a loading.tsx file is present in that route directory. The skeleton is sent to the browser immediately as part of the streamed HTML response, while the async page component and tRPC queries continue resolving on the server in the background.
User navigates to /dashboard/compliance
└─ Next.js streams loading.tsx instantly → user sees skeleton
└─ Page component + tRPC queries resolve → skeleton replaced with real content
No additional client-side logic is required — the behaviour is automatic for every covered route.
Covered Routes
All 29 dashboard route directories have a loading.tsx file.
Detail / Form Pages (PageSkeleton)
| Route | Description |
|---|---|
annual-plan/ | Annual plan overview |
admin/ | Admin settings |
settings/ | User/account settings |
irish-legislation/ | Irish legislation reference |
feedback/ | Feedback submission |
owners/import/ | Owner bulk import |
owners/[id]/ | Individual owner profile |
developments/[id]/ | Development detail |
developments/new/ | Create new development |
omc/[developmentId]/ | OMC overview for a development |
omc/[developmentId]/director-portal/ | Director portal for an OMC |
Table Pages (TablePageSkeleton)
| Route | Rows |
|---|---|
maintenance/ | 8 |
compliance/ | 7 |
communications/ | 6 |
psra/ | 5 |
gdpr/ | 6 |
activity/ | 10 |
jobs/ | 8 |
team/ | 5 |
omc/cro-compliance/ | 6 |
developments/[id]/units/ | 8 |
Finance Pages (FinancePageSkeleton)
| Route |
|---|
budget/ |
service-charges/ |
sinking-fund/ |
bank-reconciliation/ |
reports/ |
Schedule Pages (SchedulePageSkeleton)
| Route |
|---|
agm/ |
ppm/ |
Document Pages (DocumentPageSkeleton)
| Route |
|---|
documents/ |
Skeleton Variants
All skeletons are defined in src/components/skeleton.tsx. The following variants are available:
| Variant | Best for |
|---|---|
PageSkeleton | Detail views, forms, single-entity pages |
TablePageSkeleton | List/table views; accepts a rows prop to control placeholder row count |
FinancePageSkeleton | Finance dashboards with summary cards and data tables |
SchedulePageSkeleton | Calendar or schedule views |
DocumentPageSkeleton | Document library / file list views |
Example
// src/app/dashboard/compliance/loading.tsx
import { TablePageSkeleton } from "@/components/skeleton";
export default function Loading() {
return <TablePageSkeleton rows={7} />;
}
Adding a Skeleton to a New Route
- Create a
loading.tsxfile inside the route directory. - Import the most appropriate skeleton variant from
@/components/skeleton. - Export a default
Loadingcomponent that renders it.
No configuration or provider setup is needed — Next.js picks up loading.tsx files automatically.