Your site has just been rebuilt, or simply reorganised, and Search Console shows a list of 404 errors that keeps growing. Or a customer tells you that a link on your services page leads nowhere. Broken internal links nearly always appear the same way: an address changes, and the links that pointed to it stay where they were.
When I reorganised this site, I left old addresses behind myself, and I redirected them one by one. On this blog, my publishing pipeline also blocks dead links before anything goes live. Here is how I find them, how I decide what to do with each one, and what I put in place so they do not come back.
01What a broken internal link really costs
First, a fear worth deflating. Google says it plainly on its blog: 404s are a normal part of the web, and the fact that some addresses no longer exist does not affect how the rest of your site performs in search results. A long list of 404s in Search Console is not a penalty.
The cost lies elsewhere. An internal link does two jobs: it guides the visitor to the next logical thing to read, and it lets Google discover your pages. In his video on internal linking, Martin Splitt from the Google Search Central team puts it simply: Googlebot uses internal links to find the pages on a site and to understand how they relate to each other. A broken link interrupts both.
In practice, you get a visitor who was looking for your offer and hits a dead end, and an important page that no longer receives the link that made it visible. Google's documentation says that every page you care about should have a link from at least one other page on your site. When that single link breaks, the page becomes an orphan and nobody notices.
02Finding broken links without losing a week
I audit internal linking in three passes, from the quickest to the most thorough.
Start from what Google has seen
The page indexing report in Search Console has a "Not found (404)" reason. Google lists the addresses that returned a 404 there, often found through a link from another page. It is a good starting point, with one limit: the report shows what Google came across, not always where the link lives. Some of those addresses come from other sites or old links you do not control.
Crawl the site like a bot
A crawler walks every page from the homepage, follows each link and records its response code. The first thing I look at is the "source page" column: it tells you where the broken link sits, and so where to fix it. Then I filter on 404 and 410 codes, and on redirect chains. Google follows up to 10 redirect hops, but every hop slows the visitor down and there is no good reason to stack them.
Check the pages that matter, by hand
Finally, I take the ten pages that carry the business (home, services, contact, the articles that bring people in) and click every link on them, in a private window. It is slow, but it is the only pass that catches a link to a page that returns a 200 yet displays an error message, what is called a "soft 404".
For a broader audit before a redesign, I have described my method in the technical audit before a redesign.
03Fix, redirect or leave a 404
For each broken link I ask a single question: does the page the link was aiming for still exist somewhere?
- It exists at another address: I fix the link on the source page so it points straight at the right address. This is the fix I prefer, because it removes the problem instead of working around it.
- It exists elsewhere, and other links I do not control still point to the old address: I add a permanent redirect. Google recommends a server-side 301 or 308 redirect, which it treats as a strong signal; a JavaScript redirect is a last resort.
- It no longer exists and nothing replaces it: I remove the link and let the old address return a proper 404 or 410.
The third case is the one people get wrong most often. The temptation is to redirect every dead address to the homepage. Google advises against it: redirecting unknown addresses to the homepage can hurt how your site is understood and indexed, because the visitor lands on a page that does not answer what they were looking for. A clean 404, with a helpful message and a link to search or the menu, is better.
04What I did when I reorganised this site
I built this site in Next.js, then reorganised it. Each change of structure left addresses behind, and I declared them in the site's configuration file.
The Next.js documentation lets you write these redirects with a source, a destination and a permanent setting; a permanent redirect there returns a 308 code. Path patterns let you redirect a whole section in one go.
Here is what my list contains:
- the "Projects" section became "Missions", and all its old addresses lead to the portfolio;
- the detail page for each mission was removed, and those addresses redirect to the missions portfolio;
- the old "about" page leads to the Services page;
- the addresses of the previous site, built on Webflow and still known to Google, are mapped one by one;
- an address without a language leads to the French version.
I also made a compromise I would not repeat as it stands. The articles from the old blog were not carried over, and their addresses all redirect to the blog index. That is better than a dead end for the visitor, but it is exactly the case Google describes: a redirect to a page that does not replace the original. For an old article that still had traffic, the right answer would have been to rewrite it at the same address, or to leave a proper 404.
If you are planning a migration like this one, I have set out the method in migrating a site to Next.js and Sanity.
05Stopping new dead links from going live
Fixing things once is not enough. Broken links come back with every new article and every renamed page. On this blog, I therefore put the check before publishing, not after.
My content machine works with a brief, then a "gate" that rereads the article before publishing it. Three checks concern links:
- every internal link is compared with the list of pages that really exist (fixed pages and published articles, read from the CMS); a link to a missing page blocks publication;
- in network mode, the tool opens every external link; a 404 or 410 response blocks too, and the article does not go out until the source is replaced;
- after publishing, I check the public page, in French and in English, with its internal links returning a 200.
The reason is simple: a language model happily invents plausible addresses, and so does a person in a hurry. Once written, the check costs nothing. I cover this more broadly in my acceptance testing and go-live checklist, where checking links is one of the boxes to tick.
Where this method falls short
My check verifies links at the moment I write. It cannot see an article published six months ago that points to a page I deleted yesterday. For that case you still need a regular crawl of the site, or at the very least a monthly look at the indexing report. The safest option is to build it into an SEO report that goes out by itself every month, rather than relying on someone's memory.
And on a site with several thousand pages generated by a CMS, a hand-written list of redirects quickly becomes unmanageable. You then need pattern-based rules, and tests that replay them.
06Where to start this week
If you only do one thing, open the indexing report in Search Console and export the 404 addresses. For each one, find the page on your site that links to it, and apply the rule: fix the link, redirect with a 301 if the page has moved, or leave the 404 if it no longer exists. Allow about two weeks for Google to validate the fix.
Then keep a file of every address you change, at the moment you change it. That file is what will spare you the next list.
If your site is coming out of a redesign and you would like an outside view of its links and redirects, my services page explains how I work. Happy to talk it through.
