We run iphoneduosupport.com, a technical reference site for adapting iOS apps to Apple’s foldable. It ranks on Google. This post is the architecture that did it.
A caveat up front, because it is the part most posts like this get wrong: there are no traffic screenshots here. Analytics images prove very little — they are trivially cherry-picked by date range. What is independently checkable is the architecture itself, and you can verify every claim below by viewing source on that site right now. So that is what we are documenting.
The core idea: one page per search intent
The single most common structural mistake is putting many distinct questions on
one page. A hub page covering a dozen topics has one <title>, so it matches all
twelve queries weakly and none of them well.
That site is 67 indexable URLs, arranged as hubs with long-tail spokes:
| Hub | Spokes | Intent captured |
|---|---|---|
/checklist/ |
25 individual item pages | “how do I fix X” |
/faq/ |
13 individual answer pages | question queries, People Also Ask |
/frameworks/ |
6 framework guides | “framework + device” |
/blog/ |
9 posts | comparison and analysis |
Each spoke targets one specific query, and its <title> is that query. A page
whose title matches the search can show its answer in the snippet, which is also
what makes it eligible for People Also Ask placement.
The FAQ section is the clearest demonstration: it started as a single hub carrying a dozen questions behind an accordion. Splitting it into one page per question was a deliberate change, and the reason it works is not subtle — twelve search intents now have twelve titles instead of sharing one.
Structured data that resolves to one entity
Most sites that emit JSON-LD emit it repeatedly and inconsistently: each page declares its own organisation, and search engines treat them as separate things.
Every page on that site emits a single @graph with stable @id anchors:
/#organization the company entity
/#author the author entity, parentOrganization -> /#organization
/#website the site entity, publisher -> /#organization
<url>#article this page, author/publisher/isPartOf -> the above by @id
Page-level nodes reference the global entities by @id rather than restating
them. Google then resolves one organisation across all 67 URLs instead of 67
candidate organisations. This site uses the identical pattern — view source and
you will see the same anchors.
Build-time enforcement, not a checklist
Documented SEO conventions decay. Enforced ones do not.
That site’s content schemas put hard limits on the fields that matter:
title: z.string().max(110),
description: z.string().min(60).max(165),
lastVerified: z.string().regex(/^\d{4}-\d{2}-\d{2}$/),
An out-of-range description fails the build. It is not a lint warning someone
can merge past. The same principle covers placeholder text: a script scans the
built output and fails if any TODO_ marker reached it, because a placeholder
statistic on a page meant to establish expertise is worse than an empty section.
Internal links pointed deliberately
The link graph is not incidental. Every blog post links up to its framework guide, with the reason recorded in a comment in the source: so the guide accumulates the internal links that decide which page Google ranks for framework queries.
Related posts are computed from tag overlap rather than curated by hand, so the graph stays dense as content is added without anyone maintaining a list.
Machine-readable mirrors for AI crawlers
Increasingly the traffic that matters is not a click from a results page, it is a citation inside an AI answer. That site ships:
/llms.txt— an orientation document, leading with a sourcing-and-reliability section that tells citing systems which claims are documented and which are inference/llms-full.txt— the whole corpus as plain text- A
.mdmirror of every page, advertised via<link rel="alternate" type="text/markdown"> - An explicit allowlist for about twenty AI crawlers in
robots.txt
The mirrors are excluded from the sitemap and carry X-Robots-Tag: noindex, so a
plain-text duplicate never competes with the HTML original.
Visible sourcing as an E-E-A-T system
Every page carries a lastVerified date, rendered on the page, and links to the
primary sources for its claims. Pages whose conclusions are our engineering
analysis rather than vendor documentation say so, in a visible notice, because the
distinction is the difference between a reference and a guess.
This is not decoration. For a site competing on technical accuracy, being checkable is the product.
What this does not tell you
This architecture gets pages indexed, correctly interpreted and internally linked. It does not manufacture demand: if nobody searches for your topic, a perfect information architecture returns nothing.
It also takes time. Technical changes land in weeks; ranking movement takes three to six months, because that is how long the index takes to reflect a changed site.
And it cannot be bolted on. The reason we rebuilt this site is that the previous
version was a React single-page app where every service sat behind a #fragment
on one route — and Google canonicalises fragments to the root. The whole site was
four indexable URLs. No amount of content would have fixed that; the architecture
was the ceiling.
If your site has that shape, that is the thing to fix first. We do that work as SEO and Google ranking.