Programmatic SEO template: shared blocks vs unique page data
Learn how to split a programmatic SEO template into shared and per-page blocks, measure uniqueness, and gate thin pages before they reach Google's index.
A programmatic SEO template has two layers. The shared layer is the layout, navigation, design and calls to action, and it can be identical on every page. The per-page layer is the data points, comparison tables, maps, computed facts and reviews, and it has to carry the page on its own. When the shared layer is most of what a reader sees, the page sits close to what Google calls scaled content abuse. This post covers four things: how to split a template into blocks, how to measure how much of each rendered page is unique, which build gates keep thin pages out of the index, and when to skip a page entirely.
What are programmatic SEO pages?
They are pages generated at scale from one template plus a dataset. Each page targets a different long-tail query that follows the same pattern, such as “[app A] + [app B] integration” or “[currency] to [currency]” (Backlinko). If you want the longer overview with examples, I covered it in what programmatic SEO is and how it works.
Is programmatic SEO bad?
The method itself is allowed. Google’s spam policies target pages “generated for the primary purpose of manipulating search rankings and not helping users.” Using a template does not break that policy.
The track record is mixed, though. In September 2026 John Mueller said programmatic SEO “often leads to a site that’s either spam, borderline spam, or low quality,” and that Google’s systems may have “lost faith in your site providing good value to users based on the old pages” (Relevant Audience, from Search Engine Roundtable). He added that fixing it “tends to take time and significant effort.” The part to notice is the site-level effect. A bad template can drag down pages that were fine.
Glenn Gabe’s August 2026 spam update cases show what that looks like:
- Country-scaled pages padded with 100% AI text lost rankings for 200K+ queries.
- Affiliate pages with filler text flagged as 97%+ likely AI lost 14K+ queries.
- A site with 1.5M+ indexed URLs, about 85% programmatic, had pages with only “a photo and basic information found anywhere on the web.”
I went through the full 2026 update timeline in Is programmatic SEO dead?.
Which parts of a programmatic SEO template can be identical, and which must be unique?
Split the template into blocks and label each one shared or per-page.
| Block | Layer | Notes |
|---|---|---|
| Header, nav, footer | Shared | Same on every page is fine |
| Layout and design | Shared | Siege Media counts UX consistency as a strength |
| CTAs | Shared, with conditions | Backlinko recommends conditional logic so CTAs match the page’s data |
| Intro sentence with the entity name swapped in | Shared in practice | Does not count as unique |
| Data table, prices, ratings | Per-page | Carries the page |
| Comparisons and computed facts | Per-page | Carries the page |
| Map, chart | Per-page | Only if the underlying data differs |
| Reviews, UGC | Per-page | Only when they exist |
| Internal links | Per-page | Siege: “contextual, dynamic links related to that specific topic instead of being the same for all pages” |
Backlinko’s line on the swapped-name pattern is blunt: a city name dropped into otherwise identical text is “spam, not programmatic SEO.” Google’s doorway examples describe the same thing: “pages targeted at specific regions or cities that funnel users to one page.”
What template blocks add real per-page value?
Google wrote part of this list itself. In the thin affiliation section, it says affiliate sites add value through “price, original product reviews, rigorous testing and ratings, navigation of products or categories, and product comparisons.” The sites that rank at scale follow a similar pattern:
- Live rates and calculators. Wise runs about 8.5M currency converter pages according to Backlinko. Third-party estimates of its size vary widely, so treat all of them as tool estimates. Former marketing lead Fabrizio Ballarini describes the converter as a way to show users the hidden bank margin. Kraken uses live rates, calculators and charts the same way (Siege Media).
- Proprietary structured data. On Zapier integration pages, each app’s triggers and actions are what make the page unique, and they change often (Zapier).
- Reviews and location data. Tripadvisor’s “things to do in [city]” pages rank for about 100K keywords (Backlinko).
- Scoring on public data. NerdWallet adds proprietary scoring to public financial data (Omnius).
My test for any block: delete the entity name, then ask whether a reader could still tell which page they are on. If they could not, the block belongs to the shared layer.
How much unique content does a programmatic SEO page need?
Google has not published a number. Asked whether some percentage defines duplicate content, Mueller replied: “There is no number (also how do you measure it anyway?)” (Search Engine Journal).
The percentages that circulate come from other places:
- 30% and 40% come from a third-party Claude skill that warns below 40% unique words and hard-stops below 30% (Tessl registry).
- 50% has no source that I could find.
- 60% traces to Gary Illyes reportedly saying about 60% of the internet is duplicate (Gizchina). That is an observation about the web and has nothing to do with page thresholds.
Template word counts have the same problem. Backlinko suggests 500 to 1,000+ words. Omnius points out that tool pages such as Canva’s keep text light because the tool does the work. Google’s examples talk about value and never mention length.
Keep two ideas apart here. Mueller has said duplicate content carries no negative ranking score. Scaled content abuse is a separate thing: it is a spam policy, and it can act on the whole site.
How to measure uniqueness anyway
A percentage is still useful as an internal QA signal, as long as you don’t treat it as a Google target. I’d track two numbers on the rendered main content, with nav and footer excluded:
- Field share. The words rendered from page-specific fields, divided by the total words in the main content.
- Sibling similarity. Shingle overlap between a page and its nearest siblings, for example two pages in the same category.
The second number is closer to how near-duplicate detection works in practice. Google-affiliated researchers found 64-bit simhash fingerprints with k=3 workable across 8B pages (Manku et al., 2007). Google has not said whether Search uses that method today.
function shingles(text: string, k = 5): Set<string> {
const w = text.toLowerCase().split(/\s+/).filter(Boolean);
const out = new Set<string>();
for (let i = 0; i + k <= w.length; i++) out.add(w.slice(i, i + k).join(" "));
return out;
}
function similarity(a: string, b: string): number {
const A = shingles(a), B = shingles(b);
let inter = 0;
for (const s of A) if (B.has(s)) inter++;
return inter / (A.size + B.size - inter || 1);
}
Run it in CI on a sample of rendered pages. Any pair with high similarity is worth a manual look.
How do you stop thin pages from being published when data is missing?
Put the gates in the build so a thin page never reaches production. Google’s docs support three outcomes: generate the page, noindex it, or return a 404 / don’t generate it. The thresholds are yours to set. The values below are placeholders, loosely modelled on the codex-skills checks: field completeness, enough unique attributes, and a flag on records with “>80% field overlap.”
type Decision = "publish" | "noindex" | "skip";
const MIN_FIELDS = 6; // placeholder, tune per dataset
const MAX_SIBLING_OVERLAP = 0.8;
export function decide(record: Record<string, unknown>, siblingOverlap: number): Decision {
const filled = Object.values(record).filter(
(v) => v !== null && v !== "" && !(Array.isArray(v) && v.length === 0)
).length;
if (filled === 0) return "skip"; // 404, no URL, not in sitemap
if (filled < MIN_FIELDS) return "noindex"; // useful to users, too thin to index
if (siblingOverlap > MAX_SIBLING_OVERLAP) return "noindex";
return "publish";
}
At block level, render a block only when its data exists. Don’t fill the gap with “No reviews yet” text:
{entry.reviews.length > 0 && <Reviews items={entry.reviews} />}
{entry.priceHistory.length >= 2 && <PriceChart data={entry.priceHistory} />}
Generate, noindex or 404?
| Situation | Action | Google source |
|---|---|---|
| Record or filter combination has no results | 404, or don’t create the URL | Faceted navigation docs |
| Page returns 200 but looks empty | Fix it: Google treats it as a soft 404, which keeps getting crawled | Page indexing report |
| Useful to visitors, too thin to rank | noindex meta tag or X-Robots-Tag | Block indexing |
| Facet URLs you never want indexed | Block crawling in robots.txt | Faceted navigation docs |
Two traps to avoid. First, don’t combine noindex with a robots.txt disallow: Google never fetches the page, never sees the noindex, and the URL can still appear in results. Second, Google’s crawl budget docs say not to use noindex to save crawl budget, because the page is still requested before it is dropped. For pages with no data, skipping them is cheaper than noindexing them. There is more on this in the indexing hub.
Does AI-reworded boilerplate count as unique content for programmatic pages?
No. Google’s spam policy names “automated transformations like synonymizing, translating, or other obfuscation techniques” under scaled content abuse, and lists copied content modified “only slightly (for example, by substituting synonyms…)” under scraping. Google’s gen-AI guidance says generating “many pages without adding value for users may violate” the policy, and asks you to “manually factcheck and review all AI-generated content.”
A shingle check will show reworded intros as unique, so the build passes them. A rater reading the page will not see any new information. Gabe’s first two August cases were exactly this pattern. If the data is generic, Omnius’s advice is to fix the data. I agree: an LLM can’t add facts that aren’t in the dataset.
Programmatic SEO best practices: a review checklist
This is what I’d check before approving a template. It is also what I’d ask any programmatic SEO services vendor to show.
- Data source. Proprietary data is strongest, enriched or scored public data comes next, and scraped data is the weakest.
- Block map. Every block is labelled shared or per-page, and per-page blocks make up most of the main content.
- Pilot. Three to five pages built by hand before the template ships (Backlinko).
- Conditional blocks. No block renders without data.
- Gates. Every record ends in publish, noindex or skip. Empty records never get a 200.
- Similarity check. Sibling overlap is checked in CI.
- Policy check. The template is read against Google’s scaled content, doorway and thin affiliation examples, and against the helpful-content question: “Are you using extensive automation to produce content on many topics?” (Google)
- Staged rollout. Track indexation and cannibalization as well as pages published.
If a record can’t fill the per-page layer, don’t build the page.