What is programmatic SEO?
An automated approach that enables the generation of thousands of optimized pages at scale.

Programmatic SEO means building one page template, connecting it to a structured dataset and publishing a page for each row or combination that matches something people actually search for. You design the system once and the system produces the pages. It applies the usual SEO fundamentals at a volume you could never reach by hand.
A job board, from spreadsheet to live page
Say you run a job board and want to rank for searches like “data analyst jobs in Lyon”. Role plus city gives you a pattern you can repeat, and three pieces turn that pattern into pages.
The dataset
Each row is a future page, and the columns are what will make it different from its neighbors. The figures below are made up for the example.
| role | city | open_jobs | median_salary | top_skills |
|---|---|---|---|---|
| Data analyst | Lyon | 42 | 44,000 € | SQL, Power BI |
| Data analyst | Nantes | 17 | 41,000 € | SQL, Looker |
| Welder | Saint-Nazaire | 63 | 31,000 € | TIG, MIG |
| Welder | Cahors | 2 |
This can live in a SQL database, a CSV export or a plain Google Sheet. The format matters less than the accuracy.
The template
The template is the blueprint: a fixed page structure with slots that the data fills in. Here is a stripped-down version in Astro, which pre-renders one static HTML file per entry at build time.
---
// src/pages/jobs/[role]/[city].astro
import { getJobPages } from "../../../lib/job-pages";
export async function getStaticPaths() {
const pages = await getJobPages();
return pages
.filter((page) => page.openJobs >= 5)
.map((page) => ({
params: { role: page.roleSlug, city: page.citySlug },
props: { page },
}));
}
const { page } = Astro.props;
const heading = `${page.role} jobs in ${page.city}`;
const pageTitle = `${heading}, ${page.openJobs} open positions`;
---
<html lang="en">
<head>
<meta charset="utf-8" />
<title>{pageTitle}</title>
</head>
<body>
<h1>{heading}</h1>
<p>Median advertised salary: {page.medianSalary}.</p>
<p>Most requested skills: {page.topSkills.join(", ")}.</p>
<ul>
{page.jobs.map((job) => (
<li><a href={job.url}>{job.title}</a></li>
))}
</ul>
<nav aria-label="Nearby cities">
{page.nearbyCities.map((near) => (
<a href={`/jobs/${page.roleSlug}/${near.slug}`}>{page.role} in {near.name}</a>
))}
</nav>
</body>
</html>
The .filter() line is the most important one in that file. Welders in Cahors have two open positions and no salary data, so they get no page at all. A programmatic project is defined as much by the pages it refuses to create as by the ones it publishes.
The publishing pipeline
The last piece keeps everything in sync: when the data changes, the pages rebuild, the listings and salaries update, and the sitemap regenerates. Nobody edits page 3,000 by hand. The same goes for a retail catalog following its stock and prices.
What gets automated and what stays with you
Title tags, meta descriptions, internal links and XML sitemaps can all be produced from the data, and that removes a whole category of human error. A consistent rule applied to 10,000 pages beats 10,000 individual decisions.
Choosing the patterns stays with you, as does setting the threshold for publishing and reading a sample of the output. No script will tell you that page 4,212 reads as absurd. After launch, the same logic extends to quality control, and you can automate SEO audits so you hear about broken pages before your visitors do.
Variables are what make a page worth indexing
A template that only swaps a city name creates near-duplicates, which is what Google’s scaled content abuse policy is written to catch. Generating pages is allowed. Generating pages with little value for the reader is the problem, whatever tool wrote them.
The practical answer is more and better variables. For Deux.io I developed more than 90 of them: images, titles, metadata, schemas, highlighted profiles, value propositions, featured articles, links and internal linking. Depending on the variable, we generated anywhere between 100 and over 2,500 variations, and the toolchain included an AI content checker and a duplicate content checker.
AI is optional in all this. It helps write variations, but it can’t invent the facts that make a page useful, and those have to come from your data. My own check is simple: take two neighboring pages, mentally delete everything the template provides, and look at what’s left. If it’s specific and different, you have a page. The same specific facts are also what AI-generated answers look for when they read your site.
Getting thousands of pages found
A generated page nobody can reach doesn’t exist for a search engine. Three technical habits matter from day one.
Every page needs a crawlable path from another page, using real <a href> links in the HTML. Filters that only work in JavaScript don’t count.
XML sitemaps tell crawlers what exists. A single file is limited to 50,000 URLs or 50 MB uncompressed, so large sites split them and reference them from a sitemap index.
Schema.org markup such as JobPosting, Product or LocalBusiness describes the content in a form machines can read. It can make a page eligible for some search features and guarantees none. Google removed HowTo rich results and restricted FAQ rich results to authoritative government and health sites in 2023, so don’t build a plan around those snippets.
After launch, the Page indexing report in Search Console becomes your main instrument. A large block of “Crawled, currently not indexed” pages usually says something about their perceived value. I cover the rollout in pushing to production and managing indexing.
Where the model fits
| Type of site | Repeating pattern | Data behind it |
|---|---|---|
| E-commerce | Category and attribute | Catalog, prices, stock |
| Local directory | Service and city | Provider listings, reviews |
| Marketplace or price comparison | Route and airline, product and retailer | Live inventory and prices |
| Sports or news media | Player, team or match | Statistics feed |
| Real estate | Property type and location | Listings |
One caution on e-commerce: keep size and color variants on a single page unless people search for them separately. More URLs add nothing when the search demand isn’t there.
Programmatic SEO and automated SEO are different jobs
The two terms get mixed up. Programmatic SEO creates pages from structured data. Automated SEO runs tools over pages that already exist: updating metadata, monitoring performance, flagging errors. Mature sites do both, since the first builds the coverage and the second keeps it healthy.
Mock up 20 rows before you build anything
Pick one pattern and fill 20 rows in a spreadsheet by hand. Then write out three of the resulting pages in a document, making sure one comes from your weakest row. If that weakest page wouldn’t help anyone, raise your publishing threshold or go find more data, and only then design the database that will feed the real thing.