Auditing a live Next.js app: what broke and why
A real bug audit on AI ToolsHQ, a live AI-tools directory — the specific mistakes found and what actually fixed them.
Three real bugs, not hypotheticals
This wasn't a code review exercise — these were actual defects found in a live site (AI ToolsHQ, an AI tools directory). Three separate categories of bug showed up in the same audit pass.
Wrong import paths, silently broken components
Several components were importing from incorrect Radix UI paths — the kind of mistake that doesn't always throw a build error if a similarly-named export exists elsewhere, but produces a component that doesn't behave as expected at runtime.
The Next.js 15 async params trap
Next.js 15 made dynamic route params asynchronous — `params` became a Promise instead of a plain object, matching the same pattern used in this site's own `/blog/[slug]` route. Code written against the older synchronous assumption doesn't just fail loudly; in some cases it silently returns undefined values instead of crashing, which is worse, because the page renders without erroring but shows the wrong (or missing) content.
Client SDK in the wrong place
The Firebase client SDK was being called directly inside server components — which doesn't work, since client SDKs assume a browser environment. The fix was converting the affected components to `"use client"` and moving the data fetching into `useEffect` with `useParams`, keeping the client-only code actually running on the client.