ADR-0108shipped
Next.js Best Practices Audit
- Status: shipped
- Date: 2026-02-22
- Deciders: Joel, Panda
Context
joelclaw.com runs Next.js 16.1.5 but doesn’t leverage key framework capabilities. An audit against vercel-labs/next-skills identified six gaps:
- No error boundaries (
error.tsx,global-error.tsx) — failures show blank pages - No loading states (
loading.tsx,<Suspense>) — owner pages flash blank→content ConvexClientProviderwraps ALL routes in root layout — static pages (blog, ADRs, cool finds, home) ship Convex JS bundle and fire auth queries unnecessarily- Relative imports (
../../lib/) instead of@/*path aliases - No
cacheComponents/'use cache'directive usage - Owner pages do client-side auth redirect instead of middleware
Decision
Phase 1 (this ADR)
- Add
app/error.tsxandapp/global-error.tsx - Add
loading.tsxskeletons for owner pages (vault, memory, syslog, system, dashboard, voice) - Convert all relative imports to
@/*aliases across app/ directory - Keep
ConvexClientProviderin root layout — too many cross-cutting Convex deps (SiteHeader, MobileNav, ReviewGate on ADR pages) to cleanly separate
Phase 2 (future)
- Enable
cacheComponents: trueand add'use cache'to data functions - Auth middleware for owner route protection
- Evaluate ConvexProvider scoping once ReviewGate architecture settles
- Rename
middleware.ts→proxy.ts(Next.js 16 convention)
Consequences
- Static pages (home, blog posts, ADRs, cool finds) become true RSC — no Convex bundle, no client hydration beyond SiteHeader
- Owner pages get proper loading states and error recovery
- Codebase consistency with
@/*imports
Risks
- SiteHeader currently uses
authClient.useSession()to show owner nav — needs reworking since it’s in root layout (outside Convex provider). Options: (a) always show public nav in root, add owner nav separately inside (owner) layout, (b) make SiteHeader accept nav items as props - ReviewGate on ADR pages uses Convex — ADR detail pages may need to stay in a group with Convex access, or ReviewGate needs to lazy-load its provider
- Cool find detail pages use
generateStaticParamsfrom filesystem — these are true RSC and should stay public
References
- Skills:
next-best-practices,next-cache-components - ADR-0106: Review pipeline (ReviewGate dependency on Convex)