SEO

Hub-and-spoke internal links: a structure that holds

A hub defines the topic, spokes go deeper. Of 458 blog articles, 256 receive no internal link at all: the problem is direction, not volume.

Key points

  • Hub-and-spoke means one page that defines and many that go deeper, with links in both directions.
  • Across 458 blog articles, 882 internal links and 256 pages with no inbound link: half the site is reachable only from the sitemap.
  • Google follows a link only when it is an a element with an href: a link built from a JavaScript event transfers nothing.

A hub is the page that defines a topic; spokes are the articles that go deeper. The model works when every spoke links the hub, the hub links every spoke, and two neighbouring spokes link each other.

Why direction beats volume

Google uses links as a signal when judging relevance and to find new pages: that is the first sentence of the documentation on links, read on 1 November 2026. An article linked from three relevant pages receives a signal no text can replace. An article linked from nowhere depends on the sitemap, and the sitemap says the page exists, not that it matters.

What Google does not follow

The same page says Google follows a link only when it is an <a> element with an href. A div with onclick, a router.push call with no href and a link added after load can work for the user and stay invisible to the crawler. In React components the usual case is an <a> replaced by a wrapper: the browser navigates, the crawler does not.

Counting the orphans

cat > link-report.mjs  f.endsWith(".json"));
const inbound = new Map();
for (const file of files) {
  const post = JSON.parse(fs.readFileSync(`${dir}/${file}`, "utf8"));
  const html = post.body.map((b) => b.html || "").join(" ");
  for (const [, href] of html.matchAll(/href="\/blog\/([a-z0-9-]+)"/g)) {
    inbound.set(href, (inbound.get(href) || 0) + 1);
  }
}
const orphans = files
  .map((f) => f.replace(/\.json$/, ""))
  .filter((slug) => !inbound.has(slug));
console.log(`${files.length} posts, ${orphans.length} with no inbound link`);
console.log(orphans.slice(0, 20).join("\n"));
EOF
node link-report.mjs

The script reads the blog JSON, extracts every internal href and prints the articles with no inbound link. On this site's dataset that is 256 out of 458: more than half. It is not a writing mistake, it is what publishing one article a day does when nobody goes back to the pages that already exist.

The minimum shape

  • One hub per topic, with a paragraph explaining the cluster and the full list of spokes.
  • Every spoke links the hub at the top or at the end, with the topic name in the anchor text.
  • Two sibling spokes link each other when they solve the same problem from two sides.
  • Three catalogue links, because the catalogue is the proof the content exists.
  • No link added just to fill space: a link nobody clicks is still a link, but it leads nowhere.

The live record

The catalogue already has natural hubs: dashboard, blog and the root /blocks. A category page is a hub that links its blocks, and every block links its own library: the same shape, applied to 1,556 blocks. Checked on 1 November 2026.

The limitation

Internal links do not create demand. If an article has no impressions after ninety days, adding links changes little: the problem is intent or content. This project's rule is to rewrite it once, then merge it into the hub with a redirect. The orphan count tells you where to look, not what to write.

Where to continue

The wider strategy is in internal links: strategy; the list that holds a cluster together is in how to build a blog index; what to watch in Search Console is in Search Console and indexing. If you are picking a marketing site stack, how many pages you can link at no cost changes: the comparison is in Next.js or Vite for a marketing site.

Frequently asked questions

How many internal links does a page need?

There is no number: it needs the links that help someone understand. Three or four contextual links per article are enough, if each one leads to the page answering the next question.

Does an internal link count as a backlink?

No. A backlink carries a signal from another domain; an internal link distributes authority inside the site and helps pages get discovered. Both matter, for different reasons.

Do links in the menu count?

They count, but they do not discriminate: a menu link appears on every page and says little about one of them. A contextual link inside the text says what the page is about.

Anchor text or “click here”?

Anchor text, because it describes the destination. “Click here” says nothing to a screen reader user and nothing to Google.

Is an article with no inbound link invisible?

No, it stays in the sitemap and can be indexed. It loses the signal links carry, and in practice it stays behind the pages that are linked.