Skip to main content

Link, anchor, and form action hrefs resolve to pages

ab-000029 · ai-slop-hallucinations.route-references.link-hrefs-resolve
Severity: highactive

Why it matters

Broken internal hrefs turn into visible 404s the moment a user clicks a nav item — they are the most common user-facing symptom of AI hallucination because the model names a page from its training intuition rather than your routing tree. <Link href='/dashbord'> will silently deploy, get indexed by crawlers, and then 404 every visitor who lands on it. Reference integrity at the navigation layer is load-bearing for crawlability and for bounce rate on marketing pages.

Severity rationale

High because every broken internal href is a 404 a user can trigger by clicking, and search engines penalize the domain for it.

Remediation

For each unresolved href, either fix the path to match an existing page file or create the missing page. In the Next.js App Router, the href must map to a page.tsx at the corresponding directory:

// Matches app/dashboard/page.tsx
<Link href="/dashboard">Dashboard</Link>

For dynamic routes, ensure the segment file exists — for example app/posts/[id]/page.tsx for the href /posts/123.

Detection

  • ID: ai-slop-hallucinations.route-references.link-hrefs-resolve

  • Severity: high

  • What to look for: Walk all .tsx/.jsx files for these elements: <Link href="...">, <a href="...">, <NavLink to="...">, <form action="...">. Extract the literal href/to/action value. SKIP scheme-prefixed (http://, https://, mailto:, tel:, javascript:), anchor-only (#section), and protocol-relative (//cdn.example.com). For remaining absolute paths starting with /, normalize dynamic segments and match against the project's page route tree (KNOWN_ROUTES from the analysis step). For Next.js, also accept catch-all routes ([...slug]) as matching any deeper path. Count all internal hrefs inspected, total resolved, total unresolved. Sample at most 100 unique hrefs.

  • Pass criteria: 100% of internal hrefs resolve to an existing page route. Report: "X unique internal hrefs inspected, Y resolved, 0 unresolved. Sampled X of N unique hrefs."

  • Fail criteria: At least 1 internal href does not resolve to a page route after normalization.

  • Do NOT pass when: An href like /dashboard resolves only because of a catch-all route at the project root (app/[...slug]/page.tsx) — catch-alls are valid but should be reported in detail so the user knows the resolution is loose.

  • Skip (N/A) when: Project has 0 page route files (app/, pages/, routes/, src/routes/ all empty or missing).

  • Detail on fail: "3 unresolved hrefs: <Link href='/dashbord'> in src/app/page.tsx (typo of '/dashboard'), <a href='/about/team'> in src/components/Footer.tsx (no app/about/team/page.tsx). Sampled 38 of 38 unique hrefs."

  • Remediation: Broken navigation hrefs cause visible 404s when users click them. Fix each one:

    // Bad: typo in href
    <Link href="/dashbord">Dashboard</Link>
    
    // Good: matches app/dashboard/page.tsx
    <Link href="/dashboard">Dashboard</Link>
    

    For dynamic routes, ensure the page file exists at the expected path (e.g., app/posts/[id]/page.tsx for /posts/123).

Taxons

History