Programmatic SEO Page Generator
Generate hundreds of landing pages from one template and a CSV — {{column}} placeholders, filters like slug and title case, per-row wording rotation, and slug/title/meta-description patterns. Export as Markdown, HTML, JSON or CSV, or download every page as its own file in a ZIP. Runs privately in your browser.
Input
Each row becomes one page. Column names in the header row become placeholders: a column called city is {{city}}.
Placeholders: {{column}}, filters {{column|slug}} · |lower · |upper · |title · |capitalize · |trim · |default:text, the row number {{row}}, and {{rotate:A|B|C}} to vary wording from row to row.
Turned into a URL-safe slug automatically. Duplicate slugs get -2, -3… appended. Left empty, pages are named page-1, page-2…
Output
More ways to use this tool
REST API
curl -X POST https://api.iotools.cloud/v1/tool/programmatic-seo-generator \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"data": "service,city,state\nPlumber,Austin,TX\nElectrician…",
"delimiter": "auto",
"template": "## {{rotate:Best|Top-rated|Trusted}} {{service}}…",
"titlePattern": "{{service}} in {{city}}, {{state}}",
"descriptionPattern": "Find a trusted {{service|lower}} in {{city}}. Co…",
"slugPattern": "{{service|slug}}-in-{{city|slug}}",
"format": "markdown"
}'Swap in your own key from your account. The tool's fields are the body — no wrapper.
Ask an AI agent
Use the IOTools `programmatic-seo-generator` tool (Programmatic SEO Page Generator) on this input:
YOUR_INPUT_HEREPaste this at any agent connected to the IOTools MCP server, then add your input.
| Cost per API/MCP call | From 5 credits |
|---|---|
| Need more credits? | View pricing |
Also available with
Guides
What this tool does
Programmatic SEO is the practice of publishing many similar, genuinely useful pages from structured data — "plumber in Austin", "plumber in Denver", "Notion vs Obsidian", "Notion vs Trello" — instead of writing each one by hand. This generator does the mechanical half: you write one page template with {{column}} placeholders, paste a spreadsheet of data, and it produces one finished page per row, complete with a URL slug, an SEO title and a meta description.
Everything runs in your browser. Your keyword list, client data and templates are never uploaded, and the same input always produces exactly the same pages.
How to use it
- Paste your data as CSV (or TSV — the delimiter is detected automatically). The first row names the columns.
- Write the page template. A column called
cityis inserted with{{city}}. - Optionally fill in the title, meta description and slug patterns — they use the same placeholders.
- Pick an output format. Copy or download the combined result, or download the ZIP with every page as its own file, named by its slug.
Template syntax
| Placeholder | What it inserts |
|---|---|
{{city}} |
The row's value in the city column (column names are case-insensitive) |
{{city|slug}} |
A URL-safe version: São Paulo → sao-paulo |
{{city|lower}}, |upper, |title, |capitalize, |trim |
Case and whitespace filters — chain them left to right |
{{alternative|default:the competition}} |
A fallback for empty cells |
{{row}} |
The row number, starting at 1 |
{{rotate:Best|Top-rated|Trusted}} |
A different wording on each row, cycling through the options |
{{rotate:…}} is the simplest way to stop hundreds of pages from opening with the identical sentence. It's deterministic — row 1 gets the first option, row 2 the second, and so on — so regenerating never reshuffles pages you've already published.
Output formats
- Markdown — each page gets YAML front matter (
title,description,slug), ready for static-site generators such as Astro, Hugo, Jekyll or Next.js content folders. - HTML — a complete page per row with
<title>and<meta name="description">. Values from your data are HTML-escaped so a stray<or&can't break the markup; add|rawto a placeholder when the cell itself contains HTML you want inserted as-is. - Plain text — just the rendered body of each page.
- JSON and CSV — one record per page with
slug,title,descriptionandcontent, for importing into a CMS, Webflow, WordPress or a database.
The Report flags placeholders that don't match any column (they're left untouched so you can spot them), columns your template never uses, pages that ended up with an empty value, and duplicate slugs (renamed with -2, -3…). Up to 5,000 rows are processed per run.
Frequently asked questions
Will Google treat these pages as thin or duplicate content?
It can, if the only difference between pages is a swapped city name. Template engines handle the scale; the value has to come from your data. Add columns that genuinely differ per page — prices, local facts, specs, FAQs — and use {{rotate:…}} for varied phrasing.
Does it use AI?
No. It's a deterministic template engine, so output is predictable and free to regenerate as often as you like.
Related tools
Need just one URL slug? Use the Slug Generator. To turn your spreadsheet into JSON first, try the CSV to JSON Converter, and to fill a single config template from variables, the Env Var Template Expander.