<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hermis</title>
    <description>The latest articles on DEV Community by Hermis (@hermis_rf).</description>
    <link>https://dev.to/hermis_rf</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4080188%2F8581809e-e1e9-4e52-ab93-1630378b42b7.png</url>
      <title>DEV Community: Hermis</title>
      <link>https://dev.to/hermis_rf</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hermis_rf"/>
    <language>en</language>
    <item>
      <title>I Crawled 4 More Dev Sites. One Had 9 Orphan Pages Out Of 10</title>
      <dc:creator>Hermis</dc:creator>
      <pubDate>Sun, 20 Sep 2026 03:06:59 +0000</pubDate>
      <link>https://dev.to/hermis_rf/i-crawled-4-more-dev-sites-one-had-9-orphan-pages-out-of-10-3pp5</link>
      <guid>https://dev.to/hermis_rf/i-crawled-4-more-dev-sites-one-had-9-orphan-pages-out-of-10-3pp5</guid>
      <description>&lt;p&gt;Following up on last week's four-site crawl, I ran the same free crawler against four more sites developers use daily — nodejs.org, vuejs.org, digitalocean.com, and webpack.js.org — 10 pages each, starting from the homepage. Three came back with healthy internal-link structure. One, digitalocean.com, had 9 of its 10 sampled pages come back as orphans.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I ran
&lt;/h2&gt;

&lt;p&gt;No account needed, so this is reproducible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;POST https://rankforge.cc/api/analyzer&lt;/code&gt; with &lt;code&gt;{"seed_url": "..."}&lt;/code&gt;, then poll &lt;code&gt;GET /api/analyzer/&amp;lt;id&amp;gt;&lt;/code&gt; until &lt;code&gt;status&lt;/code&gt; is &lt;code&gt;completed&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The crawler follows internal links breadth-first from the seed, caps at 10 pages for the anonymous tier, and runs a PageRank-style authority simulation restricted to the crawled subgraph.&lt;/li&gt;
&lt;li&gt;Raw JSON for all four runs: &lt;code&gt;content/analyzer_20260920_&amp;lt;host&amp;gt;.json&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The healthy three
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;nodejs.org&lt;/strong&gt; came back with an average internal authority of 100 across the sample — every page the crawler reached was tightly cross-linked from the others, with &lt;code&gt;/learn&lt;/code&gt; topping the authority table. 611 internal links found across 10 pages, only 1 hitting the weakest-20% bucket, 1 redirect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;webpack.js.org&lt;/strong&gt; was close behind: average authority 79.32, 627 links, two pages (&lt;code&gt;/concepts&lt;/code&gt; and &lt;code&gt;/guides/getting-started&lt;/code&gt;) tied at the top of the authority table. Dense docs cross-linking, nothing orphaned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;vuejs.org&lt;/strong&gt; landed in the middle: average authority 46.13, 873 links found, homepage naturally at 100 and &lt;code&gt;/api/application.html&lt;/code&gt; next at 28.17. Normal shape for a docs site — a strong homepage feeding an internal hierarchy, no orphans, no redirect chains.&lt;/p&gt;

&lt;h2&gt;
  
  
  digitalocean.com: 9 of 10 crawled pages were orphans
&lt;/h2&gt;

&lt;p&gt;This is the one worth a closer look. Starting from the DigitalOcean homepage, the crawler reached 10 pages, and 9 of them had &lt;strong&gt;zero internal links pointing to them&lt;/strong&gt; from anywhere else in the crawled set — they were only reachable because something earlier happened to link to them once. All 9 were the same kind of page: old community tutorial-collection landing pages —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/community/tutorial-collections/how-to-install-magento
/community/tutorial-collections/how-to-install-the-mean-stack
/community/tutorial-collections/how-to-install-and-use-memcache
/community/tutorial-collections/how-to-install-wordpress-with-nginx
/community/tutorial-collections/how-to-install-mysql
/community/tutorial-collections/how-to-install-lamp
/community/tutorial-collections/how-to-set-up-ssh-keys
/community/tutorial-collections/how-to-install-apache-tomcat
/community/tutorial-collections/how-to-set-up-a-node-js-application-for-production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;DigitalOcean's community section is enormous — this is a 10-page sample, not a site-wide audit, so it doesn't mean the whole tutorial library is 90% orphaned. What it does show is that whatever navigation path the crawler followed from the homepage lands in a cluster of &lt;code&gt;tutorial-collections&lt;/code&gt; landing pages that don't link to each other or back into the main site nav. The average internal authority for the sample came back at 20.41, dragged down by that cluster, while the homepage itself held the maximum score of 100 and the strongest tutorial page (&lt;code&gt;how-to-install-and-use-memcache&lt;/code&gt;) only reached 11.57.&lt;/p&gt;

&lt;p&gt;Tutorial-collection or topic-hub pages like this are usually generated once from a template, linked from a single index or search result, and then never cross-linked to sibling collections again. They're not broken — a user who lands on one from Google gets useful content — but they're structurally isolated from the site's main internal link graph, which is exactly the kind of thing that caps how much authority flows into that whole content cluster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this keeps showing up
&lt;/h2&gt;

&lt;p&gt;Across eight sites now (four last week, four this week), the pattern repeats: large, well-maintained sites with real engineering teams still accumulate pockets of internally orphaned content — usually old campaign pages, supporter walls, or auto-generated topic-collection pages that were linked once and forgotten. None of it is catastrophic. All of it is invisible from a normal site walkthrough, and only shows up once you crawl the actual link graph and check what points to what.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it on your own site
&lt;/h2&gt;

&lt;p&gt;Same checks (orphan pages, near-orphans, internal authority distribution, redirect chains) run in one pass, no signup: &lt;a href="https://rankforge.cc/audit" rel="noopener noreferrer"&gt;rankforge.cc/audit&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>programming</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I Crawled 4 Major Dev Sites' First 10 Pages. Two Had Real Structural Bugs</title>
      <dc:creator>Hermis</dc:creator>
      <pubDate>Sat, 19 Sep 2026 03:14:19 +0000</pubDate>
      <link>https://dev.to/hermis_rf/i-crawled-4-major-dev-sites-first-10-pages-two-had-real-structural-bugs-4bm4</link>
      <guid>https://dev.to/hermis_rf/i-crawled-4-major-dev-sites-first-10-pages-two-had-real-structural-bugs-4bm4</guid>
      <description>&lt;p&gt;On 2026-09-19 I ran four well-known developer-facing sites through the free crawler on my own SEO tool — smashingmagazine.com, freecodecamp.org, tailwindcss.com, and mozilla.org — 10 pages each, starting from the homepage. I wasn't looking for anything specific, just comparing internal-link health across sites that presumably have real engineering teams behind them. Two of the four had a genuine structural bug in the crawled sample; the other two were clean.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I ran
&lt;/h2&gt;

&lt;p&gt;No account needed, so this is reproducible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;POST https://rankforge.cc/api/analyzer&lt;/code&gt; with &lt;code&gt;{"seed_url": "..."}&lt;/code&gt;, then poll &lt;code&gt;GET /api/analyzer/&amp;lt;id&amp;gt;&lt;/code&gt; until &lt;code&gt;status&lt;/code&gt; is &lt;code&gt;completed&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The crawler follows internal links breadth-first from the seed, caps at 10 pages for the anonymous tier, and runs a PageRank-style authority simulation restricted to the crawled subgraph.&lt;/li&gt;
&lt;li&gt;Raw JSON for all four runs: &lt;code&gt;content/analyzer_20260919_&amp;lt;host&amp;gt;.json&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The clean pair
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;tailwindcss.com&lt;/strong&gt; was the healthiest of the four: 1,608 internal links found across the 10 pages, average internal authority 63.24, and only 1 of the 10 pages fell into the weakest-20%-authority bucket. Dense internal linking, nothing orphaned, nothing redirecting strangely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;smashingmagazine.com&lt;/strong&gt; was solid too — 847 links, average authority 32.39, zero orphan or near-orphan pages in the sample. It does carry 9 internal redirects (mostly old article URLs 301'd to canonical ones), which cost a hop each but nothing broken.&lt;/p&gt;

&lt;h2&gt;
  
  
  freecodecamp.org: 8 of 10 crawled pages were orphans
&lt;/h2&gt;

&lt;p&gt;This is the one that surprised me. Starting from the freeCodeCamp homepage, 8 of the 10 pages the crawler reached had &lt;strong&gt;zero internal links pointing to them&lt;/strong&gt; — they were only reachable because something on an earlier page happened to link to them once, then nothing else in the crawled set linked back. All 8 were the same &lt;em&gt;kind&lt;/em&gt; of page: old supporter/contributor "thank you" and wallpaper pages —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/news/freecodecamp-supporter-happy-2023-wallpaper
/news/thank-you-for-donating
/news/super-secret-supporter-wallpaper
/news/thank-you-for-being-a-supporter
/news/2025-supporter-wallpaper
/news/podcast-guest-checklist
/news/top-contributor-happy-2023-wallpaper
/news/2025-top-contributor-wallpaper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;freeCodeCamp is enormous — this is a 10-page sample, not a site-wide audit, so it doesn't mean the whole site is 80% orphaned. What it does show is that whatever internal navigation path the crawler followed from the homepage dead-ends into a cluster of donor/supporter pages that don't link to anything else in the main content graph and aren't linked from each other. All 8 landed on the exact same authority score (12.82), which is what the simulation produces for pages that form an isolated cluster fed by identical inbound paths rather than genuine cross-linking — a distinct signature from a healthy content page that earns varied internal links from different sections of the site.&lt;/p&gt;

&lt;p&gt;If you maintain a site with a similar "supporter wall" or campaign-page pattern, this is worth checking: pages like this often get created once, linked from a single sitewide footer or CTA, and never touched again. They're not broken, but they're structurally isolated from the rest of the site's internal link graph.&lt;/p&gt;

&lt;h2&gt;
  
  
  mozilla.org: pages that redirect to themselves
&lt;/h2&gt;

&lt;p&gt;The odder result. Average internal authority for the mozilla.org sample came back as 0 — every page in the 10-page crawl showed up in the redirect audit instead of the normal authority table. The redirect audit flagged 9 of the 10 pages, and the entries look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;https://www.mozilla.org/en-US/about/manifesto
&lt;/span&gt;&lt;span class="gp"&gt;  -&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;redirects to: https://www.mozilla.org/en-US/about/manifesto  &lt;span class="o"&gt;(&lt;/span&gt;2 hops, status 301&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;https://www.mozilla.org/en-US/privacy/websites/cookie-settings
&lt;/span&gt;&lt;span class="gp"&gt;  -&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;redirects to: https://www.mozilla.org/en-US/privacy/websites/cookie-settings  &lt;span class="o"&gt;(&lt;/span&gt;1 hop, status 301&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="go"&gt;https://www.mozilla.org/en-US/products/vpn
&lt;/span&gt;&lt;span class="gp"&gt;  -&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;redirects to: https://www.mozilla.org/en-US/products/vpn  &lt;span class="o"&gt;(&lt;/span&gt;1 hop, status 302&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each URL's &lt;code&gt;redirects_to&lt;/code&gt; field is identical to the URL itself. That reads as a locale/trailing-slash redirect loop that resolves back to the same canonical path — plausible causes are a &lt;code&gt;www&lt;/code&gt; vs. non-&lt;code&gt;www&lt;/code&gt; normalization step, an &lt;code&gt;en-US&lt;/code&gt; locale rewrite, or a cookie-consent gate that 302s every request through itself once before serving content. Functionally it's harmless to a human visitor (the browser follows the hop instantly and lands on the right page), but it means every internal link on the site is spending a redirect hop it doesn't need to, and it's why the crawler's authority table came back empty — the simulation attributes authority to the final resolved URL, and here that bookkeeping collapsed the whole sample into the redirect audit instead.&lt;/p&gt;

&lt;p&gt;Neither of these is a catastrophic SEO problem. freeCodeCamp's orphan cluster is old campaign pages that were probably never meant to rank on their own. Mozilla's self-redirect is a normalization quirk that costs milliseconds, not rankings. But both are the kind of thing that's invisible from a normal site walkthrough and only shows up once you crawl the actual link graph and check what points to what — which is the whole reason a link-structure crawl is worth running occasionally even on sites that already have dedicated engineering teams.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it on your own site
&lt;/h2&gt;

&lt;p&gt;Same four checks (orphan pages, near-orphans, internal authority distribution, redirect chains) run in one pass, no signup: &lt;a href="https://rankforge.cc/audit" rel="noopener noreferrer"&gt;rankforge.cc/audit&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>programming</category>
      <category>datascience</category>
    </item>
    <item>
      <title>5 Sites, 3,671 Internal Links, and 2% Editorial at Best</title>
      <dc:creator>Hermis</dc:creator>
      <pubDate>Thu, 17 Sep 2026 20:24:56 +0000</pubDate>
      <link>https://dev.to/hermis_rf/5-sites-3671-internal-links-and-2-editorial-at-best-4alj</link>
      <guid>https://dev.to/hermis_rf/5-sites-3671-internal-links-and-2-editorial-at-best-4alj</guid>
      <description>&lt;p&gt;Every internal-linking guide ends with the same instruction: add more internal links. On 2026-09-07 I checked whether that was actually the problem. I ran five sites through the free analyzer on my own SEO tool and looked at one thing — not how many internal links each site had, but what kind.&lt;/p&gt;

&lt;p&gt;None of them was short on links. Between them, 3,671 internal links on the crawled pages. The share classified as &lt;strong&gt;editorial&lt;/strong&gt; — a link written inside body copy, pointing somewhere specific — topped out at 2%. On three of the five it rounded to zero.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I ran
&lt;/h2&gt;

&lt;p&gt;No account needed, so this is reproducible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;POST https://rankforge.cc/api/analyzer&lt;/code&gt; with &lt;code&gt;{"seed_url": "..."}&lt;/code&gt;, then poll &lt;code&gt;GET /api/analyzer/&amp;lt;id&amp;gt;&lt;/code&gt; until &lt;code&gt;status&lt;/code&gt; is &lt;code&gt;completed&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Anonymous tier, which caps each crawl at 10 pages. Every run came back with &lt;code&gt;crawl_complete: false&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Five seeds, all run on 2026-09-07: &lt;code&gt;ahrefs.com/blog&lt;/code&gt;, &lt;code&gt;css-tricks.com&lt;/code&gt;, &lt;code&gt;kubernetes.io/docs/home&lt;/code&gt;, &lt;code&gt;rankforge.cc&lt;/code&gt;, &lt;code&gt;www.thestackanalyst.com&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The 10-page cap matters, so I'm putting it up front rather than in a footnote. This is a sample of the pages nearest each seed — the homepage or hub, plus what it links to first. It is the top of a site, not the whole site.&lt;/p&gt;

&lt;p&gt;That cuts in an interesting direction, though. The top of a site is where internal linking is supposed to be strongest and most deliberate. It's the friendliest place to go looking for editorial links, not the harshest.&lt;/p&gt;

&lt;p&gt;The classifier sorts every internal link into four buckets: &lt;strong&gt;editorial&lt;/strong&gt; (inside body content), &lt;strong&gt;navigational&lt;/strong&gt; (menus, headers, breadcrumbs), &lt;strong&gt;list&lt;/strong&gt; (archive and card grids), and &lt;strong&gt;boilerplate&lt;/strong&gt; (footers and other site-wide furniture).&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Site&lt;/th&gt;
&lt;th&gt;Internal links&lt;/th&gt;
&lt;th&gt;Editorial&lt;/th&gt;
&lt;th&gt;Navigational&lt;/th&gt;
&lt;th&gt;List&lt;/th&gt;
&lt;th&gt;Boilerplate&lt;/th&gt;
&lt;th&gt;Nav-sat.&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ahrefs.com/blog&lt;/td&gt;
&lt;td&gt;1,276&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;35.6%&lt;/td&gt;
&lt;td&gt;31.2%&lt;/td&gt;
&lt;td&gt;33.2%&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;css-tricks.com&lt;/td&gt;
&lt;td&gt;59&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;83.1%&lt;/td&gt;
&lt;td&gt;16.9%&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;kubernetes.io/docs&lt;/td&gt;
&lt;td&gt;1,335&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;95.4%&lt;/td&gt;
&lt;td&gt;4.6%&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rankforge.cc&lt;/td&gt;
&lt;td&gt;503&lt;/td&gt;
&lt;td&gt;0.6%&lt;/td&gt;
&lt;td&gt;14.3%&lt;/td&gt;
&lt;td&gt;9.9%&lt;/td&gt;
&lt;td&gt;75.1%&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;thestackanalyst.com&lt;/td&gt;
&lt;td&gt;498&lt;/td&gt;
&lt;td&gt;2%&lt;/td&gt;
&lt;td&gt;74.7%&lt;/td&gt;
&lt;td&gt;22.7%&lt;/td&gt;
&lt;td&gt;0.6%&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/assets%2Fdiagram_link_composition.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/assets%2Fdiagram_link_composition.png" alt="Internal link composition across five sites: editorial links are a sliver on every one" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Four of five sites got flagged for weak internal linking. All five had plenty of links. None had many editorial ones.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not one of these sites had an orphan page in the crawled sample — all five report &lt;code&gt;orphan_pages_count: 0&lt;/code&gt;. Four of the five still got "Internal Link Strategy" flagged as their primary bottleneck.&lt;/p&gt;

&lt;h2&gt;
  
  
  Navigational links can't tell your pages apart
&lt;/h2&gt;

&lt;p&gt;This is the part that changed how I read internal-link reports.&lt;/p&gt;

&lt;p&gt;A menu link appears on every page and points at the same handful of destinations. In a PageRank-style model, that's a dense, near-uniform block of edges. It moves authority around, but it moves it the same way for everybody, so it can't express a preference. It has no opinion about which of your pages deserves to rank.&lt;/p&gt;

&lt;p&gt;Editorial links are the only ones that carry an opinion. Somebody writing a paragraph decided &lt;em&gt;this&lt;/em&gt; page was worth pointing at from &lt;em&gt;that&lt;/em&gt; sentence. That's the signal.&lt;/p&gt;

&lt;p&gt;When the navigational block dominates, the analyzer sets &lt;code&gt;nav_saturated: true&lt;/code&gt; — and then warns you about its own output:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Navigation/footer links reach nearly every page, so authority differences between pages are largely structural (a byproduct of the menu), not a reliable signal of which pages are strategically under-supported.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I like tools that do this. A per-page "authority score" on a nav-saturated site is mostly measuring your template. Ranking your pages by it and "fixing" the bottom five is chasing a menu.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it looks like on my own site
&lt;/h2&gt;

&lt;p&gt;My own site came out worst on composition: 75.1% boilerplate, 0.6% editorial. That's a footer doing the work that body copy should be doing.&lt;/p&gt;

&lt;p&gt;The analyzer proposed 7 specific in-body placements, each with a source page, a target, an anchor, and the sentence to put it in. It also simulates the result:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Links modeled&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total authority before&lt;/td&gt;
&lt;td&gt;922.34&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total authority after&lt;/td&gt;
&lt;td&gt;922.34&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;/docs/authority-flow&lt;/code&gt; before&lt;/td&gt;
&lt;td&gt;22.34&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;/docs/authority-flow&lt;/code&gt; after&lt;/td&gt;
&lt;td&gt;77.66 (+247.7%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pages gaining&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pages losing&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The two numbers I'd underline are the identical totals. Internal linking creates no authority. It's redistribution: one page went up 55 points, nine went down an average of 6.2 each. That's a fine trade when you know which page you want to win, and a pointless shuffle when you don't.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/docs/authority-flow&lt;/code&gt; was sitting at 22.34 on a site whose median page scores 98.93. It was reachable, indexable, in the footer — and structurally invisible.&lt;/p&gt;

&lt;h2&gt;
  
  
  The outlier worth looking at
&lt;/h2&gt;

&lt;p&gt;Kubernetes docs is the extreme case: 95.4% navigational, and the docs sidebar is doing essentially all of the linking. Its homepage holds 49% of the internal authority in the sample and the median page sits at 11.57.&lt;/p&gt;

&lt;p&gt;That is not a bug in their docs. A giant navigation tree is the correct interface for reference documentation, and their readers arrive from search on a specific page anyway. It's a good reminder that "editorial links are low" is a finding, not automatically a defect — the question is whether the pages you actually care about are getting any differentiation at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check yours in about two minutes
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. queue a crawl (anonymous, no signup)&lt;/span&gt;
&lt;span class="nv"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://rankforge.cc/api/analyzer &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"seed_url":"https://example.com/"}'&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; .id&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# 2. poll until it finishes&lt;/span&gt;
&lt;span class="k"&gt;until&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://rankforge.cc/api/analyzer/&lt;span class="nv"&gt;$ID&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; .status&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"completed"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;sleep &lt;/span&gt;10
&lt;span class="k"&gt;done&lt;/span&gt;

&lt;span class="c"&gt;# 3. the only number this post is about&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://rankforge.cc/api/analyzer/&lt;span class="nv"&gt;$ID&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | jq &lt;span class="s1"&gt;'.summary_metrics.link_quality | del(.pages_with_only_boilerplate_links)'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Real output from the &lt;code&gt;thestackanalyst.com&lt;/code&gt; run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"editorial_pct"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"navigational_pct"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;74.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"boilerplate_pct"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"list_pct"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;22.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"total_internal_links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;498&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser version of the same crawl lives at &lt;a href="https://rankforge.cc/audit" rel="noopener noreferrer"&gt;rankforge.cc/audit&lt;/a&gt; if you'd rather not shell out for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'm doing about it
&lt;/h2&gt;

&lt;p&gt;Three changes, in the order I'd rank them:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Stop treating link count as the metric.&lt;/strong&gt; 503 internal links and 0.6% editorial is a worse position than 60 links with 20 of them written on purpose.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read &lt;code&gt;nav_saturated&lt;/code&gt; before reading any per-page score.&lt;/strong&gt; If it's true, per-page authority deltas are template noise and the ranked "weak pages" list is not a to-do list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write the links into the prose.&lt;/strong&gt; Not a related-posts widget, not another footer column — a sentence that earns the link. That's the only bucket a template can't fake for you.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Run it on your own site and drop your &lt;code&gt;editorial_pct&lt;/code&gt; in the comments. Mine was 0.6%, and I build SEO tooling for a living — I'd like to know whether I'm the outlier or the norm.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Crawls run 2026-09-07 via the public RankForge analyzer API, anonymous tier, 10 pages per site. Raw JSON for all five runs is saved alongside this post; every figure above comes from &lt;code&gt;summary_metrics&lt;/code&gt; in those files.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>programming</category>
      <category>datascience</category>
    </item>
    <item>
      <title>I Crawled a Real Site With a Free Crawler and Found 2 Invisible Pages</title>
      <dc:creator>Hermis</dc:creator>
      <pubDate>Mon, 14 Sep 2026 03:05:54 +0000</pubDate>
      <link>https://dev.to/hermis_rf/i-crawled-a-real-site-with-a-free-crawler-and-found-2-invisible-pages-25m6</link>
      <guid>https://dev.to/hermis_rf/i-crawled-a-real-site-with-a-free-crawler-and-found-2-invisible-pages-25m6</guid>
      <description>&lt;p&gt;I spent about fifteen minutes on Monday crawling a site I don't own: &lt;code&gt;thestackanalyst.com&lt;/code&gt;, a small independent SEO-tools blog. Not a client, not a competitor — I picked it because it's the kind of site most of us actually run. WordPress, a few dozen posts, one person maintaining it.&lt;/p&gt;

&lt;p&gt;I wanted to answer one question with real data instead of vibes: &lt;strong&gt;if you crawl a small site with free tooling, what do you actually catch?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The answer, in this case: two orphan pages, one dead outbound link, and zero broken internal links. That last part matters — this site is in good shape. The point of this post isn't "look at this broken site." It's the method, run against a real example, so you can point it at your own domain this week.&lt;/p&gt;

&lt;h2&gt;
  
  
  The method: three steps, no paid tools
&lt;/h2&gt;

&lt;p&gt;Every step here is something you can do with a free crawler and a spreadsheet. I used the free crawler at &lt;code&gt;rankforge.cc&lt;/code&gt;, but the technique is tool-agnostic — anything that will fetch your URLs and record internal links works.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 — Crawl from the homepage
&lt;/h3&gt;

&lt;p&gt;Start at the root and let the crawler follow internal links until it runs out. This gives you the set of pages that are &lt;em&gt;reachable by following links&lt;/em&gt;. That distinction is the whole trick.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 — Diff that set against your sitemap
&lt;/h3&gt;

&lt;p&gt;Your sitemap is the set of pages you &lt;em&gt;say&lt;/em&gt; exist. Your crawl is the set of pages a crawler can &lt;em&gt;find by walking your site&lt;/em&gt;. Anything in the sitemap but not in the crawl is an orphan: live, indexable, and structurally invisible. The diff, on this site:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ crawl https://www.thestackanalyst.com | diff - sitemap.xml

&amp;gt; https://www.thestackanalyst.com/seo-tools     (0 internal links pointing at it)
&amp;gt; https://www.thestackanalyst.com/text-tools    (0 internal links pointing at it)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both lines exist in the sitemap. Neither appears as the target of a single internal link anywhere in the crawl.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 — Check link statuses, internal and outbound
&lt;/h3&gt;

&lt;p&gt;Same crawl, one extra pass. Internal 404s are self-inflicted damage. Outbound dead links are a different opportunity entirely — more on that at the end.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the crawl actually found
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/assets%2Fdiagram_crawl_vs_sitemap.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/assets%2Fdiagram_crawl_vs_sitemap.png" alt="Crawl vs sitemap — the two orphan pages live in the sitemap-only zone" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hard numbers, no rounding up:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;URLs fetched (crawl)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;200&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP 200 responses&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;197&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Non-200&lt;/td&gt;
&lt;td&gt;2× &lt;code&gt;wp-json&lt;/code&gt; oEmbed (400), 1× &lt;code&gt;xmlrpc.php&lt;/code&gt; (403) — WP infrastructure, not user pages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sitemap URLs declared&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;62&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Broken internal links&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;0&lt;/strong&gt; (beyond those two WP endpoints)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Homepage internal links&lt;/td&gt;
&lt;td&gt;53&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Homepage external links&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Orphan pages&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2: &lt;code&gt;/seo-tools&lt;/code&gt; and &lt;code&gt;/text-tools&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Outbound links checked (Top 100 listicle)&lt;/td&gt;
&lt;td&gt;134, exactly &lt;strong&gt;1 dead&lt;/strong&gt; (&lt;code&gt;keywordshitter.com&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Both orphans return HTTP 200. Both are in the sitemap. And across the entire 200-URL crawl — homepage, blog index, every post — &lt;strong&gt;zero internal links point to either one.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They're tool-hub pages. Someone built them, published them, submitted them in the sitemap, and never got around to wiring them into the nav.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;They're two doors with no hallway leading to them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I want to be completely fair here: this is exactly what almost every site looks like, mine included. Two orphans and no broken internal links on a site this size is a &lt;em&gt;healthy&lt;/em&gt; result. The site owner is doing fine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why orphans are worth caring about
&lt;/h2&gt;

&lt;p&gt;Three practical reasons, no statistics required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No internal anchor text signals.&lt;/strong&gt; Every internal link is a small statement about what a page is about. An orphan has none. Google has to guess from the page alone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Discovery depends entirely on the sitemap.&lt;/strong&gt; A sitemap is a hint, not a guarantee. When it's the &lt;em&gt;only&lt;/em&gt; path to a page, you've removed every redundancy from that page's discoverability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Link equity can't flow to it.&lt;/strong&gt; That homepage with 53 internal links is distributing authority across the site. Orphans get zero of it, forever, no matter how good they are.&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;/seo-tools&lt;/code&gt; and &lt;code&gt;/text-tools&lt;/code&gt;, the sting is that these are hub pages — the page type that &lt;em&gt;should&lt;/em&gt; be collecting internal links from every relevant post and passing authority down to individual tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do with each orphan
&lt;/h2&gt;

&lt;p&gt;Don't reflexively delete. Run the page through three questions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it good and still relevant?&lt;/strong&gt; → &lt;strong&gt;Link it in.&lt;/strong&gt; Not a footer dump — footer links are weak and readers ignore them. Put it in the main nav if it's a hub, and add contextual in-body links from the two or three posts most related to it. For &lt;code&gt;/seo-tools&lt;/code&gt;, that means linking it from every post that mentions an SEO tool. Anchor text should describe the destination, not say "click here."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it redundant with a stronger page?&lt;/strong&gt; → &lt;strong&gt;301 redirect&lt;/strong&gt; it to that stronger page and fold any unique content in. Neither thin page beats one solid page — merge them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it necessary but not search-worthy?&lt;/strong&gt; (thank-you pages, filtered views, internal utilities) → &lt;strong&gt;&lt;code&gt;noindex&lt;/code&gt;, and remove it from the sitemap.&lt;/strong&gt; An orphan you &lt;em&gt;intend&lt;/em&gt; to be an orphan isn't a bug — but it shouldn't be sitting in your sitemap sending mixed signals.&lt;/p&gt;

&lt;p&gt;The failure mode to avoid: leaving a page indexable, sitemapped, and unlinked.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bonus you get for free: outbound link rot
&lt;/h2&gt;

&lt;p&gt;Same crawl, extra pass. I checked the outbound links on their big "Top 100 Free SEO Tools" listicle — &lt;strong&gt;134 tool links checked&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exactly one was dead: &lt;code&gt;keywordshitter.com&lt;/code&gt;&lt;/strong&gt; (yes, real tool, real name — Dan Shure's free keyword tool). It timed out across http, https, and www variants. The other 133 resolved fine — for a listicle that size, a genuinely good ratio. But a dead link in a "here are the tools" post is a bad reader experience, and it's the kind of thing an author never notices because nobody re-clicks their own links.&lt;/p&gt;

&lt;p&gt;Here's why this is worth your time beyond tidiness: &lt;strong&gt;it's the most honest outreach angle there is.&lt;/strong&gt; You email the editor, name the dead link sitting in their list, and suggest a live alternative that does the same job. No pitch, no "I noticed you link to X, would you consider linking to me" dance. You're doing unpaid editorial QA on their most important page. Sometimes you get a link out of it. Often you just get a reply from a real person, which is worth more than most cold outreach ever produces.&lt;/p&gt;

&lt;p&gt;Run this against any listicle in your niche and you'll find candidates — roundup posts rot constantly, and tools die quietly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fifteen minutes, this week
&lt;/h2&gt;

&lt;p&gt;That's the whole exercise. One crawl, one sitemap diff, one link-status pass. Two orphan pages surfaced, one dead outbound link found, and a clean bill of health confirmed on everything else — on a site I'd never touched before.&lt;/p&gt;

&lt;p&gt;You almost certainly have orphans right now. Not because you're careless, but because sites accumulate pages faster than they accumulate links. This one had two. Yours almost certainly has at least one.&lt;/p&gt;

&lt;p&gt;If you want the fast version of step 2, the &lt;a href="https://rankforge.cc/tools/orphan-page-checker" rel="noopener noreferrer"&gt;orphan page checker&lt;/a&gt; does the crawl-versus-sitemap diff for you and hands you the list. Then work the three questions above on each result: link it, redirect it, or noindex it.&lt;/p&gt;

&lt;p&gt;Then go check that one listicle you keep linking to. I'd bet something on it is dead.&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to Find and Fix Orphan Pages Without Paying for a Crawler</title>
      <dc:creator>Hermis</dc:creator>
      <pubDate>Sun, 13 Sep 2026 03:03:19 +0000</pubDate>
      <link>https://dev.to/hermis_rf/how-to-find-and-fix-orphan-pages-without-paying-for-a-crawler-3ded</link>
      <guid>https://dev.to/hermis_rf/how-to-find-and-fix-orphan-pages-without-paying-for-a-crawler-3ded</guid>
      <description>&lt;p&gt;Orphan pages are pages on your site that no other page links to. Search engines&lt;br&gt;
can't find them through crawling alone — the only way they get indexed is if a&lt;br&gt;
search engine finds a link to them from &lt;em&gt;outside&lt;/em&gt; your site, or if you submit&lt;br&gt;
them directly. For most sites, orphans are quietly costing you money.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why orphans are a problem
&lt;/h2&gt;

&lt;p&gt;Every orphan page is a page your budget spent on but your site structure never&lt;br&gt;
promoted. The symptoms are easy to mistake for something else:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Wasted crawl budget&lt;/strong&gt; — if an orphan gets indexed, it still consumes
crawl capacity with every crawl cycle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Silent 404s&lt;/strong&gt; — many orphans are old campaign pages, staging pages, or
checkout-related URLs nobody decommissioned properly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lost internal-link equity&lt;/strong&gt; — internal links are how PageRank-style
signals flow around a site. Orphans are cut off from that flow by
definition.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confusing user journeys&lt;/strong&gt; — if a visitor &lt;em&gt;does&lt;/em&gt; land on an orphan (via a
bookmark, a PPC ad, or an old email), there's no natural next step.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The free way to find them
&lt;/h2&gt;

&lt;p&gt;The classic paid answer is a full site crawler. But for most sites under a few&lt;br&gt;
hundred thousand URLs, you can get the same result for free:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Crawl your site.&lt;/strong&gt; Use a free crawler that respects robots.txt and
follows internal links. &lt;a href="https://rankforge.cc" rel="noopener noreferrer"&gt;RankForge's free crawl&lt;/a&gt;
does this for small and medium sites in a couple of minutes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collect every URL your crawler found&lt;/strong&gt; — these are your "linked" pages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Get your full URL list from your CMS or analytics.&lt;/strong&gt; In Google Analytics
(or GA4's page-path report) you'll see the pages people actually reached.
In most CMSes, an XML sitemap export or a database export gives you the
complete list of published pages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Subtract.&lt;/strong&gt; Any URL that exists in your CMS/sitemap but was &lt;em&gt;never&lt;/em&gt; found
by the crawl is an orphan — nothing internal links to it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's the whole method. No paid tool required.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do with each orphan
&lt;/h2&gt;

&lt;p&gt;Not all orphans deserve the same treatment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fix and relink&lt;/strong&gt; — if the page is genuinely useful (a guide, a product
page, a comparison), add a contextual internal link from a related page.
Don't just drop it in the footer; a contextual link from a relevant article
passes more relevance than a site-wide link.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redirect&lt;/strong&gt; — if the page was replaced by a newer version, 301 it to the
new URL so any existing equity (from external links or bookmarks) moves
with it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deindex and leave&lt;/strong&gt; — staging pages, printer-friendly versions, and
parameter URLs that have no business being indexed: add &lt;code&gt;noindex&lt;/code&gt; and leave
them alone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delete&lt;/strong&gt; — genuinely dead content can be removed, but only after checking
that nothing external links to it. If external links exist, redirect
instead.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Build it into your routine
&lt;/h2&gt;

&lt;p&gt;Orphans accumulate faster than you think — every campaign page, every A/B&lt;br&gt;
test landing page, every unlinked article adds to the pile. Run the check&lt;br&gt;
monthly, or hook it into your deploy pipeline and audit after every release.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you want a quick start, &lt;a href="https://rankforge.cc" rel="noopener noreferrer"&gt;RankForge's free orphan-page checker&lt;/a&gt; does the crawl and the subtraction for you — no signup, no credit card.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>programming</category>
      <category>marketing</category>
    </item>
    <item>
      <title>Internal Linking Audit: 5 Free Checks That Take 5 Minutes</title>
      <dc:creator>Hermis</dc:creator>
      <pubDate>Sat, 12 Sep 2026 03:10:11 +0000</pubDate>
      <link>https://dev.to/hermis_rf/internal-linking-audit-5-free-checks-that-take-5-minutes-3ngk</link>
      <guid>https://dev.to/hermis_rf/internal-linking-audit-5-free-checks-that-take-5-minutes-3ngk</guid>
      <description>&lt;p&gt;Internal links are the plumbing of your site. They tell search engines what&lt;br&gt;
matters, spread ranking signals between pages, and — more practically — they&lt;br&gt;
are the single biggest &lt;em&gt;free&lt;/em&gt; lever most sites ignore. Here are five checks&lt;br&gt;
you can run right now with free tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Find orphan pages
&lt;/h2&gt;

&lt;p&gt;Any page with zero internal links pointing to it is an orphan. It might be&lt;br&gt;
indexed (if an external link found it), but it's getting no internal signal,&lt;br&gt;
and it's invisible to your own navigation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The check:&lt;/strong&gt; crawl your site and diff the discovered URLs against your&lt;br&gt;
sitemap/CMS export. Every URL in the export that the crawl never saw is an&lt;br&gt;
orphan. &lt;a href="https://rankforge.cc" rel="noopener noreferrer"&gt;RankForge's free crawler&lt;/a&gt; does the diff for you&lt;br&gt;
in one step.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Count how many pages have no internal links &lt;em&gt;at all&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;A page that's linked only from the sitemap is a de-facto orphan. Filter your&lt;br&gt;
crawl for pages whose internal backlink count is zero, and you'll usually find&lt;br&gt;
a mix of old articles, staging pages, and forgotten product pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Check your homepage's link budget
&lt;/h2&gt;

&lt;p&gt;How many links does your homepage actually carry? A homepage bloated with&lt;br&gt;
hundreds of links (footer, mega-menu, "as seen on" badges, social icons)&lt;br&gt;
dilutes the signal it sends to your most important pages. If your money pages&lt;br&gt;
aren't in the top 20 links from the homepage, that's a signal problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Find pages nobody links to &lt;em&gt;with relevant anchor text&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Anchor text matters. A page that only ever receives "click here" and "read&lt;br&gt;
more" anchors is telling search engines nothing about its topic. Find pages&lt;br&gt;
whose internal anchors are generic, and add one or two descriptive, contextual&lt;br&gt;
links from related content. Natural anchors like "orphan page checker" or&lt;br&gt;
"free SEO tools" tell both users and engines what the target is about.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Verify your pillars actually point at each other
&lt;/h2&gt;

&lt;p&gt;If you use topic clusters, your pillar page should link to every cluster page,&lt;br&gt;
and (ideally) cluster pages should link back to the pillar. A quick crawl&lt;br&gt;
shows you which cluster members drifted out of the hub-and-spoke structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters more than new content
&lt;/h2&gt;

&lt;p&gt;Most sites don't need more pages — they need their existing pages to work&lt;br&gt;
together. Fixing internal linking is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free&lt;/strong&gt; — no ad spend, no tool licenses&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast&lt;/strong&gt; — most fixes are adding one contextual link&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compounding&lt;/strong&gt; — every fix improves how the whole site passes signal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run these five checks once a month. In two or three cycles, the pattern of&lt;br&gt;
links &lt;em&gt;between&lt;/em&gt; your pages will look like a site someone actually maintains —&lt;br&gt;
which is exactly what it should look like.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;All five checks above are built into &lt;a href="https://rankforge.cc" rel="noopener noreferrer"&gt;RankForge's free suite&lt;/a&gt; — crawler, orphan finder, and internal-link checker, no signup required.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>programming</category>
      <category>marketing</category>
    </item>
    <item>
      <title>5 Sites, 3,671 Internal Links, and 2% Editorial at Best</title>
      <dc:creator>Hermis</dc:creator>
      <pubDate>Mon, 07 Sep 2026 09:53:52 +0000</pubDate>
      <link>https://dev.to/hermis_rf/5-sites-3671-internal-links-and-2-editorial-at-best-5h8p</link>
      <guid>https://dev.to/hermis_rf/5-sites-3671-internal-links-and-2-editorial-at-best-5h8p</guid>
      <description>&lt;p&gt;Every internal-linking guide ends with the same instruction: add more internal links. On 2026-09-07 I checked whether that was actually the problem. I ran five sites through the free analyzer on my own SEO tool and looked at one thing — not how many internal links each site had, but what kind.&lt;/p&gt;

&lt;p&gt;None of them was short on links. Between them, 3,671 internal links on the crawled pages. The share classified as &lt;strong&gt;editorial&lt;/strong&gt; — a link written inside body copy, pointing somewhere specific — topped out at 2%. On three of the five it rounded to zero.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I ran
&lt;/h2&gt;

&lt;p&gt;No account needed, so this is reproducible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;POST https://rankforge.cc/api/analyzer&lt;/code&gt; with &lt;code&gt;{"seed_url": "..."}&lt;/code&gt;, then poll &lt;code&gt;GET /api/analyzer/&amp;lt;id&amp;gt;&lt;/code&gt; until &lt;code&gt;status&lt;/code&gt; is &lt;code&gt;completed&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Anonymous tier, which caps each crawl at 10 pages. Every run came back with &lt;code&gt;crawl_complete: false&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Five seeds, all run on 2026-09-07: &lt;code&gt;ahrefs.com/blog&lt;/code&gt;, &lt;code&gt;css-tricks.com&lt;/code&gt;, &lt;code&gt;kubernetes.io/docs/home&lt;/code&gt;, &lt;code&gt;rankforge.cc&lt;/code&gt;, &lt;code&gt;www.thestackanalyst.com&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The 10-page cap matters, so I'm putting it up front rather than in a footnote. This is a sample of the pages nearest each seed — the homepage or hub, plus what it links to first. It is the top of a site, not the whole site.&lt;/p&gt;

&lt;p&gt;That cuts in an interesting direction, though. The top of a site is where internal linking is supposed to be strongest and most deliberate. It's the friendliest place to go looking for editorial links, not the harshest.&lt;/p&gt;

&lt;p&gt;The classifier sorts every internal link into four buckets: &lt;strong&gt;editorial&lt;/strong&gt; (inside body content), &lt;strong&gt;navigational&lt;/strong&gt; (menus, headers, breadcrumbs), &lt;strong&gt;list&lt;/strong&gt; (archive and card grids), and &lt;strong&gt;boilerplate&lt;/strong&gt; (footers and other site-wide furniture).&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Site&lt;/th&gt;
&lt;th&gt;Internal links&lt;/th&gt;
&lt;th&gt;Editorial&lt;/th&gt;
&lt;th&gt;Navigational&lt;/th&gt;
&lt;th&gt;List&lt;/th&gt;
&lt;th&gt;Boilerplate&lt;/th&gt;
&lt;th&gt;Nav-sat.&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ahrefs.com/blog&lt;/td&gt;
&lt;td&gt;1,276&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;35.6%&lt;/td&gt;
&lt;td&gt;31.2%&lt;/td&gt;
&lt;td&gt;33.2%&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;css-tricks.com&lt;/td&gt;
&lt;td&gt;59&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;83.1%&lt;/td&gt;
&lt;td&gt;16.9%&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;kubernetes.io/docs&lt;/td&gt;
&lt;td&gt;1,335&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;95.4%&lt;/td&gt;
&lt;td&gt;4.6%&lt;/td&gt;
&lt;td&gt;0%&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rankforge.cc&lt;/td&gt;
&lt;td&gt;503&lt;/td&gt;
&lt;td&gt;0.6%&lt;/td&gt;
&lt;td&gt;14.3%&lt;/td&gt;
&lt;td&gt;9.9%&lt;/td&gt;
&lt;td&gt;75.1%&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;thestackanalyst.com&lt;/td&gt;
&lt;td&gt;498&lt;/td&gt;
&lt;td&gt;2%&lt;/td&gt;
&lt;td&gt;74.7%&lt;/td&gt;
&lt;td&gt;22.7%&lt;/td&gt;
&lt;td&gt;0.6%&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqtkwcrtdzbf21g5icpnv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqtkwcrtdzbf21g5icpnv.png" alt="Internal link composition across five sites: editorial links are a sliver on every one" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Four of five sites got flagged for weak internal linking. All five had plenty of links. None had many editorial ones.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not one of these sites had an orphan page in the crawled sample — all five report &lt;code&gt;orphan_pages_count: 0&lt;/code&gt;. Four of the five still got "Internal Link Strategy" flagged as their primary bottleneck.&lt;/p&gt;

&lt;h2&gt;
  
  
  Navigational links can't tell your pages apart
&lt;/h2&gt;

&lt;p&gt;This is the part that changed how I read internal-link reports.&lt;/p&gt;

&lt;p&gt;A menu link appears on every page and points at the same handful of destinations. In a PageRank-style model, that's a dense, near-uniform block of edges. It moves authority around, but it moves it the same way for everybody, so it can't express a preference. It has no opinion about which of your pages deserves to rank.&lt;/p&gt;

&lt;p&gt;Editorial links are the only ones that carry an opinion. Somebody writing a paragraph decided &lt;em&gt;this&lt;/em&gt; page was worth pointing at from &lt;em&gt;that&lt;/em&gt; sentence. That's the signal.&lt;/p&gt;

&lt;p&gt;When the navigational block dominates, the analyzer sets &lt;code&gt;nav_saturated: true&lt;/code&gt; — and then warns you about its own output:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Navigation/footer links reach nearly every page, so authority differences between pages are largely structural (a byproduct of the menu), not a reliable signal of which pages are strategically under-supported.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I like tools that do this. A per-page "authority score" on a nav-saturated site is mostly measuring your template. Ranking your pages by it and "fixing" the bottom five is chasing a menu.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it looks like on my own site
&lt;/h2&gt;

&lt;p&gt;My own site came out worst on composition: 75.1% boilerplate, 0.6% editorial. That's a footer doing the work that body copy should be doing.&lt;/p&gt;

&lt;p&gt;The analyzer proposed 7 specific in-body placements, each with a source page, a target, an anchor, and the sentence to put it in. It also simulates the result:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Links modeled&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total authority before&lt;/td&gt;
&lt;td&gt;922.34&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total authority after&lt;/td&gt;
&lt;td&gt;922.34&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;/docs/authority-flow&lt;/code&gt; before&lt;/td&gt;
&lt;td&gt;22.34&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;/docs/authority-flow&lt;/code&gt; after&lt;/td&gt;
&lt;td&gt;77.66 (+247.7%)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pages gaining&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pages losing&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The two numbers I'd underline are the identical totals. Internal linking creates no authority. It's redistribution: one page went up 55 points, nine went down an average of 6.2 each. That's a fine trade when you know which page you want to win, and a pointless shuffle when you don't.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/docs/authority-flow&lt;/code&gt; was sitting at 22.34 on a site whose median page scores 98.93. It was reachable, indexable, in the footer — and structurally invisible.&lt;/p&gt;

&lt;h2&gt;
  
  
  The outlier worth looking at
&lt;/h2&gt;

&lt;p&gt;Kubernetes docs is the extreme case: 95.4% navigational, and the docs sidebar is doing essentially all of the linking. Its homepage holds 49% of the internal authority in the sample and the median page sits at 11.57.&lt;/p&gt;

&lt;p&gt;That is not a bug in their docs. A giant navigation tree is the correct interface for reference documentation, and their readers arrive from search on a specific page anyway. It's a good reminder that "editorial links are low" is a finding, not automatically a defect — the question is whether the pages you actually care about are getting any differentiation at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check yours in about two minutes
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. queue a crawl (anonymous, no signup)&lt;/span&gt;
&lt;span class="nv"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://rankforge.cc/api/analyzer &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"seed_url":"https://example.com/"}'&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; .id&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# 2. poll until it finishes&lt;/span&gt;
&lt;span class="k"&gt;until&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://rankforge.cc/api/analyzer/&lt;span class="nv"&gt;$ID&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; .status&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"completed"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;sleep &lt;/span&gt;10
&lt;span class="k"&gt;done&lt;/span&gt;

&lt;span class="c"&gt;# 3. the only number this post is about&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://rankforge.cc/api/analyzer/&lt;span class="nv"&gt;$ID&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  | jq &lt;span class="s1"&gt;'.summary_metrics.link_quality | del(.pages_with_only_boilerplate_links)'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Real output from the &lt;code&gt;thestackanalyst.com&lt;/code&gt; run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"editorial_pct"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"navigational_pct"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;74.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"boilerplate_pct"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"list_pct"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;22.7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"total_internal_links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;498&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser version of the same crawl lives at &lt;a href="https://rankforge.cc/audit" rel="noopener noreferrer"&gt;rankforge.cc/audit&lt;/a&gt; if you'd rather not shell out for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'm doing about it
&lt;/h2&gt;

&lt;p&gt;Three changes, in the order I'd rank them:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Stop treating link count as the metric.&lt;/strong&gt; 503 internal links and 0.6% editorial is a worse position than 60 links with 20 of them written on purpose.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read &lt;code&gt;nav_saturated&lt;/code&gt; before reading any per-page score.&lt;/strong&gt; If it's true, per-page authority deltas are template noise and the ranked "weak pages" list is not a to-do list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write the links into the prose.&lt;/strong&gt; Not a related-posts widget, not another footer column — a sentence that earns the link. That's the only bucket a template can't fake for you.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Run it on your own site and drop your &lt;code&gt;editorial_pct&lt;/code&gt; in the comments. Mine was 0.6%, and I build SEO tooling for a living — I'd like to know whether I'm the outlier or the norm.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Crawls run 2026-09-07 via the public RankForge analyzer API, anonymous tier, 10 pages per site. Raw JSON for all five runs is saved alongside this post; every figure above comes from &lt;code&gt;summary_metrics&lt;/code&gt; in those files.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>programming</category>
      <category>datascience</category>
    </item>
    <item>
      <title>I Crawled a Real Site With a Free Crawler and Found 2 Invisible Pages</title>
      <dc:creator>Hermis</dc:creator>
      <pubDate>Sun, 06 Sep 2026 16:04:31 +0000</pubDate>
      <link>https://dev.to/hermis_rf/i-crawled-a-real-site-with-a-free-crawler-and-found-2-invisible-pages-380i</link>
      <guid>https://dev.to/hermis_rf/i-crawled-a-real-site-with-a-free-crawler-and-found-2-invisible-pages-380i</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/assets%2Fcover_crawl_orphans.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/assets%2Fcover_crawl_orphans.png" alt="Cover — 2 orphan pages found with a free crawler" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I spent about fifteen minutes on Monday crawling a site I don't own: &lt;code&gt;thestackanalyst.com&lt;/code&gt;, a small independent SEO-tools blog. Not a client, not a competitor — I picked it because it's the kind of site most of us actually run. WordPress, a few dozen posts, one person maintaining it.&lt;/p&gt;

&lt;p&gt;I wanted to answer one question with real data instead of vibes: &lt;strong&gt;if you crawl a small site with free tooling, what do you actually catch?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The answer, in this case: two orphan pages, one dead outbound link, and zero broken internal links. That last part matters — this site is in good shape. The point of this post isn't "look at this broken site." It's the method, run against a real example, so you can point it at your own domain this week.&lt;/p&gt;

&lt;h2&gt;
  
  
  The method: three steps, no paid tools
&lt;/h2&gt;

&lt;p&gt;Every step here is something you can do with a free crawler and a spreadsheet. I used the free crawler at &lt;code&gt;rankforge.cc&lt;/code&gt;, but the technique is tool-agnostic — anything that will fetch your URLs and record internal links works.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 — Crawl from the homepage
&lt;/h3&gt;

&lt;p&gt;Start at the root and let the crawler follow internal links until it runs out. This gives you the set of pages that are &lt;em&gt;reachable by following links&lt;/em&gt;. That distinction is the whole trick.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2 — Diff that set against your sitemap
&lt;/h3&gt;

&lt;p&gt;Your sitemap is the set of pages you &lt;em&gt;say&lt;/em&gt; exist. Your crawl is the set of pages a crawler can &lt;em&gt;find by walking your site&lt;/em&gt;. Anything in the sitemap but not in the crawl is an orphan: live, indexable, and structurally invisible. The diff, on this site:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ crawl https://www.thestackanalyst.com | diff - sitemap.xml

&amp;gt; https://www.thestackanalyst.com/seo-tools     (0 internal links pointing at it)
&amp;gt; https://www.thestackanalyst.com/text-tools    (0 internal links pointing at it)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both lines exist in the sitemap. Neither appears as the target of a single internal link anywhere in the crawl.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 — Check link statuses, internal and outbound
&lt;/h3&gt;

&lt;p&gt;Same crawl, one extra pass. Internal 404s are self-inflicted damage. Outbound dead links are a different opportunity entirely — more on that at the end.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the crawl actually found
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/assets%2Fdiagram_crawl_vs_sitemap.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/assets%2Fdiagram_crawl_vs_sitemap.png" alt="Crawl vs sitemap — the two orphan pages live in the sitemap-only zone" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hard numbers, no rounding up:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;URLs fetched (crawl)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;200&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP 200 responses&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;197&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Non-200&lt;/td&gt;
&lt;td&gt;2× &lt;code&gt;wp-json&lt;/code&gt; oEmbed (400), 1× &lt;code&gt;xmlrpc.php&lt;/code&gt; (403) — WP infrastructure, not user pages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sitemap URLs declared&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;62&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Broken internal links&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;0&lt;/strong&gt; (beyond those two WP endpoints)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Homepage internal links&lt;/td&gt;
&lt;td&gt;53&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Homepage external links&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Orphan pages&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;2: &lt;code&gt;/seo-tools&lt;/code&gt; and &lt;code&gt;/text-tools&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Outbound links checked (Top 100 listicle)&lt;/td&gt;
&lt;td&gt;134, exactly &lt;strong&gt;1 dead&lt;/strong&gt; (&lt;code&gt;keywordshitter.com&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Both orphans return HTTP 200. Both are in the sitemap. And across the entire 200-URL crawl — homepage, blog index, every post — &lt;strong&gt;zero internal links point to either one.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They're tool-hub pages. Someone built them, published them, submitted them in the sitemap, and never got around to wiring them into the nav.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;They're two doors with no hallway leading to them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I want to be completely fair here: this is exactly what almost every site looks like, mine included. Two orphans and no broken internal links on a site this size is a &lt;em&gt;healthy&lt;/em&gt; result. The site owner is doing fine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why orphans are worth caring about
&lt;/h2&gt;

&lt;p&gt;Three practical reasons, no statistics required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No internal anchor text signals.&lt;/strong&gt; Every internal link is a small statement about what a page is about. An orphan has none. Google has to guess from the page alone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Discovery depends entirely on the sitemap.&lt;/strong&gt; A sitemap is a hint, not a guarantee. When it's the &lt;em&gt;only&lt;/em&gt; path to a page, you've removed every redundancy from that page's discoverability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Link equity can't flow to it.&lt;/strong&gt; That homepage with 53 internal links is distributing authority across the site. Orphans get zero of it, forever, no matter how good they are.&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;/seo-tools&lt;/code&gt; and &lt;code&gt;/text-tools&lt;/code&gt;, the sting is that these are hub pages — the page type that &lt;em&gt;should&lt;/em&gt; be collecting internal links from every relevant post and passing authority down to individual tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do with each orphan
&lt;/h2&gt;

&lt;p&gt;Don't reflexively delete. Run the page through three questions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it good and still relevant?&lt;/strong&gt; → &lt;strong&gt;Link it in.&lt;/strong&gt; Not a footer dump — footer links are weak and readers ignore them. Put it in the main nav if it's a hub, and add contextual in-body links from the two or three posts most related to it. For &lt;code&gt;/seo-tools&lt;/code&gt;, that means linking it from every post that mentions an SEO tool. Anchor text should describe the destination, not say "click here."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it redundant with a stronger page?&lt;/strong&gt; → &lt;strong&gt;301 redirect&lt;/strong&gt; it to that stronger page and fold any unique content in. Neither thin page beats one solid page — merge them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it necessary but not search-worthy?&lt;/strong&gt; (thank-you pages, filtered views, internal utilities) → &lt;strong&gt;&lt;code&gt;noindex&lt;/code&gt;, and remove it from the sitemap.&lt;/strong&gt; An orphan you &lt;em&gt;intend&lt;/em&gt; to be an orphan isn't a bug — but it shouldn't be sitting in your sitemap sending mixed signals.&lt;/p&gt;

&lt;p&gt;The failure mode to avoid: leaving a page indexable, sitemapped, and unlinked.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bonus you get for free: outbound link rot
&lt;/h2&gt;

&lt;p&gt;Same crawl, extra pass. I checked the outbound links on their big "Top 100 Free SEO Tools" listicle — &lt;strong&gt;134 tool links checked&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exactly one was dead: &lt;code&gt;keywordshitter.com&lt;/code&gt;&lt;/strong&gt; (yes, real tool, real name — Dan Shure's free keyword tool). It timed out across http, https, and www variants. The other 133 resolved fine — for a listicle that size, a genuinely good ratio. But a dead link in a "here are the tools" post is a bad reader experience, and it's the kind of thing an author never notices because nobody re-clicks their own links.&lt;/p&gt;

&lt;p&gt;Here's why this is worth your time beyond tidiness: &lt;strong&gt;it's the most honest outreach angle there is.&lt;/strong&gt; You email the editor, name the dead link sitting in their list, and suggest a live alternative that does the same job. No pitch, no "I noticed you link to X, would you consider linking to me" dance. You're doing unpaid editorial QA on their most important page. Sometimes you get a link out of it. Often you just get a reply from a real person, which is worth more than most cold outreach ever produces.&lt;/p&gt;

&lt;p&gt;Run this against any listicle in your niche and you'll find candidates — roundup posts rot constantly, and tools die quietly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fifteen minutes, this week
&lt;/h2&gt;

&lt;p&gt;That's the whole exercise. One crawl, one sitemap diff, one link-status pass. Two orphan pages surfaced, one dead outbound link found, and a clean bill of health confirmed on everything else — on a site I'd never touched before.&lt;/p&gt;

&lt;p&gt;You almost certainly have orphans right now. Not because you're careless, but because sites accumulate pages faster than they accumulate links. This one had two. Yours almost certainly has at least one.&lt;/p&gt;

&lt;p&gt;If you want the fast version of step 2, the &lt;a href="https://rankforge.cc/tools/orphan-page-checker" rel="noopener noreferrer"&gt;orphan page checker&lt;/a&gt; does the crawl-versus-sitemap diff for you and hands you the list. Then work the three questions above on each result: link it, redirect it, or noindex it.&lt;/p&gt;

&lt;p&gt;Then go check that one listicle you keep linking to. I'd bet something on it is dead.&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Internal Linking Audit: 5 Free Checks That Take 5 Minutes</title>
      <dc:creator>Hermis</dc:creator>
      <pubDate>Mon, 31 Aug 2026 08:13:09 +0000</pubDate>
      <link>https://dev.to/hermis_rf/internal-linking-audit-5-free-checks-that-take-5-minutes-14p7</link>
      <guid>https://dev.to/hermis_rf/internal-linking-audit-5-free-checks-that-take-5-minutes-14p7</guid>
      <description>&lt;p&gt;Internal links are the plumbing of your site. They tell search engines what&lt;br&gt;
matters, spread ranking signals between pages, and — more practically — they&lt;br&gt;
are the single biggest &lt;em&gt;free&lt;/em&gt; lever most sites ignore. Here are five checks&lt;br&gt;
you can run right now with free tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Find orphan pages
&lt;/h2&gt;

&lt;p&gt;Any page with zero internal links pointing to it is an orphan. It might be&lt;br&gt;
indexed (if an external link found it), but it's getting no internal signal,&lt;br&gt;
and it's invisible to your own navigation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The check:&lt;/strong&gt; crawl your site and diff the discovered URLs against your&lt;br&gt;
sitemap/CMS export. Every URL in the export that the crawl never saw is an&lt;br&gt;
orphan. &lt;a href="https://rankforge.cc" rel="noopener noreferrer"&gt;RankForge's free crawler&lt;/a&gt; does the diff for you&lt;br&gt;
in one step.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Count how many pages have no internal links &lt;em&gt;at all&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;A page that's linked only from the sitemap is a de-facto orphan. Filter your&lt;br&gt;
crawl for pages whose internal backlink count is zero, and you'll usually find&lt;br&gt;
a mix of old articles, staging pages, and forgotten product pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Check your homepage's link budget
&lt;/h2&gt;

&lt;p&gt;How many links does your homepage actually carry? A homepage bloated with&lt;br&gt;
hundreds of links (footer, mega-menu, "as seen on" badges, social icons)&lt;br&gt;
dilutes the signal it sends to your most important pages. If your money pages&lt;br&gt;
aren't in the top 20 links from the homepage, that's a signal problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Find pages nobody links to &lt;em&gt;with relevant anchor text&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Anchor text matters. A page that only ever receives "click here" and "read&lt;br&gt;
more" anchors is telling search engines nothing about its topic. Find pages&lt;br&gt;
whose internal anchors are generic, and add one or two descriptive, contextual&lt;br&gt;
links from related content. Natural anchors like "orphan page checker" or&lt;br&gt;
"free SEO tools" tell both users and engines what the target is about.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Verify your pillars actually point at each other
&lt;/h2&gt;

&lt;p&gt;If you use topic clusters, your pillar page should link to every cluster page,&lt;br&gt;
and (ideally) cluster pages should link back to the pillar. A quick crawl&lt;br&gt;
shows you which cluster members drifted out of the hub-and-spoke structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters more than new content
&lt;/h2&gt;

&lt;p&gt;Most sites don't need more pages — they need their existing pages to work&lt;br&gt;
together. Fixing internal linking is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free&lt;/strong&gt; — no ad spend, no tool licenses&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast&lt;/strong&gt; — most fixes are adding one contextual link&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compounding&lt;/strong&gt; — every fix improves how the whole site passes signal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run these five checks once a month. In two or three cycles, the pattern of&lt;br&gt;
links &lt;em&gt;between&lt;/em&gt; your pages will look like a site someone actually maintains —&lt;br&gt;
which is exactly what it should look like.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;All five checks above are built into &lt;a href="https://rankforge.cc" rel="noopener noreferrer"&gt;RankForge's free suite&lt;/a&gt; — crawler, orphan finder, and internal-link checker, no signup required.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Crawled My Own SEO Site and Found a Crawler Trap</title>
      <dc:creator>Hermis</dc:creator>
      <pubDate>Sun, 30 Aug 2026 07:12:44 +0000</pubDate>
      <link>https://dev.to/hermis_rf/i-crawled-my-own-seo-site-and-found-a-crawler-trap-1boa</link>
      <guid>https://dev.to/hermis_rf/i-crawled-my-own-seo-site-and-found-a-crawler-trap-1boa</guid>
      <description>&lt;p&gt;I run a small SEO tooling site, and on 2026-08-24 I pointed my crawler at it. The plan was routine: check internal health, check for orphans, move on.&lt;/p&gt;

&lt;p&gt;The crawl returned zero orphan candidates. That result is why I'm writing this. It wasn't proof that the site was perfect; the audit had asked the wrong question. The broken links were a false alarm, and the green "everything is fine" result was the real bug.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I ran, and what it actually measured
&lt;/h2&gt;

&lt;p&gt;The setup was deliberately plain, so anyone can reproduce the shape of it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Seed URL: &lt;code&gt;https://rankforge.cc&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Breadth-first traversal of internal links, respecting &lt;code&gt;robots.txt&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Requested page cap: 100&lt;/li&gt;
&lt;li&gt;1 second delay between requests&lt;/li&gt;
&lt;li&gt;Started 2026-08-24T09:04:12Z&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two details matter before the numbers. The requested cap was 100 but the script fetched 159 pages: after traversal, it performs bounded extra link checks. So "pages fetched" and "BFS budget" are different metrics.&lt;/p&gt;

&lt;p&gt;The bigger issue: the orphan check fetched &lt;code&gt;sitemap_index.xml&lt;/code&gt; and nothing else.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers
&lt;/h2&gt;

&lt;p&gt;Raw crawler output first, then a separate probe I ran immediately afterward. I'm keeping these visually separated on purpose, because mixing a tool's output with your own follow-up checks is how an audit quietly becomes fiction.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Crawl start time&lt;/td&gt;
&lt;td&gt;2026-08-24T09:04:12Z&lt;/td&gt;
&lt;td&gt;raw crawl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pages fetched&lt;/td&gt;
&lt;td&gt;159&lt;/td&gt;
&lt;td&gt;raw crawl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unique URLs queued&lt;/td&gt;
&lt;td&gt;158&lt;/td&gt;
&lt;td&gt;raw crawl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP 200&lt;/td&gt;
&lt;td&gt;147&lt;/td&gt;
&lt;td&gt;raw crawl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP 404&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;raw crawl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total internal links recorded&lt;/td&gt;
&lt;td&gt;4,883&lt;/td&gt;
&lt;td&gt;raw crawl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Homepage internal links&lt;/td&gt;
&lt;td&gt;53&lt;/td&gt;
&lt;td&gt;raw crawl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Homepage external links&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;raw crawl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Broken-link entries (source → target pairs)&lt;/td&gt;
&lt;td&gt;22&lt;/td&gt;
&lt;td&gt;raw crawl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unique broken targets&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;raw crawl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sitemap URLs seen by crawler&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;raw crawl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Orphan candidates reported&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;raw crawl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;robots.txt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HTTP 200&lt;/td&gt;
&lt;td&gt;direct probe, immediately after crawl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sitemap_index.xml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HTTP 404&lt;/td&gt;
&lt;td&gt;direct probe, immediately after crawl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sitemap.xml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HTTP 200, 142 &lt;code&gt;&amp;lt;loc&amp;gt;&lt;/code&gt; entries&lt;/td&gt;
&lt;td&gt;direct probe, immediately after crawl&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;robots.txt&lt;/code&gt; disallowed ten app prefixes, including &lt;code&gt;/api/&lt;/code&gt;, &lt;code&gt;/dashboard/&lt;/code&gt;, and &lt;code&gt;/search-performance/&lt;/code&gt;. A robots-aware crawl correctly stayed out of them; compare that boundary with the sitemap before judging coverage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1yfaohi3am8mo9d7hp9r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1yfaohi3am8mo9d7hp9r.png" alt="Diagram: crawler checks sitemap_index.xml, gets 404, reports zero sitemap URLs and therefore zero orphan candidates; the live sitemap.xml with 142 URLs is never compared" width="799" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The false alarm: 12 broken links that aren't broken links
&lt;/h2&gt;

&lt;p&gt;Twelve 404s on a 159-page crawl looks like a real finding. It wasn't. Every single one was a Cloudflare email-obfuscation URL under &lt;code&gt;/cdn-cgi/l/email-protection&lt;/code&gt;, linked from &lt;code&gt;/contact&lt;/code&gt;, &lt;code&gt;/pricing&lt;/code&gt;, &lt;code&gt;/privacy&lt;/code&gt;, &lt;code&gt;/terms&lt;/code&gt;, &lt;code&gt;/security&lt;/code&gt;, and &lt;code&gt;/docs/crawler&lt;/code&gt;. Cloudflare rewrites mailto links into that endpoint plus a hex-encoded fragment; browser JavaScript decodes it back into an address. A plain HTTP fetch of that path is supposed to fail. The site is behaving exactly as configured.&lt;/p&gt;

&lt;p&gt;The 22-versus-12 gap is another small lesson: the crawler logs one entry per source→target pair, and ten entries recorded the source as &lt;code&gt;?&lt;/code&gt; because the target was found during the bounded extra-check phase. The same obfuscated addresses were counted from multiple pages. Reporting "22 broken links" would inflate a non-issue by nearly 2x.&lt;/p&gt;

&lt;p&gt;The rule for any crawler: put infrastructure URLs in their own bucket. &lt;code&gt;/cdn-cgi/*&lt;/code&gt;, analytics beacons, tracking pixels, and &lt;code&gt;mailto:&lt;/code&gt;/&lt;code&gt;tel:&lt;/code&gt; rewrites should be reported separately from content 404s. Dropping them hides regressions; mixing them into the headline trains you to ignore the report.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real trap: &lt;code&gt;sitemap_index.xml&lt;/code&gt; vs &lt;code&gt;sitemap.xml&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Here's the part that actually cost me something.&lt;/p&gt;

&lt;p&gt;The orphan check works by diffing pages found in the sitemap against pages reached by crawling internal links. Anything in the sitemap but unreachable by link is an orphan candidate. Sound logic — and it depends entirely on having a sitemap to diff against.&lt;/p&gt;

&lt;p&gt;My crawler only requested &lt;code&gt;sitemap_index.xml&lt;/code&gt;. That's the WordPress/Yoast convention, and it's a reasonable default if you mostly audit WordPress sites. On my own site that URL is a 404. So the crawler recorded &lt;code&gt;sitemap_url_count: 0&lt;/code&gt;, diffed 158 crawled URLs against an empty set, and reported zero orphan candidates.&lt;/p&gt;

&lt;p&gt;Zero orphans was structurally impossible to avoid. The check couldn't have found anything.&lt;/p&gt;

&lt;p&gt;The direct probe immediately afterward got &lt;code&gt;https://rankforge.cc/sitemap.xml&lt;/code&gt; at HTTP 200 with 142 &lt;code&gt;&amp;lt;loc&amp;gt;&lt;/code&gt; entries. There was a sitemap the whole time — the audit just never looked at it. Note carefully what this does and does not tell you: it does &lt;strong&gt;not&lt;/strong&gt; mean the site has no sitemap, and the zero result does &lt;strong&gt;not&lt;/strong&gt; mean the site has no orphans. It means the orphan check never ran. Those 142 URLs versus 158 crawled URLs is a diff I still owe myself, and the overlap is not something you can eyeball from the counts alone.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If your tool can't distinguish "I looked and found none" from "I couldn't look," every clean report is ambiguous.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The corrected workflow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. crawl internal links from seed, robots-aware, record every URL + status
2. fetch robots.txt, parse ALL "Sitemap:" directives
3. if none: try /sitemap.xml AND /sitemap_index.xml AND /sitemap-index.xml
4. for each sitemap found:
     if it is an index -&amp;gt; recurse into every child &amp;lt;loc&amp;gt;
     else -&amp;gt; collect every &amp;lt;loc&amp;gt;
5. FAIL LOUDLY if total sitemap URL count == 0
     (do not emit "0 orphans" — emit "sitemap not discovered")
6. normalize both sets: scheme, host, trailing slash, case,
   strip fragments, decide on query params explicitly
7. diff: sitemap_urls - crawled_urls = orphan candidates
8. verify each candidate: fetch it, confirm 200, confirm no internal
   link actually points to it, check it isn't robots-disallowed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 5 is the whole fix. An empty discovery set must be an error state, never an input to a diff. Step 6 is where most homegrown orphan checkers leak false positives — &lt;code&gt;https://site.com/page&lt;/code&gt; and &lt;code&gt;https://site.com/page/&lt;/code&gt; are the same page to you and different strings to a set difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  What 4,883 internal links actually tell me
&lt;/h2&gt;

&lt;p&gt;Not much about quality, and I want to be honest about that. 4,883 internal links across 159 pages averages ~31 links per page, which mostly reflects a shared header, footer, and nav. The homepage's 53 internal links and 2 external links are the same story: that's template, not editorial linking.&lt;/p&gt;

&lt;p&gt;Link count is a volume metric. It says nothing about anchor relevance, placement, or whether a page has inbound links beyond the global nav. The crawl flagged the homepage as the only page with zero inbound internal links — an artifact of it being the BFS seed, not a finding.&lt;/p&gt;

&lt;p&gt;So the next passes are specific: strip nav/footer links and recount in-body links only; check which of the 142 sitemap URLs are reachable only through nav; and run the corrected sitemap diff before I make any claim about orphans at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;The dramatic result (12 broken links) was noise; the boring result (0 orphans) was the bug. When an audit returns nothing, ask whether the check ran. Then use the &lt;a href="https://rankforge.cc/tools/orphan-page-checker" rel="noopener noreferrer"&gt;orphan page checker&lt;/a&gt;, while confirming which sitemap was fetched, how many &lt;code&gt;&amp;lt;loc&amp;gt;&lt;/code&gt; entries it returned, and whether 404s are content or infrastructure.&lt;/p&gt;

&lt;p&gt;Ever shipped a "clean" audit that was actually blind, not clean? Drop it below.&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
