Loading & Error States

Catmint uses file-based conventions for loading and error UI. Place a loading.tsx in a route directory for Suspense fallbacks, and an error.tsx for error boundaries.

Suspense with Async Components

The component below is an async server component that takes 2 seconds to resolve. While it loads, React shows the Suspense fallback. In a real app, loading.tsx in the route directory would provide this automatically.

Loading slow data...

Error Boundary

The component below throws an error on demand. The ErrorBoundary catches it and shows a fallback with a reset button. In a real app, error.tsx in the route directory provides this automatically.

Click the button below to throw a runtime error. The ErrorBoundary will catch it and show the fallback UI with a “Try Again” button.

Server Error (Async)

Async server components can also throw. The error boundary catches rendering errors from any child, whether sync or async.

Loading error-prone component...

File Convention

app/
  dashboard/
    page.tsx        # Your page
    loading.tsx     # Suspense fallback (auto-wrapped)
    error.tsx       # Error boundary (auto "use client")

// loading.tsx
export default function Loading() {
  return <div>Loading dashboard...</div>
}

// error.tsx — receives { error, reset } props
export default function Error({
  error,
  reset,
}: {
  error: Error
  reset: () => void
}) {
  return (
    <div>
      <p>Error: {error.message}</p>
      <button onClick={reset}>Retry</button>
    </div>
  )
}
  • loading.tsx is used as the Suspense fallback for the route segment
  • error.tsx is automatically treated as a client component (the Vite plugin injects "use client")
  • Error boundaries don't catch errors from layout.tsx in the same directory
  • Both files walk up the directory tree — parent loading/error files apply to child routes