← All posts

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.

LayerTypical linksGood forWeak atUsual owner
Global navigationTop categories and hubsDiscovery, keeping hubs shallowSaying anything specificProduct and design
FooterPolicies, company pages, category listsReaching utility pagesRelevance, long lists blurDesign or marketing
BreadcrumbsParent categories, hubLinking up the hierarchy with clear anchorsSideways linksEngineering
Category listingsItems in the categoryDiscovering itemsItems past page one get weak pathsMerchandising and engineering
PaginationPage 2, 3 and onReaching deep itemsDistance from the startEngineering
Facets and filtersFiltered variantsRefining a listCan create endless crawlable URLsEngineering
Related-content modulesA few "related" itemsSideways discovery at scaleShallow matching, links that keep changingEngineering or data
Links in body copyHand-picked linksRelevance and precise anchorsDoesn't scale aloneContent 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 typeUsual roleAction
Home pageDonorLink to the main hubs, not to everything
Guides and articles with external linksDonorAdd in-body links to the category or product each one supports
Commercial hubs and categoriesAcceptorMake sure navigation, breadcrumbs and relevant articles link to them
New products or pagesAcceptorFeature them in listings and hubs until they settle
Thin tag and archive pagesNeitherConsolidate, or keep them out of the main link paths
Sorted and filtered viewsNeitherFew 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.

  1. Pull the guides that discuss the category's topic, through site search or a CMS query.

  2. 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.

  3. Replace both "click here" anchors.

  4. Check that trail shoe product pages carry a breadcrumb to the category and that the running shoes hub links to it.

  5. 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.

AnchorProblemBetter
click hereSays nothing about the destinationwaterproof hiking boots
best hiking boots cheap hiking boots for saleKeyword stuffinghiking boots for wide feet
read more, on 20 cards in a rowTwenty identical generic anchorsThe article title as the link
this guide, pointing to a sizing pageVaguehow to measure your feet for boots
An icon with no text or altNothing for Google to readVisible 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:

  1. Build the list of URLs that should be indexable, from XML sitemaps, a CMS or database export, and analytics landing pages.

  2. Crawl from the home page following links only, not sitemaps, with JavaScript rendering if your links depend on it.

  3. 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 inventory

Each 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.

ApproachHow links are chosenStabilityGood forMain risk
Live widgetCalculated on each request from tags, co-views or popularityChanges oftenCovering a huge long tail cheaplyChurn, and links pile onto already-popular pages
Stored link tableCalculated in batches, reviewed, then served from a tableStable between updatesLarge catalogs that need predictable linksGoes stale if never recalculated
Hand-picked linksChosen by someone who knows both pagesStableHubs and priority pagesDoesn'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.