A Suspense Boundary For the Whole Segment
loading.tsx — Instant Skeleton
A `loading.tsx` file automatically wraps the segment's children in `<Suspense>`, using the file's default export as the fallback.
What you'll learn
- Create a `loading.tsx` with a skeleton
- See it render instantly on navigation
- Nest loading UIs per segment
The previous lesson showed manual <Suspense> boundaries. For the common case — show a
loading state while the segment’s data loads — Next.js has a convention file.
Drop In a loading.tsx
// app/dashboard/loading.tsx
export default function Loading() {
return (
<div className="skeleton" aria-busy="true">
<div className="skeleton-bar" />
<div className="skeleton-bar short" />
</div>
)
} That is the whole API. Next wraps the segment’s page.tsx (and any nested children) in
a <Suspense> boundary with this component as the fallback.
What the User Sees
On navigation to /dashboard, the loading UI renders instantly while the server fetches
data. When the data is ready, the real page.tsx streams in and replaces it.
Nest Loading States
loading.tsx lives at any segment. A nested route gets its own loading fallback for the
portion of the page that is changing.
app/
dashboard/
loading.tsx # shown when navigating to /dashboard
settings/
loading.tsx # shown when navigating to /dashboard/settings
page.tsx Only the segment that is actually loading shows its skeleton — the shared layout above stays put. That is why navigations feel app-like instead of page-reloads.
error.tsx — Error Boundary →