Skip to content

How Do I Find Buttons and Links in My App That Go Nowhere Before Users Do?

6 min read

To find every dead button and broken link before your users do, you walk the whole app and click everything, one screen at a time, while watching the browser console and the address bar. There is no shortcut that beats actually clicking, but there is a fast, systematic way to do it so you miss nothing. The short answer: make a list of every screen, click every clickable thing on each, and note anything that does nothing or lands on a broken page.

Why this happens

When you ask an agent to "add a settings menu" or "put a share button here," it adds the button. Whether that button is wired to anything is a separate step, and if you didn't ask for the destination, you often didn't get it. So you end up with a beautiful button that has no onClick, or a link pointing at /dashboard when the real route is /app/dashboard, or a "Coming soon" feature that was never finished.

The agent built exactly what you asked for. You asked for a button. You did not say "and make sure it goes somewhere," so nobody checked. In the demo it looked complete, because you never clicked it.

How to check

  1. List your screens. Write down every page and every important state: logged out, logged in, empty account, account with data, error states. This is your map.
  2. Open the browser console (right-click, Inspect, Console tab) and keep it visible. A dead button often logs nothing, but a broken link or failed action frequently throws a red error here.
  3. Click everything on each screen. Every button, every link, every menu item, every icon. Watch three things each time: did the page change, did the address bar update to a real page, did the console throw an error.
  4. Catch the two failure shapes. A dead button does nothing at all, no navigation, no console entry, no visual change. A broken link navigates but lands on a crash page, a blank screen, or a 404.

To catch broken internal links in bulk, you can also crawl the site. With the app running locally, a link checker will follow every link and report the dead ones:

npx linkinator http://localhost:3000 --recurse

This finds links that point at pages that don't exist. It will not catch a dead button that has no link at all, so you still need the manual click pass.

The fix

  1. Dead button with no destination yet. Decide: finish it or hide it. If the feature isn't ready for beta, remove the button or disable it with a clear label rather than leaving it clickable and silent.
  2. Button that should act but doesn't. It is missing its handler. Ask your agent to wire the specific button to the specific action, and then click it yourself to confirm it works, do not take "done" on trust.
  3. Link to a page that doesn't exist. Either the route is wrong or the page was never built. Fix the path to match the real route, or build the page.
  4. Re-run the crawl and the click pass after each batch of fixes. Fixing one route sometimes reveals another link that was pointing at the old one.

The trap to avoid

Do not add a global catch-all that quietly redirects every unknown link back to the home page. It makes the crawler report zero broken links while your users still click "Billing" and mysteriously end up on the landing page, confused. A missing page should be fixed or should show an honest not-found page, not be swept under a redirect.

Where this fits

Dead buttons and links that go nowhere are the fastest way to make a working app feel unfinished, and they are invisible in a demo because the person demoing never clicks the broken parts. This is exactly what the free Readiness Report walks for you: your own agent clicks through the app and lists what leads nowhere, alongside related gaps like what a page should show when a request fails and leftover demo data. If you would rather have the dead ends fixed and handed back in order, that is what the Finishing Pass is for.