How do loading.js and error.js integrate with Suspense and Error Boundaries?
Tests grasp of App Router conventions wrapping React primitives. loading.js suspends its segment for instant navigation feedback; error.js adds a client Error Boundary for child segment crashes. Wrong: assuming they are server-only or replace manual usage.
WHAT THIS TESTS: Whether you understand that Next.js App Router special files are framework conventions around standard React primitives rather than proprietary magic. The interviewer wants to see that you know loading.js is a declarative Suspense boundary and error.js is a declarative Error Boundary, and that both operate at the route segment level to improve perceived performance and resilience.
A GOOD ANSWER COVERS four things in order. First, loading.js is a convention that automatically wraps the segment's children in a React Suspense boundary; the exported default component renders as the fallback while the segment's async work resolves. Second, this gives instant feedback during navigation because the browser can stream the fallback immediately without waiting for the server to finish data fetching. Third, error.js creates a client-side React Error Boundary that catches rendering errors in its segment and all nested child segments, displaying a fallback UI instead of unmounting the entire page. Fourth, because error.js is a client component boundary, it can recover from crashes in server or client components below it while preserving parent layouts above it.
COMMON WRONG ANSWERS: Thinking loading.js only works for client-side navigation or that it replaces manual Suspense components inside your own code. Another red flag is saying error.js runs on the server; it is explicitly a client-side Error Boundary, so it only catches errors during client rendering or hydration, and during SSR it acts as a passive boundary that activates on the client. Also, claiming these files eliminate the need for error handling in data fetching libraries like throwing within async server components.
LIKELY FOLLOW-UPS: How would you share a loading state across multiple sibling segments? When would you still use a manual Suspense component instead of loading.js? How does error.js interact with the root layout, and why can you not catch errors in the root layout itself with an app-level error.js? What happens to metadata or head content when a segment is suspended?
ONE CONCRETE EXAMPLE: Imagine a dashboard at app/dashboard/page.js that fetches revenue data taking 800ms. Without loading.js, the browser stares at the previous page until the server streams the full response. With app/dashboard/loading.js, Next.js wraps the dashboard segment in Suspense and immediately streams a skeleton UI. If the revenue fetch throws because a database connection drops, an app/dashboard/error.js boundary catches the render error and shows a retry button, while the root layout and sidebar remain fully interactive.
Read the original → nextjs.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.