loading.js: the instant fallback
If app/blog/page.js takes two seconds to fetch, what does the user see meanwhile? Without help: the old page, frozen. Next.js fixes this with another special file:
// app/blog/loading.js export default function Loading() { return <p>Loading posts…</p>; }
Drop it next to page.js and Next.js shows it immediately on navigation, then streams in the real page when the data resolves. Under the hood this is React <Suspense>, wired up by the file convention. In the React course you managed loading flags by hand. Here the router does it for the whole page.
error.js: the safety net
When a page throws (the API is down, the JSON is malformed), the matching error.js renders instead of a crash:
// app/blog/error.js "use client"; export default function Error({ error, reset }) { return ( <div> <p>Something went wrong.</p> <button onClick={reset}>Try again</button> </div> ); }
Two details to decode:
error.jsmust be a client component. It needs theonClickforreset, which re-attempts the render.- Like layouts, both files scope to their folder: an
error.jsinapp/blog/catches blog failures without touching the rest of the site.
Quiz
Why does error.js require the "use client" directive?
Problem
Your /dashboard page fetches slowly and users see nothing during navigation. Which special file do you add to app/dashboard/ to show an instant skeleton? (file name)