Nakodo publishes 76 pages: 13 hand-built ones and 63 generated from a content registry. Every internal link in that registry is checked at build time, so I knew none of them were broken. I did not know anything about their shape: which pages collect links, which pages give them away, and whether a crawler arriving at the home page can reach everything.
So I built the graph. The method is four lines of shell and twenty of Python, and you can run it against any site with a sitemap.
Getting the edges
mkdir -p /tmp/site && cd /tmp/site curl -s https://nakodo.app/sitemap.xml \ | grep -o '<loc>[^<]*' | sed 's/<loc>//' > urls.txt while read -r u; do curl -s "$u" -o "$(echo "$u" | sed 's|https://nakodo.app||; s|^$|home|; s|/|_|g').html" done < urls.txt That is 36 MB of HTML for our site, most of it inline SVG. Then parse the anchors, and parse them twice: once over the whole document, once over the contents of <main> only. The difference between those two numbers is the entire point of the exercise, because a site-wide footer makes every page look well connected whether it is or not.
import re, collections body = open(path, encoding="utf-8").read() main = re.search(r"<main[^>]*>(.*?)</main>", body, re.S).group(1) hrefs = re.findall(r'<a\b[^>]*href="([^"]+)"', main) Totals first: 5,184 anchor tags across the 76 pages, of which 4,795 are internal and 389 point off the site. That is about 68 links on an average page.
The footer is doing the work
Our header carries 8 links and our footer carries 35, and the footer is byte-identical on all 76 pages:
/ /about /alternatives /blog /for/agencies /for/amazon-sellers /for/ecommerce-brands /for/indie-game-studios /for/mobile-apps /for/saas /for/shopify-stores /for/small-businesses /glossary /guides /guides/how-much-to-pay-youtubers /guides/how-to-find-a-youtubers-email /guides/how-to-find-instagram-influencers /guides/how-to-find-tiktok-influencers /guides/how-to-find-youtube-influencers /how-it-works /instagrammers /login /login?mode=signup /pricing /privacy /terms /tiktokers /tools/engagement-rate-calculator /tools/instagram-engagement-rate-calculator /tools/sponsorship-cost-calculator /tools/tiktok-engagement-rate-calculator /youtubers /youtubers/beauty /youtubers/gaming /youtubers/tech 43 of the 68 links on a page are that chrome. Walk the full graph from the home page and the site is as flat as a site can be: 32 pages at one click, 43 at two, nothing further away. Nothing is unreachable.
Now delete the header and the footer from the data and walk it again, using only links inside <main>, the ones somebody wrote on purpose:
| clicks from home | pages |
|---|---|
| 1 | 6 |
| 2 | 26 |
| 3 | 20 |
| 4 | 2 |
| no editorial route at all | 21 |
Those 21 pages are three whole branches of the site: every Instagram and TikTok niche page, all four alternatives pages, and five of the eight audience pages. Google will find them, because the footer links them from everywhere. A reader following the writing will not, which is a different and worse problem: those pages are not part of any argument the site makes.
Three pages that nothing links to
Counting only links inside <main>, 682 edges connect the 76 pages, and the in-degree distribution is lopsided:
| page | in-links from other pages' bodies |
|---|---|
| /how-it-works | 72 of 75 possible |
| / | 71 |
| /guides | 28 |
| /glossary | 23 |
| /guides/how-much-to-pay-youtubers | 22 |
| /pricing | 20 |
Counting every occurrence rather than every page, /how-it-works is linked 299 times across the site. It is the page that explains the product, every page eventually points at it, and I am happy about that.
The other end of the table is the finding. The eight audience pages, by body in-links:
/for/ecommerce-brands 7 /for/small-businesses 4 /for/saas 3 /for/amazon-sellers 1 /for/shopify-stores 1 /for/agencies 0 /for/indie-game-studios 0 /for/mobile-apps 0 Nothing in the body of any page on this site links to those last three. They were written in the same batch as the others, from the same template, with the same cross-link fields available, and the difference is simply that the earlier pages got woven into the guides as the guides were written and the later ones were published and forgotten.
There is a test that every internal link in the registry resolves to a real page. There is nothing that asserts the reverse: that every page is the target of at least one editorial link. That test is about four lines, it would have failed on the day those pages shipped, and it is the next thing I am adding.
Reciprocity, and the pages that give nothing back
Of the 682 edges, 285 are reciprocal: 41.8 percent of the time, if A links to B then B links back to A. That is higher than I expected, and it comes from the registry's "read next" field: when two pages are written in the same sitting, each one gets pointed at the other, so the reciprocal pairs are a fossil record of which pages were drafted together.
Out-degree is where the hand-built pages give themselves away:
/guides 30 links out /youtubers 16 /glossary 16 ... /about 4 /pricing 3 /terms 2 /privacy 1 The privacy notice has exactly one body link, and it goes to the terms. That is correct, not a gap. A legal page that funnels you into the product is a legal page somebody will not trust, and both of those pages are deliberately dead ends.
The 389 links that leave
45 distinct hosts, 18 of them linked exactly once. The top of the list is www.youtube.com (78), then Instagram's help centre (37), then four competitors.
Every one of those links is rendered by the registry's link component, which gives it the same two attributes:
<a href="https://..." rel="noopener noreferrer" target="_blank"> 385 of 389 have exactly that pair. The other four are all on the about page, and they are the links to our sibling apps. The about page is one of the 13 hand-built pages, so its links are hand-written <a> tags that never pass through the component, and four hand-written anchors are missing the attributes that 385 generated ones have. No harm in these four cases, since they go to our own domains, but it is a clean illustration of why the generated pages are easier to trust than the hand-written ones.
What you will not find anywhere in those 389 links is rel="nofollow". The four alternatives pages carry 103 external links between them, 97 of which point at the four competitors' own websites, all followable. A comparison page that will not link to the thing it compares is not a comparison, it is an advert, and UK advertising rules on comparative claims are strict enough that I would rather the reader could check every line against the source in one click.
Worth running on your own site
Three numbers came out of this that I would not have guessed:
- Full-graph depth said the site was perfect. Body-only depth said a quarter of it is orphaned. Any crawl report that counts footer links will tell you the first story.
- The in-degree of a page is a record of the order it was written in, not of how important it is.
- The pages generated from a registry were uniformly correct. The handful of pages written by hand held every exception, in a site where the hand-written pages are 17 percent of the total and 100 percent of the attribute mistakes.
The pages are all public, so if you want to check the figures, start with sitemap.xml and the shell above.

