Internal Links: What They Are and How to Fix Broken Ones
What internal links are, how our report tests them with live requests, and how to repair any link that returns an error.
Free to use 19 min read Updated Oct 2026
What Are Internal Links? The Quick Answer
Quick answer: An internal link is a clickable link on one page that points to another page on the same website, written in HTML as an a element with an href. Our report requests the first 30 testable links it finds on your page and checks that each one answers with a working response.
- Pass: Every link we request answers with a success, or with a redirect that lands on a live page.
- Warning: Some of the links return an error, time out or refuse the request, while others work.
- Fail: Every link we request fails, so the page sends visitors and crawlers nowhere useful.
- Fix: Change each broken href to a live URL on your own site, or remove the link, then run the report again.
You don't need an account to run the report. One point is worth settling from the start: the row in the report is labeled In-page Links, but it tests link health, not link structure. A pass means your links respond. It does not mean your internal linking is well planned, and the rest of this page explains how to tell the difference.
What Are Internal Links on a Website?
An internal link is any link whose destination sits on the same site as the page it appears on, which our test narrows to the same exact host. If you are reading an article at example.com/blog/post/ and it links to example.com/contact/, that is an internal link. A link from the same article to another domain is an external link, and a link from someone else's site to yours is a backlink. Only the first kind is fully in your hands, which is why the rest of this page concentrates on it.
A link only counts as a link for crawlers when it is built the right way. Google follows links written as an HTML anchor element with an href attribute, the construct the WHATWG HTML Living Standard defines for hyperlinks, and it reads the visible text between the tags as the anchor text. When the link wraps an image, the alt text of that image takes the place of the visible text. Google documents this in its Search Central guidance, summarized in Google link best practices, which is the page to read if you build menus with JavaScript.
One boundary matters for the report, and it is stricter than the everyday meaning. Our test treats the exact host as the dividing line. A link from www.example.com to example.com, or to blog.example.com, is counted as external for this check, even though you own every one of them. That is a testing rule, not a verdict on your site, but it explains unexpected numbers in the external list.
Internal links vs external links vs backlinks
An internal link stays on your host and is fully under your control. An external link points from your page to another domain, so its health depends on someone else's server. A backlink is the same thing seen from the other side: a link on another site that points to yours.
The difference matters because of what you can do about each. You can fix or add internal links today with an edit and a save. You can only earn backlinks, and you can only hope that the external sites you reference keep their pages alive.
Common types of internal links
Internal links fall into two broad groups. Navigational links belong to the template and repeat on many pages: the main menu, footer links, breadcrumb links, pagination links and sitewide links in a sidebar. Contextual links sit inside the body copy, where a sentence about a topic points to a page that explains it in depth. Image links and button links work the same way, with the image or the button label acting as the anchor.
Picture a small plumbing company. Its menu links to Services, About and Contact on every page. A blog post about frozen pipes links the words "burst pipe repair" to the emergency service page, and a related posts block at the bottom adds three more. All of those are internal, and all of them can break independently.
What a crawlable internal link looks like
Here is the pattern you want to see in your page source, followed by a version that crawlers may not follow:
<a href="/guides/page-speed/">page speed guide</a>
<span onclick="location.href='/guides/page-speed/'">page speed guide</span>The first line is a real link: it has an href, it has descriptive text, and any crawler can read it. The second line only works when a script runs and a person clicks, so a crawler has nothing to follow. The href itself can be written in three forms, and all of them work as long as they resolve to a real URL: a relative URL such as page-speed/, a root relative path such as /guides/page-speed/, or a full absolute URL that includes https and the host.
How SEO Site Checker Tests Internal Links
This is a link health test, not a link counting test. We ask whether each link on your page still leads somewhere that answers, and we do not score how many links you have or where they point. That difference changes how you should read the result, so the table below shows exactly how the three outcomes are decided.
| Situation | Report result | What it means |
|---|---|---|
| Every checked link ends on HTTP 200 to 399 | Passed | All tested links respond, redirects included. |
| At least one checked link fails, but not all | Warning | Some links need attention, and the How to Fix button appears. |
| Every checked link fails | Failed | No tested link answered with a working response. |
| The page has no checkable links | Passed | There was nothing to test, so nothing failed. |
Read the count as links needing attention: The number printed beside Internal Links is the count of internal links that failed the live test, not the total on the page. A clean page can read 0.
What the check requests
A real headless Chromium browser loads your page and waits for the load event. We then read every a element that has an href from the rendered page, so links that your scripts added before the load finished are included. Links your scripts add only after the page has finished loading, or after a click, may be missing from what we read.
Some hrefs are skipped: empty ones, ones that start with #, and javascript: links. Links that begin with mailto: or tel: are collected and listed separately, but they are never requested. Everything else is resolved against the address you scanned.
Only the first 30 of those links, in page order, are tested. Internal and external links share that window, and nothing is de-duplicated. Each one gets a single HEAD request with redirects followed and a three second timeout. The MDN HEAD method reference puts it simply: the server sends the same headers it would send for a GET request, but no response body. The HTTP HEAD method itself is specified in RFC 9110 HTTP Semantics.
How the three results are decided
A link counts as healthy when its final status code, after redirects, falls between 200 and 399. A final 400 to 499, a 500 or above, a timeout, a connection error or a scheme we cannot fetch counts as failing.
If no checked link fails, the row passes. If some fail, you get a warning, and if all of them fail, the row is marked failed. A page without any checkable links passes. The red How to Fix button appears for warnings and failures, and only for those. Because internal and external links share the same 30 link window, one broken external link can turn the row amber even when every internal link is healthy.
What the number in the report really shows
The line reading "This webpage has N internal links" prints how many internal links failed, duplicates included. If your broken footer link appears on the page twice, it adds two. Don't rely on the color of the badge beside the count to judge the result. Read the number itself.
The expandable Internal Links and External Links lists contain failing URLs only. The Mail To and Telephone lists show every such link we found. The URL lists open for signed in users, and signing up costs nothing.
Why a working link can still be flagged
Because we use a HEAD request and a plain automated client, a few healthy links get flagged. The usual causes are these:
- The server dislikes HEAD. Some servers answer HEAD with 405 Method Not Allowed or 501 even though a normal GET works, so a link that opens fine in your browser still counts as failing.
- A firewall blocks automated requests. A security rule may answer with 403 Forbidden or 429 when it sees a script instead of a browser.
- The page is slow or the redirects go wrong. A target that takes longer than three seconds to answer is marked as failing, and so is a redirect chain that ends on a 404 or loops.
- The scheme is not web based. Links such as sms: or whatsapp: cannot be fetched over HTTP, so they land in the failing external list.
- The link sits past the 30th. It is not tested at all, which makes it a blind spot rather than a false alarm.
A 5xx server error, such as a 500 or 503, counts as failing and may be temporary: if the link passes on the next run, the server was simply having a bad moment. A soft 404 is the opposite problem. The page says "not found" but still answers with HTTP 200, so our row passes it while Google may treat it as an error. Our check only asks whether the link answers, so a pass is not proof that the whole site is clean.
Not tested: how many links a page has, the quality of the anchor text, orphan pages, nofollow attributes, whether robots.txt or a noindex tag blocks a target, soft 404 content, and any link after the first 30.
Why Internal Links Matter for SEO
Crawlers discover pages by following links. Google states that every page you care about should be linked from at least one other page, and a page nobody links to is an orphan that may never be found. Our write-up on how Google crawls links covers the discovery process in more detail.
Links also give context. The anchor text and the words around a link tell people and crawlers what the target page is about, which is why a link labeled "frozen pipe repair" says more than one labeled "this page". Links from strong pages can also help pass importance to other pages on your site, an idea often called link equity. Be careful with the details, though: Google publishes no formula for how much, and no ideal link count, so anyone quoting exact numbers is guessing.
The human side is just as practical. A working link keeps a visitor moving, while a dead link ends the visit and makes a site look neglected. Broken links also waste crawl effort, because a crawler spends a request to learn nothing, which matters most on very large sites where crawl budget is tight. Search Console help draws a useful line here: the 404 errors worth fixing are the ones you link to yourself, or list in a sitemap. That is exactly the kind of error the In-page Links row is built to surface.
Internal links also express your site architecture. Picture a pillar page on page speed that links to three narrower posts, on image compression, caching and fonts, and each of those posts links back to it. That shape shows people and crawlers which page is the main one on the subject. Don't expect any single link to move a ranking on its own.
How to Check Internal Links on Your Website
The aim is to find dead links before a visitor does, because link rot is slow and quiet: pages get renamed and products are retired. These steps are quick for a single page and slower for a whole site.
- Run the report. Scan the page and find the In-page Links row. The icon is green when every checked link responds, amber when some fail and red when all of them do.
- Open the failing list. Expand Internal Links and External Links, because a broken external link can turn the row amber on its own. Sign in, which costs nothing, if you want to see the URLs, and copy every failing address.
- Confirm each one yourself. Open the address in a private window, then run curl against it and read the status on the first line. Add the -L flag to follow redirects the way the report does.
- Cross check in Google Search Console. The Page indexing report lists the Not found (404) URLs Google has met, and the Links report shows which of your pages receive the most internal links. Its tables are limited to 1,000 rows.
- Cover what the report skips. Links beyond the 30 link window described earlier are never tested, so check header, footer and sidebar templates by hand or with a site crawler. To find orphan pages, compare the URLs in your XML sitemap with the URLs a crawler reaches by following links from the home page: any sitemap URL the crawl never reaches has no internal link pointing at it. The Meta Tag Analyzer counts the unique full URLs on your own domain written in a page source. Relative links are not counted, while image, script and style URLs are, so use it as a rough size check only.
Here is what a manual check looks like. The three examples below are alternatives, one per outcome, and you would see only one of them for any given address. The -I flag makes curl send a HEAD request, which is the same method the report uses, so it usually reproduces the result you saw in the row.
# A working link
curl -I https://example.com/working-page/
HTTP/2 200
# A redirected link
curl -I https://example.com/old-guide/
HTTP/2 301
location: https://example.com/new-guide/
# A broken link
curl -I https://example.com/deleted-page/
HTTP/2 404A 200 means the link works. A 301 with a location header means it works only after a hop, which our report accepts but you should still tidy. A 404 error means the link is broken, and it belongs on your fix list.
How to Fix Broken Internal Links
Work through your failing URLs one at a time and ask the same question of each: was the page moved, replaced by a close equivalent, deleted with nothing to replace it, or simply mistyped? The answer decides the fix.
Update, redirect or remove the link
If the page moved, edit the href to its new address. If the address was mistyped, correct the typo and nothing else is needed. If a better page replaced the old one, point the link at the replacement and add a 301 redirect from the old URL for anyone arriving from outside your site.
When the page is gone and nothing equivalent exists, remove the link or point to the closest useful live page. Let the old URL return a helpful 404, ideally with a clear custom 404 page that offers a way back into the site.
A before and after pair makes the change clear. The old anchor points at a deleted path, and the new one points at the page that replaced it:
<!-- before: the path no longer exists -->
<a href="/old-guide/">page speed guide</a>
<!-- after: the final live URL -->
<a href="/guides/page-speed/">page speed guide</a>A dead external link is fixed the same way: update the href to the page's new address, or remove the link if nothing equivalent exists. If other sites or old emails still use the old address, add a redirect as well. On the Apache HTTP Server, one line in the .htaccess file does it. On Nginx, add a location block inside the server block, test the configuration and reload the service. Use one of the two snippets below, not both, because each belongs to a different server:
# Apache, in the .htaccess file in your site root
Redirect 301 /old-guide/ /guides/page-speed/
# Nginx, inside the server block
location = /old-guide/ { return 301 /guides/page-speed/; }Notice the difference in matching. Apache's Redirect works on a prefix, so a request for /old-guide/anything is also sent to /guides/page-speed/anything, while the Nginx line with an equals sign matches that one path only. Whichever redirect you add, still edit the href in your own pages, because every internal link that goes through a redirect costs an extra request.
Fix at the source: A broken link in a menu, footer or template is fixed once and repairs every page that uses it. It also brings the number in the report down, often by a lot.
Fix the host, protocol and trailing slash
Replace hard coded staging, localhost or http links with root relative paths or https links on your canonical host, and the same applies after a domain move.
Match the slash style your server really uses. If your site serves /services/ and redirects /services to it, link to the version with the slash, so the link doesn't depend on a redirect to work.
Fix links that work but get flagged
The check sends a default script user agent and a HEAD request, and some servers and firewalls refuse both, so here is a quick way to tell a false alarm from a real fault. If the page opens fine in a browser, send it a normal GET request and compare the answer with the HEAD result:
curl -s -o /dev/null -w '%{http_code}' https://example.com/page/This prints only the status code of a GET request. If it prints 200 while curl -I, which is a HEAD request, returned 405 or 403, the link is fine for people and only the automated check was refused. A 403 can also be a genuine access restriction, so confirm that the page opens for a normal visitor before you decide.
Recheck your fixes
- Test each address. Run
curl -ILagainst it and expect HTTP 200, or a single 301 that ends on a 200. - Run the report again. Scan the page once more and confirm that the In-page Links row turns green.
How to Add Internal Links in WordPress, Shopify and Wix
Every platform has a link picker, and using it is safer than pasting a typed address because the picker inserts the current permalink.
In the WordPress block editor, select the words you want to turn into a link, then press the link icon or Ctrl or Cmd plus K. Start typing the post or page title into the search box that appears in the link popover, and pick the match from the results, which inserts its current permalink. The classic editor and most page builders follow the same select, link and confirm pattern.
In Shopify, use the link button in the rich text editor. Where the dialog offers them, choose a Page, Collection, Product or Blog post instead of pasting a URL. Menus live in the admin under Content, then Menus, where you can edit each menu item.
In Wix, select the text, click the link icon and choose Page as the link type, so the link points at the page itself and not at a typed address. Squarespace and Webflow work much the same way. On a plain HTML site or a static site generator, use root relative paths such as /guides/page-speed/ and run a link check before each deploy.
One warning applies to all of them: renaming a slug breaks every old link unless a 301 and the edited links are both in place. Rename /services/ to /plumbing-services/, for example, and every menu item and post that still points at /services/ returns a 404 until you redirect the old address and edit those links.
Internal Link Best Practices
These habits come from Google's documentation or from long practice. Where something is a rule of thumb and not a Google rule, the item says so.
- Write descriptive anchor text. The Lighthouse link text audit fails vague phrases such as "click here" and "learn more". That is a Lighthouse best practice, not a confirmed ranking factor, but Google's own guidance also asks for descriptive, concise link text. WCAG's link purpose criterion also expects a link's purpose to be clear, from its text or its surrounding context, which matters for screen reader users.
- Use plain anchor elements. Build links as anchor elements (a tags) with an href, not as onclick handlers or router-only links, so that crawlers can follow them.
- Link from relevant body copy. Make sure no important page is an orphan, and keep an XML sitemap as a backup for hard to reach pages (our XML Sitemap Generator builds one), never as a replacement for real links.
- Keep key pages close to the home page. As a rule of thumb, not a Google rule, aim for about three clicks from the home page. The article on flat vs deep site structure goes deeper on click depth.
- Don't chase a link count. Google says there is no fixed number. Keep links proportional to the content, and treat roughly 100 URLs per page as a legacy sanity limit, not a rule.
- Leave nofollow off your own links. In normal cases there is no reason to add it internally, and the page on nofollow links explains the cases that are different. Open internal links in the same tab by default.
- Mark up your breadcrumbs. Breadcrumb links are among the most useful navigational links, and BreadcrumbList schema lets search engines read the same trail. It supports the visible links and doesn't replace them.
- Link to final URLs. Point each link at its final URL, with no redirect in between, on your canonical host and https, and run the report again after migrations, slug changes or deleted content.
Common Internal Linking Mistakes
The most common cause of a failing link is plain neglect. Someone deletes or renames a page and forgets that a dozen other pages still point at it. The links keep rendering, so nothing looks wrong until a visitor clicks, or until a report like ours requests them.
Launch leftovers come second. Staging, localhost or http URLs hard coded into a template survive for years, and every page that uses the template inherits the problem. An http link on an https site sends visitors through a needless 301 redirect before they reach the page. Related to that are internal redirect chains: a link points at an old URL that redirects to another old URL, and each hop adds a request and a chance of failure. Clean, stable addresses help here, which is why our guide to SEO friendly URLs is worth reading before you rename anything.
Anchor text goes wrong in two ways. Generic phrases tell nobody anything, and identical text used for different destinations confuses people and crawlers about which page a phrase refers to. Navigation built only on JavaScript click handlers, with no href, creates links that crawlers may never follow.
Finally, a huge menu at the top of every page deserves a warning. Given the 30 link window described earlier, a long menu can fill the whole window before any body link is reached, and the links that matter most to a reader go unchecked.
How to Fix
The short version, the same steps you see when you click How to Fix in your report.
Why this fails: At least one link on this page did not return a working response when SEO Site Checker requested it. A link that errors, times out or refuses the request sends visitors and crawlers to a dead end.
How to fix it:
- Expand Internal Links and External Links in the report row and copy each failing URL.
- Open each URL in a browser, then run
curl -ILon it to read the real final status code. - Edit the href to the new address if the page moved. If it was replaced, add a 301 redirect and still edit the href. If it is gone, remove the link or point to a live page.
- Allow HEAD requests and automated checks on your server or firewall if a link loads fine in your browser but was flagged, because 405, 403 and 429 are the usual causes.
- Fix links in menus, footers and templates once, at the source, so every page is repaired together.
<!-- before -->
<a href="/old-guide/">page speed guide</a>
<!-- after -->
<a href="/guides/page-speed/">page speed guide</a># Apache, in .htaccess
Redirect 301 /old-guide/ /guides/page-speed/
# Nginx, inside the server block
location = /old-guide/ { return 301 /guides/page-speed/; }Use only the snippet that matches your server. Apache's Redirect matches by prefix, so /old-guide/anything also goes to /guides/page-speed/anything.
- WordPress: select the text, press Ctrl or Cmd plus K and pick the page from the list.
- Shopify and Wix: use the link picker and choose the page, product or collection.
- Apache: add the Redirect line to the .htaccess file in your site root, no restart needed.
- Nginx: add the location block inside your server block, run
nginx -t, then reload Nginx.
Re-test: run curl -IL on each URL and expect HTTP 200, or a single 301 that ends on a 200. Then Re-run the SEO report and confirm the In-page Links row is green.
Frequently Asked Questions
What are internal links in SEO?
How many internal links should a page have?
Do internal links help SEO?
Should internal links open in a new tab?
How do I add internal links in WordPress?
What is the difference between internal links and backlinks?
How do I find and fix broken internal links?
Do redirects on internal links hurt SEO?
See how your site scores right now
Paste your address into the free report, then use the How to Fix button on anything that needs work.
Free to use. Results in under a minute for most sites.