Loading and Error UI — Complete Guide
Loading and Error UI — Complete Guide: free step-by-step lesson with examples, common mistakes, and interview tips — part of Next.js Tutorial on Toolliyo Academy.
On this page
Next.js Tutorial (LearnHub) · Lesson 33 of 100
Loading and Error UI
Beginner ✓ → Intermediate → Advanced → Professional
Intermediate · 2 — Building apps · ~14 min read · Module 4: Auth & APIs
Introduction
You know the basics now. Here we use Loading and Error UI in real LearnHub screens — layouts, data, and APIs. Still plain language, just a bit more depth. loading.tsx shows instant feedback while a route segment loads. error.tsx catches runtime errors in that segment and shows a recovery UI. When LearnHub lesson data is slow or fails, students should see a skeleton or friendly error — not a frozen blank page.
Route Handlers are how LearnHub talks to webhooks and mobile clients. Get JSON responses solid here.
When will you use this?
Use Route Handlers when a mobile app, webhook, or external client needs JSON from your server.
- Mobile apps and partner sites call your Next.js Route Handlers for JSON over HTTP.
- Webhook endpoints for payment providers live in app/api routes.
Real-world: Zoho-style SaaS dashboard
The B2B SaaS team building Zoho-style SaaS dashboard uses Loading and Error UI to apply Loading and Error UI when building billing, team settings, and analytics widgets. tenant admins never see the TypeScript files — they just get a fast, reliable billing, team settings, and analytics widgets.
Production-style code
// app/courses/[slug]/loading.tsx
export default function Loading() {
return <div className="animate-pulse">Loading course...</div>;
}
// app/courses/[slug]/error.tsx
'use client';
export default function Error({
error,
reset
}: {
error: Error;
reset: () => void;
}) {
return (
<div>
<p>Could not load this course.</p>
<button type="button" onClick={reset}>Try again</button>
</div>
);
}
What happens in production: In Zoho-style SaaS dashboard, getting Loading and Error UI right means tenant admins trust the billing, team settings, and analytics widgets every day.
Lesson example (start here)
Copy this smaller example first. Once it works, compare it with the real-world code above.
// app/courses/[slug]/loading.tsx
export default function Loading() {
return <div className="animate-pulse">Loading course...</div>;
}
// app/courses/[slug]/error.tsx
'use client';
export default function Error({
error,
reset
}: {
error: Error;
reset: () => void;
}) {
return (
<div>
<p>Could not load this course.</p>
<button type="button" onClick={reset}>Try again</button>
</div>
);
}
Line-by-line walkthrough
| Code | What it means |
|---|---|
// app/courses/[slug]/loading.tsx | Comment — notes for humans; the compiler ignores it. |
export default function Loading() { | Default export — the main page or component this file provides to Next.js. |
return <div className="animate-pulse">Loading course...</div>; | Returns JSX — what the user sees in the browser. |
} | Closes a block started by { above. |
// app/courses/[slug]/error.tsx | Comment — notes for humans; the compiler ignores it. |
'use client'; | Marks this file as a Client Component — can use useState, onClick, and browser APIs. |
export default function Error({ | Default export — the main page or component this file provides to Next.js. |
error, | Part of the Loading and Error UI example — read it together with the lines before and after. |
reset | Part of the Loading and Error UI example — read it together with the lines before and after. |
}: { | Closes a block started by { above. |
error: Error; | Part of the Loading and Error UI example — read it together with the lines before and after. |
reset: () => void; | Part of the Loading and Error UI example — read it together with the lines before and after. |
}) { | Closes a block started by { above. |
return ( | Returns JSX — what the user sees in the browser. |
How it works (big picture)
- loading.tsx is a Server Component shell shown during suspense.
- error.tsx must be a Client Component because it uses reset().
Do this on your computer
- Add loading.tsx to a dynamic course route.
- Add artificial delay in fetch to see the skeleton.
- Add error.tsx and throw in fetch to test recovery.
- Read the real-world section and name which part of LearnHub uses this topic.
- Run the example locally with npm run dev and confirm the same behavior.
- Change one value in the example (route, text, or course id) and predict what will happen before you save.
Experiments — try changing this
- Change a string or route in the example and save — watch the browser update.
- Break the code on purpose (remove a bracket), read the error overlay, then fix it.
- Use npm run dev while editing Loading and Error UI — the page hot-reloads on save.
Remember
loading.tsx = route-level suspense fallback. error.tsx = catch and recover. Pair with not-found.tsx for 404 cases.
Common questions
Difference from Suspense fallback?
loading.tsx applies to the whole route segment automatically; inline Suspense is for parts of a page.
How long should I spend on Loading and Error UI?
Until you can explain it in your own words and run the example without looking at the answer. Beginners often need 30–60 minutes per new concept; setup lessons may take one afternoon.
What if I get stuck on Loading and Error UI?
Re-read the line-by-line walkthrough, check the terminal and browser overlay for errors, and compare your code character-by-character with the example. Search the exact error text — someone else had it too.
Where is Loading and Error UI used in real jobs?
See the real-world section above — the same pattern appears in LMS, e-commerce, SaaS, and dashboards. Interviewers ask you to explain it using one concrete example.