Programmatic SEO (pSEO) generates large numbers of pages from structured data and templates: every city × service, every integration pair ("Connect X to Y"), every comparison, every entity in a dataset. Done right it captures long-tail demand no hand-written content could economically reach (Zapier, Tripadvisor and Zillow are the canonical examples). Done wrong, it is the textbook definition of what Google's scaled content abuse policy targets, and since May 2026 that policy reaches into AI answers too.
The qualifying questions#
Before building, all four must be "yes":
- Does query demand exist at the pattern level?
weather in {city},{tool} vs {tool}: validate with keyword research that the pattern has volume across many values, even if each page's volume is tiny. - Do you have unique data per page? Real values per entity: prices, specs, reviews, availability, measurements. If every page is the same sentence with a swapped noun, stop.
- Does each page satisfy its query alone? A user landing on "best coworking spaces in Lisbon" must get a genuinely useful answer, not a template skeleton.
- Can you maintain it? Stale programmatic data at scale (closed businesses, old prices) becomes a quality liability.
The 2026 rules: fan-out pages and AI answers#
Two Google changes on 2026-05-15 matter directly for pSEO:
- Spam policies now cover generative AI responses. The definition of spam now includes "attempting to manipulate generative AI responses in Google Search". Policies apply to AI Overviews and AI Mode, not just blue links.
- Fan-out page farms are named. AI Mode and AI Overviews use query fan-out: the model runs several related searches behind the scenes. Google's new AI optimization guide warns that creating "separate content for every possible variation of how people might search (for example, by focusing on other queries that people have asked, or fan-out queries)" primarily to manipulate rankings or AI responses "violates Google's scaled content abuse spam policy."
So "one page per fan-out query" is not a GEO strategy. The same guide adds that AI systems understand synonyms, so you do not need a page for every phrasing. A legitimate pSEO page is one per entity (a city, a product, an integration) with data the user needs, not one per phrasing of the same need.
Also watch doorway abuse: "multiple domain names or pages targeted at specific regions or cities that funnel users to one page", or "substantially similar pages that are closer to search results than a clearly defined, browseable hierarchy." City × service pages for a business that does not operate in those cities are the classic case.
If you use AI to generate or enrich page copy, Google's guidance on generative AI content (updated 2026-10-01) says to fact-check all of it before publishing, including titles, meta descriptions, structured data and alt text. At pSEO scale that means automated checks plus human review of samples. See AI-Assisted Content Without Penalties.
Architecture in Next.js#
The standard build: a data source, a dynamic route, generateStaticParams for pregeneration, and per-page metadata.
import type { Metadata } from "next";
import { notFound } from "next/navigation";
import { getCities, getCityData } from "@/lib/coworking";
export async function generateStaticParams() {
const cities = await getCities();
return cities.map((city) => ({ city: city.slug }));
}
export async function generateMetadata({
params,
}: PageProps<"/coworking/[city]">): Promise<Metadata> {
const { city } = await params;
const data = await getCityData(city);
if (!data) return {};
return {
title: `${data.spaceCount} Best Coworking Spaces in ${data.name} (${data.year})`,
description: `Compared on price, wifi speed and amenities. Day passes from ${data.minPrice}.`,
alternates: { canonical: `https://example.com/coworking/${city}` },
};
}
export default async function CityPage({ params }: PageProps<"/coworking/[city]">) {
const { city } = await params;
const data = await getCityData(city);
if (!data || data.spaceCount < 3) notFound(); // quality gate: thin pages don't ship
return <CityGuide data={data} />;
}Implementation notes:
- Quality-gate in code. The
notFound()on insufficient data is the most important line: it enforces "no thin pages" structurally rather than editorially. Apply the same gate ingenerateStaticParamsand in your sitemap so gated pages are never listed. - SSG or ISR over SSR. Pregenerated pages give the TTFB and LCP profile thousands of pages need, and
revalidatekeeps data fresh. - Vary the template genuinely: conditional sections based on what data exists per entity, so pages differ in structure, not just nouns.
- Keep it lean. Googlebot fetches only the first 2MB of an HTML file, so do not bloat templates with huge inline JSON payloads ahead of the content.
Template design for value density#
Each page should lead with the unique data, not boilerplate:
- Above the fold: the entity-specific answer: the table, the map, the number.
- Comparative context: how this entity ranks among its siblings ("3rd cheapest of 41").
- Structured data matching the entity type (
Product,LocalBusiness,Datasetand so on). SkipFAQPageas a rich-result play: Google stopped showing FAQ rich results on 2026-05-07, and entity-swapped FAQs are exactly the boilerplate that makes pages look templated. - Hand-written framing where it counts: intro paragraphs for the top-traffic pages. The head of the long tail deserves human attention.
Internal linking at scale#
Thousands of pages need systematic discovery paths (architecture principles):
- Hub indexes with pagination (country → cities; category → entities)
- Sibling links ("nearby cities", "similar tools"): algorithmic but capped and relevant
- Breadcrumbs everywhere
- Sitemaps segmented by section (
/sitemaps/coworking.xml) so you can monitor indexation per pattern in Search Console
Rollout and monitoring#
Launch in tranches, not all at once. Ship a few hundred pages and watch Search Console indexation: "Crawled - currently not indexed" at scale is a quality verdict. Iterate on the template, then expand. Track per pattern:
- indexation rate (indexed ÷ submitted in that sitemap)
- impressions and clicks, including impressions in the Generative AI performance report
- engagement and conversions in analytics
Patterns that never index or never earn clicks get improved, consolidated or removed (content pruning). Given Mueller's "lost faith" warning, pruning a failed pattern early protects the rest of the site.
Next: Site Migrations, the highest-stakes operation in technical SEO.