Lesson 6 +10 XP

Loading UI and Error Boundaries (loading.tsx, error.tsx, not-found.tsx)

Loading UI and Error Boundaries (loading.tsx, error.tsx, not-found.tsx)

Next.js provides special reserved files to handle loading states, uncaught runtime errors, and 404 pages gracefully without boilerplate code.

1. Instant Loading UI (loading.tsx)

loading.tsx uses React Suspense behind the scenes. It displays fallback UI (such as skeleton loaders) instantly while page content or data fetching completes on the server.

// app/dashboard/loading.tsx
export default function DashboardLoading() {
  return (
    <div className="p-6 space-y-4 animate-pulse">
      <div className="h-8 w-48 bg-slate-200 rounded"></div>
      <div className="h-64 w-full bg-slate-200 rounded"></div>
    </div>
  );
}

2. Graceful Error Handling (error.tsx)

error.tsx automatically wraps child routes in a React Error Boundary. Must be a Client Component ('use client').

// app/dashboard/error.tsx
'use client';

import { useEffect } from 'react';

export default function DashboardError({
  error,
  reset,
}: {
  error: Error & { digest?: string };
  reset: () => void;
}) {
  useEffect(() => {
    console.error('Logged to error reporting service:', error);
  }, [error]);

  return (
    <div className="p-6 bg-red-50 border border-red-200 rounded-md">
      <h2 className="text-xl font-bold text-red-700">Something went wrong!</h2>
      <p className="text-sm text-red-600 mt-1">{error.message}</p>
      <button
        onClick={() => reset()}
        className="mt-4 px-4 py-2 bg-red-600 text-white rounded hover:bg-red-700"
      >
        Try Again
      </button>
    </div>
  );
}

3. Custom 404 Pages (not-found.tsx)

not-found.tsx renders when the notFound() function is invoked in a Server Component or when a URL path doesn't match any route.

// app/not-found.tsx
import Link from 'next/link';

export default function NotFound() {
  return (
    <main className="flex flex-col items-center justify-center min-h-screen">
      <h1 className="text-4xl font-extrabold">404 - Page Not Found</h1>
      <p className="mt-2 text-slate-600">The requested resource could not be found.</p>
      <Link href="/" className="mt-4 text-blue-600 underline">
        Return Home
      </Link>
    </main>
  );
}

Summary Table

Special FileReact FeatureComponent RequirementFunctionality
loading.tsx<Suspense>Server or ClientRenders immediate skeleton loader UI
error.tsx<ErrorBoundary>Must be Client Component ('use client')Catches runtime errors & provides reset()
not-found.tsxFallback HandlerServer or ClientRenders UI when notFound() is triggered

TL;DR

  • loading.tsx creates instant visual feedback using React Suspense.
  • error.tsx must be a Client Component ('use client') and provides a reset() retry handler.
  • Trigger 404s programmatically using notFound() imported from next/navigation.
  • These special files isolate failures to specific sub-branches of your UI tree.