You have 800 articles, a vague sense that internal linking matters, and no idea which 20 missing links would actually move rankings. This tutorial turns that fog into a ranked CSV of bridge candidates: pairs where the source article already has authority, the target is on-topic and under-linked, and a natural anchor exists. AI does the cross-article reading; you sign off on the diff. On a real content site you should see target-page impressions in Search Console rise within 2-4 weeks and previously orphaned pages start collecting clicks inside 60 days.
TL;DR
- Export every article to a CSV: slug, title, first 200 words, tags, and current inbound-link count (a ~30-line script over your content folder).
- Feed the CSV to a 1M-context model (Claude Opus 4.7, Sonnet 4.6, or Gemini 3.1 Pro) and ask for 50 bridge candidates where source inlinks are 3 or more and target inlinks are 2 or fewer, each with a one-line rationale, suggested anchor, and a 1-5 confidence score.
- Keep the top 20 by confidence, reject anything justified by tag overlap alone, verify each insertion paragraph by hand, and ship in one PR.
- Re-run after every batch of 20+ new articles. Bridges are the cheapest SEO win on a content site.
Why orphan and under-linked pages bleed traffic
Google discovers and ranks pages largely through the links pointing at them. A page with zero internal inbound links is an orphan: crawlers reach it only through your sitemap or an external link, and it sits near the bottom of the crawl priority. Pages with few inbound links concentrate little PageRank and rarely rank for anything competitive. The fix is not more pages, it is routing the authority you already have to the pages that need it.
Two numbers from current SEO guidance anchor the whole workflow. First, keep total links on any page under roughly 150 (nav and footer included), because Google distributes link equity across every outbound link, so a page stuffed with links passes a thinner signal through each one. Second, keep priority pages within three clicks of the homepage. Bridge links are how you pull a deep, under-linked page closer to the surface without redesigning navigation.
You can sanity-check your starting point for free: Google Search Console’s Links report has a “Top linked pages (internal)” table. The pages missing from the bottom of that list, or sitting at one or two links, are your orphan and under-linked targets. Export it and compare against your full slug inventory to find the gaps the report does not even surface.
Who this is for
Content site owners with 200+ articles, indie SEOs running monthly link sweeps, and editors handed a legacy site with no internal-link discipline. Skip the tooling if you have under 100 articles; eyeballing the topic graph is genuinely faster at that scale.
Two ways to score “topical fit”
There are two AI approaches, and the strongest workflow combines them.
| Approach | How it works | Strength | Weakness |
|---|---|---|---|
| Long-context LLM | Paste the whole CSV into one prompt; the model reasons over titles and intros | Judges intent and writes natural anchors | Recall degrades past ~400K tokens; expensive on huge sites |
| Embeddings + cosine similarity | Embed each article, compute similarity for every pair, rank | Cheap, scales to thousands of pages, deterministic | Surfaces semantically near but contextually wrong pairs; no anchor text |
The practical recipe: if your CSV fits comfortably under ~300K tokens (roughly 1,000 articles of title plus first paragraph), a single long-context pass is simplest. Above that, embed all pages first, keep the top similarity pairs, then hand only those candidate pairs to an LLM to judge fit and draft anchors. Embeddings narrow the field cheaply; the LLM does the judgment embeddings cannot.
Picking a model as of June 2026: Claude Opus 4.7, Sonnet 4.6, and Gemini 3.1 Pro all carry a 1M-token context window, so they swallow a full mid-size site in one prompt. Independent long-context tests show retrieval accuracy falls off as you fill the window, so do not assume a 900K-token prompt is read as carefully as a 200K one. Note that Gemini 3.1 Pro’s API price tiers up past 200K input tokens (input roughly doubles), so a 600K-token CSV pass costs more than the headline rate suggests. For a few hundred articles, any of the three is fine and cheap.
Before you start
- Export your full article inventory: slug, title, primary keyword, tags, and current inbound-link count. A small script over your content collection produces this in minutes.
- Define what “bridge” means for your site. The default rule below: source has 3+ existing inbound links (authority to pass) and target has 2 or fewer (needs the lift).
- Have a 1M-context model ready. 800 rows of title plus first paragraph easily clears 80k tokens; you do not want to chunk this.
- Write a “do not link” list: legal pages, sitemap, dated news, thank-you pages. AI will propose links into them otherwise.
Step by step
- Generate the CSV. Columns: slug, title, H1, first 200 words, primary keyword, tag list, current inlink count. The first 200 words are the context AI needs to judge topical fit; the title and tags alone are not enough.
- Compute inlink counts. Walk your markdown files and count internal-link occurrences per slug. A script like the one below is enough.
- Prompt the model. Paste the full CSV and the rule: propose 50 bridge candidates where source inlinks >= 3 and target inlinks <= 2. Require a one-line rationale naming the topical connection, suggested anchor text (3-6 words), and a confidence score of 1-5.
- Filter to the top 20 by confidence. Reject anything where the rationale leans on a tag match alone. Tag overlap without topical overlap produces weak links that read as inserted.
- Verify each insertion point by hand. Open the source article, confirm the paragraph the model cited actually exists, and read the suggested anchor in context. If it does not read naturally aloud, rewrite the anchor or drop the link.
- Ship in one PR. One commit per source file keeps the diff reviewable. Avoid bulk regex inserts; they break sentence flow and you cannot defend them in six months.
- Measure. After 4 weeks, check target-page impressions in Search Console. Bridge links surface previously orphaned pages, so impressions rise before clicks.
A minimal inlink-count script
This Node snippet walks a content folder, counts how many files link to each slug, and writes the inlink column. Adapt the link pattern to your routing.
import { readFileSync, readdirSync, writeFileSync } from "node:fs";
import { join } from "node:path";
const dir = "src/content/articles/en";
const files = readdirSync(dir, { recursive: true }).filter((f) => f.endsWith(".mdx"));
const counts = {};
for (const file of files) {
const body = readFileSync(join(dir, file), "utf8");
// matches /en/articles/<slug>/ links in prose
for (const m of body.matchAll(/\/en\/articles\/([a-z0-9-]+)\//g)) {
counts[m[1]] = (counts[m[1]] || 0) + 1;
}
}
const rows = files.map((f) => {
const slug = f.replace(/\.mdx$/, "").split("/").pop();
return `${slug},${counts[slug] || 0}`;
});
writeFileSync("inlinks.csv", "slug,inlinks\n" + rows.join("\n"));
Join this inlinks.csv against your title and first-200-words export, and you have the full input for the AI pass.
The bridge prompt
Paste the CSV, then:
You are an internal-linking editor. From the CSV, propose 50 bridge links. A valid bridge goes from a source article with
inlinks >= 3to a target withinlinks <= 2, and the two must share genuine topical overlap (not just a tag). For each, output: source slug, target slug, suggested anchor text (3-6 words, varied across the batch), a one-line rationale naming the specific shared topic, and a confidence score 1-5. Never propose links into this banned list: [your do-not-link slugs]. Reject pairs where the only connection is a shared tag.
Quality check before you merge
- Every bridge has a one-line rationale that names the specific topical connection, not “related topic.” Vague rationales mask weak proposals.
- Anchor text varies across the batch. If 15 of 20 anchors are the target’s exact title, the model is being lazy; add a variation constraint and re-run.
- No bridge points from a thin page (under 800 words) to a pillar. Authority flows from depth, and a thin source passes a thin signal.
- No source page is pushed over ~150 total links by your additions. Two contextual bridges per paragraph is the hard ceiling.
- Spot-check 3 random source paragraphs aloud: does the link read naturally, or feel inserted?
Make it a repeatable monthly sweep
- Save the prompt, the inlink-count script, and the banned-target list as a project doc. Re-run after every content launch without re-thinking the rules.
- Keep a “link debt” log: target pages still below 2 inlinks after two sweeps. Those pages usually need rewriting, not more links pointed at them.
- Save each round’s rejected candidates. Patterns emerge (“this model keeps proposing links to FAQ pages”) and become banned-target rules next round.
Common mistakes
- Linking on tag overlap instead of topical overlap. Tags are a proxy; the model must judge the content, not the metadata.
- Repeating one anchor across the batch. It looks templated to Google and dilutes the signal.
- Stuffing 5 bridges into one paragraph. Two per paragraph maximum, or the source reads as link bait.
- Skipping the rationale field. Without it you cannot tell strong proposals from filler, and you cannot defend the link later.
- Linking from a thin source. The link passes proportional authority; thin sources pass thin signals.
- Trusting a 900K-token prompt blindly. Long-context recall degrades as the window fills, so verify the model actually used pages buried mid-CSV.
FAQ
- How many bridges per month? 20 high-quality bridges beats 100 weak ones. Quality compounds; quantity dilutes the equity each link passes.
- Should bridges always go from old to new pages? Mostly. Old pages have accrued authority and new pages need the lift. Reverse only when the new page is a pillar that older pages should feed.
- What anchor length works best? 3-6 descriptive words. Single-word anchors are weak; sentence-long anchors look spammy and rarely read naturally.
- Embeddings or a long-context LLM? For under ~1,000 articles, one long-context pass is simpler. Above that, embed first to cut the candidate set, then let the LLM judge fit and write anchors.
- Can AI judge topical fit reliably? It is strong on semantic similarity and weaker on intent matching, which is exactly why the one-line rationale is your guardrail. You reject; the model proposes.
- How long until I see results? Target-page impressions typically rise in 2-4 weeks, rankings follow in 4-8 weeks, and clicks come after rankings settle.
Related
Tags: #SEO #internal-links #Tutorial