/ โ† Internal Linking Fixes / Broken Internal Links
In this guide
  1. What counts as a broken internal link
  2. Why one mistake becomes hundreds of broken links
  3. Common causes and where they live
  4. Finding the exact element that creates a link
  5. Where to fix it on each platform
  6. The fix, step by step
  7. Redirect or update the link?
  8. Stopping broken links coming back
  9. Questions and answers

What counts as a broken internal link

Any link from one of your pages to another address on your own domain that does not end in a working page. That covers more than the familiar 404.

What the link reachesStatusTreat it as
A page that does not exist404 Not FoundBroken. Fix the link.
A page removed on purpose410 GoneBroken from the visitor's side. Remove or repoint the link.
A page that errors500, 502, 503Check the page first; the link may be fine and the page faulty.
A redirect to another page301, 302, 307, 308Not broken, but an avoidable hop. Point the link at the final address.
A page that says "not found" but returns 200Soft 404Broken in practice. Fix the link, and fix the page's status code.
A #section that no longer exists on the page200The page loads but the jump fails. Worth fixing on long guides.
A staging, development or old domainVariesBroken or leaking. Always replace with the live address.

Links to other websites that no longer work are a separate subject, as are pages that other sites link to on your domain. This guide stays with links you publish between your own pages, and in particular with where in your site those links are generated.

Why one mistake becomes hundreds of broken links

The Internal Link Analysis finds broken links across your crawled pages and lists which pages contain them. When you first open that list, look at two numbers side by side: the number of broken link occurrences and the number of different broken destinations.

If there are 800 occurrences but only 6 destinations, you do not have 800 problems. You have 6, each repeated by something that appears on many pages. Typical multipliers are:

Content links, the ones typed into individual paragraphs, usually produce long lists of different destinations with one or two occurrences each. They are slower to fix, so sort them by the importance of the page they sit on.

๐Ÿ’ก Sort the export by destination, then count how many source pages each destination has. Anything that appears on nearly every page is in a template or menu. Fix those first and re-crawl; the list is often a fraction of its original size afterwards.

Common causes and where they live

CauseTell-tale signWhere to fix
Page renamed or slug editedOld address still used in many linksMenus and content; add a redirect as a safety net
Page deleted without checking linksDestination returns 404 or 410Every page that linked to it
Relative path written wronglyLink like services/repair without a leading slash resolves differently on each pageTemplate or content: use root-relative /services/repair/
Trailing slash or case mismatch/About works locally but not on the serverTemplate; match the exact live address
Site moved from staging or an old domainLinks contain staging.example.co.uk or http://Database search and replace
Framework base path or locale prefixLinks missing /en-gb/ or a subfolderRouter or link component configuration
Product or post unpublishedRelated blocks or collections still link to itWidget query or manual list
Typing errorOne-off odd addressThe single paragraph

The relative path trap

A link written as href="pricing" means "pricing, relative to the current folder". On /services/ it resolves to /services/pricing; on /blog/2026/winter-tips/ it resolves to /blog/2026/winter-tips/pricing. The same template therefore produces a different broken address on every page. Use root-relative links that start with a slash, such as /pricing/, in templates and menus.

Finding the exact element that creates a link

Knowing which page contains a broken link is only half the job. You need to know which part of the page wrote it. Open one of the source pages, then open developer tools and paste this into the Console, replacing the path with the broken destination:

const bad = '/old-services/boiler-repair/';
document.querySelectorAll('a[href]').forEach(a => {
  if (a.pathname === bad) {
    console.log(a.closest('header, nav, footer, aside, main, [class]'), a);
  }
});

Each result shows the nearest landmark or classed element, which usually tells you straight away whether the link is in the header, a menu, a sidebar widget or the main content. Click the logged element to jump to it in the Elements panel.

Use your server logs too

Your access logs record the page the visitor came from in the referrer field. Filtering 404 responses where the referrer is your own domain gives you a live list of broken internal links that real people are clicking, which is a good way to prioritise. On a typical Linux server:

grep ' 404 ' access.log | grep 'example.co.uk' | awk '{print $7, $11}' | sort | uniq -c | sort -rn | head -30

Field positions vary with the log format, so adjust the column numbers if your output looks wrong.

Check the status yourself

Before editing, confirm what the destination really returns. curl -sI https://example.co.uk/old-services/boiler-repair/ shows the status line and any Location header. A page that loads in your browser may still return a 404 status, and a page that looks missing may be a temporary server error.

Where to fix it on each platform

WordPress

wp search-replace '/old-services/boiler-repair/' '/services/boiler-repair/' --dry-run
wp search-replace '/old-services/boiler-repair/' '/services/boiler-repair/'

Shopify

Static sites and frameworks

The fix, step by step

Step 1

Group the broken links by destination

Export the broken links found by the Internal Link Analysis into a spreadsheet and sort by the broken destination address. Add a column counting how many source pages link to each destination. A destination linked from nearly every page almost certainly comes from a menu, header, footer or sidebar. A destination linked from one or two pages is probably a typing error or an old link in content. This grouping turns a long, alarming list into a short set of causes.

Step 2

Find the element that creates each link

For each destination, open one source page and locate the link in developer tools. Note whether it sits in the header, navigation, footer, a widget, a reusable block or the main content. Write that location into your spreadsheet. Check whether the link is typed as a relative path without a leading slash, contains an old domain, or differs from the live address only by a trailing slash or capital letter, because those point to a template fix rather than a content fix.

Step 3

Decide what the link should point to

For each broken destination, choose the correct replacement. If the page moved, use its new address. If it was merged into another page, point to the page that now covers the subject. If the content is gone for good and nothing replaces it, remove the link and adjust the sentence rather than sending people to a vaguely related page. Record the decision beside each row so anyone applying fixes later uses the same target consistently across the site.

Step 4

Fix menus, templates and widgets

Start with the links that repeat on many pages. Correct menu items, preferably by selecting the page itself rather than typing an address, so future slug changes follow automatically. Edit header, footer and sidebar templates, synced patterns and page builder global sections. Replace relative paths with root-relative ones starting with a slash. Clear any page or CDN cache after saving, then check two or three pages to confirm the corrected link appears everywhere the template is used.

Step 5

Fix links inside page content in bulk

For content links, use a bulk method where the same old address appears on many pages: wp search-replace with a dry run on WordPress, a product export and re-import on Shopify, or a project-wide find and replace on a static site. Take a backup first. For one-off errors, edit the individual page, starting with pages that get the most visits. Check the anchor text still describes the new destination after you change where the link points.

Step 6

Update links that pass through redirects

From the same analysis, list internal links whose destination returns a 301 or 302 redirect. These still work for visitors, but each one adds a hop, and a chain of several redirects slows things further. Replace each link with the final address the redirect lands on. Keep the redirects themselves in place for bookmarks and links from other websites, but make sure your own pages link directly to the live address.

Step 7

Add a check before anything is published

Put a guard in place so the list does not refill. Before deleting or renaming a page, look up which pages link to it and update them in the same session. On static or framework sites, run a link checker such as lychee, linkinator or htmltest against the built site in your deployment pipeline so a broken internal link fails the build. Then re-run the Internal Link Analysis to confirm the count has fallen.

Redirect or update the link?

A redirect and a corrected link solve different problems, and a tidy site usually needs both.

If your redirects have built up into chains, where A redirects to B and B to C, the redirect chains guide covers flattening them. Fixing your internal links first reduces how often those chains are used at all.

โš ๏ธ Take a full backup before any database-wide search and replace. A replacement string that is too short, such as replacing /blog everywhere, can alter far more than the links you intended.

Stopping broken links coming back

Broken internal links are nearly always created by a change: a page renamed, a product removed, a menu edited, a site moved. Catching them at the moment of change is far cheaper than finding them months later.

  1. Link to pages by selection, not by typing. CMS menu items and link pickers that reference a page by its ID update when the slug changes.
  2. Check incoming links before deleting. Make it a habit to look up what links to a page before removing it, and repoint those links in the same session.
  3. Test links in the build. For static and framework sites, a link checker in continuous integration catches mistakes before they go live. For example, lychee --offline ./public checks links between local files only, without making network requests, and fails with a non-zero exit code if any are broken.
  4. Re-crawl after migrations and redesigns. These are the moments when template links change most. Run the Internal Link Analysis on staging if you can, and again on the live site immediately after launch.
  5. Keep a friendly 404 page. It will not fix links, but it gives anyone who hits a dead end a search box and links to your main sections.

Pages that have lost every internal link after a clean-up are a related but different problem; the orphan pages guide covers deciding whether to link them back in.

Questions and answers

1. Do broken internal links hurt SEO?

They do not bring a penalty, but they do cause real harm. Visitors reach dead ends and often leave. Crawlers spend requests on addresses that return nothing, which matters more on large sites. And any page you meant to support with that link receives no benefit from it. A few broken links on a large site are normal; many broken links from menus or templates suggest the site is not maintained, which is worth fixing for visitors alone.

2. Why does the report show hundreds of broken links when I only deleted one page?

Because links in menus, headers, footers, sidebars and reusable blocks appear on every page that uses them. If one of those contains a link to the deleted page, the crawler finds that broken link on every page of the site and reports each occurrence. Sort the report by destination and you will usually see only a few distinct broken addresses. Fix the menu or template once and all occurrences disappear together.

3. Is a link that goes through a redirect a broken link?

No. It still reaches a working page, so visitors are fine. It is, however, an avoidable hop that slows the journey slightly and makes your internal link data harder to read, because the address in the link is not the page that loads. Since you control your own links, update them to the final address. Keep the redirect itself in place so that bookmarks and links from other websites keep working.

4. Should I redirect every broken address instead of fixing the links?

Redirects are a safety net, not a replacement for fixing links. Add a redirect where a page has moved and outsiders may still use the old address. Then update your own links so they point directly at the new page. Where content is gone with no replacement, do not redirect to the homepage or an unrelated page; remove the internal links, and let the old address return a 404 or 410 with a helpful error page.

5. How do I fix a broken link that appears in my WordPress menu?

Open Appearance, Menus in a classic theme or the Navigation block in the Site Editor for a block theme, and find the item. If it is a custom link with a typed address, replace it with the page itself selected from the list, so future slug changes follow automatically. Save, then clear any caching plugin and CDN cache. If the link is not in the menu, check widgets, template parts, synced patterns and your page builder's global header or footer.

6. What is a safe way to replace one address across the whole site?

On WordPress, use WP-CLI's search-replace command, which handles serialised data correctly, and run it with the dry-run option first to see how many rows would change. Take a full database backup before the real run. Make the search string specific, such as the complete old path, so you do not change unintended text. On static sites, use a project-wide find and replace in your editor and review the changes in version control before deploying.

7. How can I stop broken internal links being published in future?

Link to pages by selecting them in menus and link pickers rather than typing addresses, since those references follow slug changes. Before deleting or renaming any page, check which pages link to it and update them in the same session. On static or framework sites, add a link checker to your build so any broken internal link fails the deployment. Finally, run the Internal Link Analysis after every migration, redesign or large content change.

Find every broken internal link and where it sits

The Internal Link Analysis maps every internal link across your crawled pages and identifies broken links, orphans and over-linked pages, with the pages each link sits on, so you can trace problems back to their source.

Open Internal Linking Fixes โ†’
๐Ÿ’ฌ Got a problem?
Related Guides: All Internal Linking Fixes  ·  Redirect Chains  ·  Orphan Pages  ·  Internal Links Guide  ·  Learning Hub

About aiwebpageseo

aiwebpageseo.com is a data-driven SEO and AEO (Answer Engine Optimisation) platform providing a free suite of technical SEO tools. Rather than relying on AI-theorised assumptions, the platform analyses live URL performance, delivering objective diagnostics, page speed metrics, CLS debugging, and site crawl data alongside actionable technical tutorials.