Internal linking at scale, how to structure links on large sites
On a large site, templates decide most internal links. Navigation, breadcrumbs, category listings, pagination and related-content modules create far more links than any editor writes, so the fixes that matter happen there: make every page you care about reachable through a crawlable link, decide which pages the templates should favor, and use links in body copy to say what pages are about.
Editorial links still matter, but on a site with tens of thousands of URLs they sit on top of a structure the templates already built. That makes internal linking a product decision, with owners and requirements.
What internal links do
Google's guide to crawlable links describes two jobs: links help Google find new pages to crawl, and they are a signal when it determines the relevance of pages. The anchor text, and the words around it, tell people and Google what the destination covers. The same guide sets a modest baseline: every page you care about should have a link from at least one other page on your site.
That only counts if the link is crawlable. Google can generally only follow links that are a elements with an href attribute; links that exist only as click handlers on buttons or spans aren't reliably extracted. If your navigation or modules render in the browser, check the rendered HTML, as the guide to JavaScript SEO describes.
XML sitemaps help without replacing links. Google's sitemaps overview says a properly linked site is usually discoverable, and that sitemaps help large sites because it is harder there to link every page from at least one other. A sitemap gets a URL discovered but says nothing about how the page relates to the rest of the site; the post on XML sitemaps that help covers what belongs in them.
Map the link layers your templates create
Before changing anything, list the layers that generate links and what each one is good for. A page's internal links are mostly the sum of the layers it appears in.
| Layer | Typical links | Good for | Weak at | Usual owner |
|---|---|---|---|---|
| Global navigation | Top categories and hubs | Discovery, keeping hubs shallow | Saying anything specific | Product and design |
| Footer | Policies, company pages, category lists | Reaching utility pages | Relevance, long lists blur | Design or marketing |
| Breadcrumbs | Parent categories, hub | Linking up the hierarchy with clear anchors | Sideways links | Engineering |
| Category listings | Items in the category | Discovering items | Items past page one get weak paths | Merchandising and engineering |
| Pagination | Page 2, 3 and on | Reaching deep items | Distance from the start | Engineering |
| Facets and filters | Filtered variants | Refining a list | Can create endless crawlable URLs | Engineering |
| Related-content modules | A few "related" items | Sideways discovery at scale | Shallow matching, links that keep changing | Engineering or data |
| Links in body copy | Hand-picked links | Relevance and precise anchors | Doesn't scale alone | Content team |
A product that appears only on page 9 of one category depends entirely on the pagination layer. A guide that only the related-content module links to gets whatever that module's algorithm picks this week.
Hubs, clusters and the direction of links
The structure that holds up at scale is a hub page for each broad topic, cluster pages for the subtopics under it, and supporting articles that feed both. The direction of each link is the part teams get wrong.
/running-shoes/ hub: links down to every cluster page
/running-shoes/trail/ cluster: links up to the hub
/running-shoes/wide-fit/ cluster: links up to the hub
/running-shoes/carbon-plate/ cluster: links up to the hub
/guides/choosing-trail-shoes/ article: links to the hub and to /trail/
/guides/running-with-wide-feet/ article: links to the hub and to /wide-fit/The hub links to every cluster page. Cluster pages link back to the hub through breadcrumbs and in-body links with descriptive anchors. Siblings link sideways when a reader of one would want the other, not by default. Supporting articles link to the commercial page they support.
A common SEO heuristic says important pages should sit within three or four clicks of the home page. Google doesn't set a number; its documented requirement is the single link from another page. Depth is more useful as a symptom: pages buried behind pagination and date archives are usually the ones no other layer links to, and the fix is a layer that reaches them, such as hub links or featured items, rather than flattening the whole site.
Decide where the links should point
Internal links work like a budget that is easy to spend by accident. To plan it, sort pages into donors, which have attention to pass on, and acceptors, which need it.
| Page type | Usual role | Action |
|---|---|---|
| Home page | Donor | Link to the main hubs, not to everything |
| Guides and articles with external links | Donor | Add in-body links to the category or product each one supports |
| Commercial hubs and categories | Acceptor | Make sure navigation, breadcrumbs and relevant articles link to them |
| New products or pages | Acceptor | Feature them in listings and hubs until they settle |
| Thin tag and archive pages | Neither | Consolidate, or keep them out of the main link paths |
| Sorted and filtered views | Neither | Few links, with canonicals to the main version |
Watch for the inverted pattern: articles attract external links and link mostly to each other through related-content modules, while the category pages that earn revenue get links only from the main navigation.
A hypothetical repointing project
Say an outdoor retailer has 120 buying guides and a category for waterproof trail running shoes. A related-articles module links the guides to each other. Fifteen of them discuss trail shoes, but only two link to the category, both with "click here" as the anchor. The category's other internal links come from the main navigation.
Pull the guides that discuss the category's topic, through site search or a CMS query.
In each relevant guide, add one link to the category inside a sentence where it helps the reader, with a descriptive anchor that fits that sentence, such as "waterproof trail running shoes" in one and "trail shoes with a waterproof membrane" in another.
Replace both "click here" anchors.
Check that trail shoe product pages carry a breadcrumb to the category and that the running shoes hub links to it.
Log the date and the URLs changed, then compare how often Googlebot requests the category, and how it performs in search, with the weeks before the change.
Anchor text on templates and in copy
Google's link guidance is specific. Good anchor text is descriptive, reasonably concise and relevant to both the page it sits on and the page it points to. Generic text such as "click here" or "read more" gives no context. Cramming keywords into anchors is out, and Google points out that keyword stuffing violates its spam policies. The words before and after a link matter too, and links chained next to each other lose that context. When a link wraps an image, Google uses the image's alt text as the anchor.
| Anchor | Problem | Better |
|---|---|---|
| click here | Says nothing about the destination | waterproof hiking boots |
| best hiking boots cheap hiking boots for sale | Keyword stuffing | hiking boots for wide feet |
| read more, on 20 cards in a row | Twenty identical generic anchors | The article title as the link |
| this guide, pointing to a sizing page | Vague | how to measure your feet for boots |
| An icon with no text or alt | Nothing for Google to read | Visible text, or an icon with descriptive alt text |
Navigation labels are short by necessity, which is fine as long as breadcrumbs and in-body links carry the descriptive anchors. On related-content cards, make the destination title the link text. Varying anchors to the same page is a readability choice; Google hasn't said repeated internal anchors are a problem in themselves. One pattern does work as a diagnostic: when two different pages keep receiving the same anchor text, the pages probably overlap, which is a content question before it is a linking one.
Find orphans and buried pages
An orphan is a page with no internal links pointing at it. It can sit in the sitemap and even be indexed, yet nothing on the site leads to it. Finding orphans means comparing two lists:
Build the list of URLs that should be indexable, from XML sitemaps, a CMS or database export, and analytics landing pages.
Crawl from the home page following links only, not sitemaps, with JavaScript rendering if your links depend on it.
Compare the two lists in both directions.
# known.txt: every URL that should exist and be indexable
# crawled.txt: every URL the link-only crawl reached
sort -u known.txt > known.sorted
sort -u crawled.txt > crawled.sorted
comm -23 known.sorted crawled.sorted > orphans.txt # exist, no link path
comm -13 known.sorted crawled.sorted > unlisted.txt # linked, but not in the inventoryEach orphan needs a decision: link it from the right layer, merge it into a stronger page, or retire it with a 404, 410 or a redirect to a real replacement. The unlisted file usually holds parameter variants, old URLs still linked from somewhere, or pages missing from the sitemap, and each needs either a link fix or a place in the inventory.
From the same crawl, review click depth by template rather than by URL, so structural gaps stand out. Then check the crawler's side. Server logs show whether verified Googlebot requests your priority pages, and how often compared with filter and parameter URLs; the log file analysis primer explains how to segment requests that way. A priority page that Googlebot visits far less often than junk URLs is a linking problem, a crawl waste problem, or both.
Pagination, facets and JavaScript links
Google's pagination guidance asks for links from each page to the next using a elements with href attributes, and warns that Google's crawlers don't click buttons and generally don't trigger JavaScript functions. A "load more" button or infinite scroll therefore needs real paginated URLs behind it. The same guidance says to give each paginated page its own canonical URL instead of pointing them all at page one, which the post on canonical tags covers in more detail.
To shorten the path to deep items, link category pages directly to their most important products whatever their position in the sort order, and link newer articles to older evergreen ones. Filters need the opposite treatment: limit which combinations are linked at all, because every linked filter combination is another URL to crawl. The post on taming faceted navigation goes through those controls.
Related-link widgets, automated or stored
Every large site ends up automating some links. The choice that matters is between links recalculated constantly and links computed, reviewed and stored.
| Approach | How links are chosen | Stability | Good for | Main risk |
|---|---|---|---|---|
| Live widget | Calculated on each request from tags, co-views or popularity | Changes often | Covering a huge long tail cheaply | Churn, and links pile onto already-popular pages |
| Stored link table | Calculated in batches, reviewed, then served from a table | Stable between updates | Large catalogs that need predictable links | Goes stale if never recalculated |
| Hand-picked links | Chosen by someone who knows both pages | Stable | Hubs and priority pages | Doesn't scale alone |
A live widget can show different neighbors on every crawl, so no page builds a consistent set of links, and popularity-based matching keeps feeding the pages that need help least. A stored table fixes both: recalculate on a schedule and serve the same links until the next run. Either way, cap the number of links, exclude targets that redirect, carry noindex or are filtered views, and reserve some slots for pages with few internal links. Then hand-write links on the pages that matter most.
Make linking a template requirement
Template links change only when someone files a ticket, so write linking rules the way engineering expects requirements. For each module, specify:
which page types it appears on, and which page types it may link to
that targets must be indexable canonical URLs, never tracking or sorted variants, in line with Google's advice in its canonical guide to link to the canonical URL rather than a duplicate
how targets are chosen, how many links it outputs, and where the anchor text comes from
that links are plain a elements with href attributes in the server-rendered HTML
how to test it: a crawl of staging that confirms the expected links appear on a sample of pages
Redesigns are where linking breaks most visibly. Before a new menu, footer or module ships, check which pages lose their only links. The site migration checklist includes that check in its staging parity crawl.
Audit after every template release
Run these checks on a schedule, and again after any release that touches navigation, listings or modules, because one template change can remove thousands of links at once:
inlink counts per indexable URL, sorted from fewest to most
click depth for priority templates
anchors pointing at priority pages, looking for generic, empty or misleading text
internal links that hit redirects or 404s, repointed to the final URL
nofollow on links between your own pages, which only withholds signals from your own content
the orphan and unlisted comparison from the section above
A useful first move is to take your three most important commercial templates, list every layer that links to them, and check whether your strongest articles link to them with descriptive anchors. If they don't, that is the first change to ship.