Abid Ali

Technical SEO

How to Find and Fix Broken Internal Links

By Abid Ali · Published · Updated

Crawl the site, list internal URLs that 404, fix the href or add a redirect, and check the canonical so repaired links point at the URL you want indexed.

Cover illustration: How to Find and Fix Broken Internal Links
Cover illustration.

Broken internal links are hrefs on your own site that do not reach a working page. A navigation item, a footer link, a "related" card, a canonical, or a URL in the sitemap can all be the source. Visitors hit a dead end. Crawlers spend time on URLs you did not mean to offer.

An internal link audit is a list: source page, href, status code. Fix the list. Then crawl again.

Find them with a crawl, not by clicking

Clicking the nav finds the obvious ones. It misses a link inside a blog post or a generated card. Crawl the site the way a robot does.

  • Start from the home page and follow only your host.
  • Record every internal href and the status of the response.
  • Treat 404 and 410 as broken. Treat 500 as a defect, not as a link to tidy up with a redirect.
  • Include URLs from the sitemap. A sitemap URL that 404s is a broken promise, even if nothing in the HTML points at it.
  • Include the canonical link and the og:url. They are URLs too.

A desktop crawler (Screaming Frog is the usual one) or a small script that parses href from your routes will do. For an App Router site, also search the repo for href= and for template strings that build paths. A renamed slug often survives in one component.

Query strings count. /work and /work?type=concepts are different requests. If the interface links to the filtered URL, that URL has to render. If the filtered URL's canonical points at /work, say that on purpose: the filter is a view, and the indexed URL is the one in the canonical. Do not link to a filter and also tell crawlers to ignore it unless that consolidation is the decision. Canonical internal links should match the decision. Either the filtered URL is real and self-canonical, or internal links point at the canonical URL.

Fix the href or redirect the old path

Choose one:

  • The page was renamed. Update every internal href to the new path. Add a redirect from the old path so bookmarks and external sites still land. In Next.js that redirect can live in next.config or in a route handler. Prefer a 301 when the move is permanent.
  • The link was a typo. Fix the href. No redirect, because the wrong URL was never a public address. Do add a redirect if the typo was published and crawled.
  • The page was removed and nothing replaced it. Delete the internal links. A 404 is the honest status. 404 redirects that send every missing URL to the home page make the home page look like the answer to unrelated requests. Search engines treat that as a soft 404.

After redirects, update the sitemap so it lists the new URL only. A sitemap that still advertises the old path keeps the dead URL in circulation.

Check the pages that generate links

Hand-written nav is easy to read. Generated links are where renames hide.

  • Cards built from a slug field (/work/${slug}, /blogs/${slug}). If the record's slug changes, the href changes, which is what you want. If a slug is edited in the URL but not in the record, the card 404s.
  • "Next article" links that assume an order. When a post is removed, the neighbor should not point at it.
  • Concept or case-study links that use an absolute production host. They still need to match a route that exists on that host.

Meme Tap's shareable sound pages are the same shape. Each sound has a URL. A category page that links to a sound slug that was removed is a broken internal link, even though the category page itself returns 200.

Close the loop

Crawl again after the fix. The first report should shrink to zero internal 404s. Then spot-check:

  • The nav, footer, and one deep page.
  • One redirected URL. It should land on the replacement in a single hop, not a chain.
  • The canonical on that replacement. It should be the final URL, not the old one.

Broken internal links come back when a slug changes in content and the menu is a separate list. One source for routes (the content records, or a single navigation array) keeps the hrefs and the pages in the same edit.

Questions

Are broken external links the same issue?
They disappoint a reader, but an internal link audit is about your own URLs. You can fix those hrefs or redirect them. An external 404 is someone else's page.
Should every 404 become a redirect?
Redirect when the content moved and there is a clear replacement. If nothing replaced it, let it 404 and remove the internal links. A redirect to the home page hides the mistake and sends people to the wrong place.
Do query-string URLs count as separate links?
Yes. /work and /work?type=concepts are different URLs. If both are linked, both must return a page, and each should declare the canonical URL you want indexed.

Next in the reading path: A Developer's Guide to Core Web Vitals

Let's discuss your next project.

Tell me what you are building, who it is for and what a good result looks like. I'll reply with questions, a suggested approach and the next steps.