loading.js file creates an automatic React Suspense boundary around the page.js file and its children. The fallback UI is shown immediately on navigation and swapped for the real content once it finishes streaming.
app/dashboard/loading.js
Parameters
Loading UI components do not accept any parameters.Behavior
Instant loading states
The fallback UI is prefetched along with the route, so navigation feels instant. You can use any lightweight UI: skeletons, spinners, or a partial preview of the page content (cover photo, title, etc.).loading.js automatically wraps page.js and nested layouts in a <Suspense> boundary within the same route segment.
Navigation
- Navigation is interruptible — users can navigate away before the page finishes loading
- Shared layouts remain interactive while new segments load
- The fallback is prefetched, making navigation feel immediate
Layouts and loading.js
loading.js sits below layout.js in the component hierarchy. This means it cannot show a fallback for uncached or runtime data access in the layout itself (such as cookies(), headers(), or uncached fetch calls).
To ensure instant navigation when a layout fetches data:
- Wrap runtime data access in the layout with its own
<Suspense>boundary - Move uncached data fetching from
layout.jsintopage.js
app/dashboard/layout.js
Status codes
Streamed responses return a200 status code. Errors and not-found states are communicated through the streamed content itself. Because headers are sent before streaming begins, the status code cannot be changed after streaming starts.
Platform support
| Deployment option | Supported |
|---|---|
| Node.js server | Yes |
| Docker container | Yes |
| Static export | No |
| Adapters | Platform-specific |
Examples
Skeleton loading UI
app/dashboard/loading.js
Granular Suspense boundaries
You can also manually place<Suspense> boundaries for individual components rather than wrapping the entire page:
app/dashboard/page.js
- Streaming server rendering — HTML is progressively sent from server to client
- Selective hydration — React prioritizes making the most-interacted components interactive first
Pending state with useFormStatus
For<Form> submissions, use useFormStatus to show pending state before the loading UI appears:
app/ui/search-button.js
Version history
| Version | Changes |
|---|---|
v13.0.0 | loading introduced |
