Programmatic SEO Mode — Template-Based Bulk Generation
Programmatic SEO Mode lets you create hundreds of similar pages from a single template and a data source. Write a template once, plug in a spreadsheet of variables, and the system generates unique pages for every row. This mode is built as a 4-step wizard: Template → Data Source → Mapping → Generate.
Accessing Programmatic SEO Mode
Open the Generator tab and click the 3-way mode selector at the top right. Select 🔄 Programmatic to enter the wizard.
A step indicator at the top shows your progress through the four stages. Completed steps display a checkmark, the active step is highlighted, and future steps are grayed out. You can click any completed step to jump back and make changes.
Step 1: Template
The Template Editor is where you create or select the master content template for your pages.
Template Library
Toggle 📚 Show Library to browse available templates. The library has two collapsible sections:
Starter Templates — Five pre-built templates ship with the platform:
| Template | Category | Purpose |
|---|---|---|
| City Service Page | 🏠 Location | Local SEO pages for service-based businesses targeting specific cities |
| Product Comparison | ⚖️ Comparison | Side-by-side reviews (e.g., "Notion vs Coda") |
| Integration Guide | 🔌 Integration | Step-by-step tutorials for connecting two tools/platforms |
| Product Landing Page | 📦 Product | High-converting product pages with social proof |
| Best X for Y Listicle | ✨ Custom | Ranked list articles (e.g., "10 Best CRMs for Startups") |
Each card shows the template name, variable count, character count, and a short description. Click any template to load it into the editor.
Your Templates — Saved custom templates appear here. Each card has a 🗑️ delete button. If you have no saved templates, a prompt suggests starting from a starter template.
Creating a Template
Click ➕ New Template to start from scratch, or select a starter template and customize it.
Fill in:
- Template Name (required) — A label for the template
- Category — Location, Comparison, Integration, Product, or Custom
- Description (optional) — Brief note about the template's purpose
Writing Template Content
The main editor accepts Markdown with variable placeholders. Variables use double curly braces:
# Best {{service}} in {{city}}
Looking for {{service}} in {{city}}? Here's everything you need to know about
finding quality {{service}} providers in the {{city}} area.
## Pricing
Prices typically start at {{price}} for basic services.
The system auto-detects variables as you type. A 🎯 Detected Variables sidebar updates in real-time, listing every {{variable}} found in your content along with its inferred type.
Quick Insert
Below the detected variables panel, a Quick Insert section provides one-click buttons for common variable names: city, state, service, price, year. Click any button to insert the variable at your cursor position in the editor.
Download CSV Template
When variables are detected, a button appears to download a CSV template pre-filled with your variable names as column headers. This is the fastest way to build your data source file.
Saving Templates
- Click 💾 Save as New to create a new saved template
- Click 💾 Update Template to overwrite an existing saved template (only appears for your own templates, not starters)
- Selecting a starter template and saving always creates a new copy rather than overwriting the original
Templates persist in your account via the database, so they're available across sessions.
Advancing to Step 2
Once your template has a name and content with at least one variable, click Next: Data Source → to proceed.
Step 2: Data Source
The Data Source Manager handles the structured data that gets merged with your template.
Mode Toggle
Two input modes sit at the top:
- 📁 Upload File — Drag-and-drop or click-to-browse for CSV and JSON files
- ✏️ Manual Entry — Build a data table directly in the browser
File Upload
Drag a .csv or .json file onto the drop zone (or click to open the file picker). The system parses the file immediately:
CSV files are processed with PapaParse. Headers are required. Empty lines are skipped. The first row determines column names.
JSON files must contain an array of objects. Each object represents a row, and keys become column names. All values are converted to strings.
After a successful upload, a data preview shows:
- File name, row count, column count, and source type
- A scrollable table previewing up to 20 rows
- A green "✓ Data Loaded" badge
Manual Entry
When you select Manual Entry, the column headers auto-populate from your template's detected variables. If your template uses {{city}}, {{service}}, and {{price}}, the manual table starts with those three columns.
Manual editing controls:
- + Add Column — Appends a new column with a default name
- + Add Row — Appends a blank row
- Column headers are editable inline (click to rename)
- Each column has a ✕ button to remove it (minimum one column required)
- Each row has a 🗑️ button to remove it (minimum one row required)
- Click ✓ Apply Data to commit your manual table as the data source
Clearing Data
A 🗑️ Clear Data button appears when a data source is loaded. Click it to remove all data and start fresh.
Advancing to Step 3
Once your data source is loaded (file or manual), click Next: Mapping → to proceed.
Step 3: Variable Mapping
The Variable Mapper connects your template's variables to your data source's columns.
How It Works
The left panel shows your template variables. The right panel shows your data columns. For each variable, select which column provides its value using a dropdown.
Auto-Map
Click 🔗 Auto-Map to let the system match variables to columns automatically. It matches by exact name first, so if your template uses {{city}} and your CSV has a "city" column, they pair up instantly.
Transformations
Each mapped variable has an optional transformation dropdown:
| Transformation | Effect | Example |
|---|---|---|
| None | Pass through as-is | "new york" → "new york" |
| Uppercase | Convert to all caps | "new york" → "NEW YORK" |
| Lowercase | Convert to all lowercase | "New York" → "new york" |
| Capitalize | Capitalize first letter of each word | "new york" → "New York" |
Mapping Summary
A status bar shows how many variables are mapped vs. total. Unmapped variables remain as literal {{variable_name}} text in the output.
Uniqueness Scoring Configuration
A configuration panel lets you set the uniqueness score threshold. Pages that score below this threshold during generation get flagged. The uniqueness score measures how different each generated page is from the other pages in the batch. This helps catch cases where template-generated content is too repetitive.
AI Enhancement Configuration
Toggle AI Enhancement to run a second pass over each generated page. When enabled, the AI rewrites introductions and conclusions to make each page sound more natural and distinct, reducing the templated feel.
Advancing to Step 4
Once at least one variable is mapped, click Next: Generate → to proceed.
Step 4: Generate & Preview
The Generation Preview is the final step where pages are created, monitored, and exported.
Starting Generation
Click the Generate button to begin processing. Each row in your data source becomes one page. The system:
- Takes your template content
- Replaces each
{{variable}}with the mapped column value for that row - Applies any transformations (uppercase, lowercase, capitalize)
- Runs AI enhancement if enabled (generates unique intros/conclusions)
- Calculates a uniqueness score against other generated pages
- Saves the result
Progress Tracking
Each page shows its current status:
| Status | Meaning |
|---|---|
| Pending | Queued, not yet processed |
| Generating | Currently being processed |
| Completed | Successfully generated |
| Failed | Error during generation |
| Skipped | Skipped due to missing data or user stop |
A progress bar and counter update in real-time as pages process.
Pause & Stop Controls
- Pause — Temporarily halts generation. Click again to resume from where it stopped.
- Stop — Stops generation entirely. Completed pages are preserved.
Preview Pane
Click any generated page in the list to see its full content in a preview pane alongside the page list. The preview renders the Markdown output so you can verify formatting, variable replacement accuracy, and overall quality.
Uniqueness Scores
Each completed page displays a uniqueness score as a percentage. Higher scores mean the page content differs more from other pages in the batch. Pages that fall below your configured threshold (set in Step 3) are flagged so you can review them.
Retry Failed Pages
Individual failed pages can be retried. Click the retry button next to any failed page to reprocess just that row.
CSV Export
Click the export button to download all generated pages as a CSV file. Each row includes the generated content, page title, and metadata. This lets you import the batch into any CMS or content management workflow.
LocalStorage Persistence
Generated pages are saved to your browser's LocalStorage. If you close the browser and return, your generated pages are still available. This prevents lost work during long generation runs.
Best Practices
Template Design
- Start with one of the five starter templates and customize from there
- Use descriptive variable names (
{{city_name}}over{{v1}}) so auto-mapping works correctly - Include Markdown formatting in your template (headers, bold, lists, tables) for structured output
- Keep variable count manageable. A template with 50+ variables gets hard to maintain
Data Source Preparation
- Name your CSV columns to match your template variables exactly so auto-mapping handles everything
- Use the "Download CSV Template" button from Step 1 to get a pre-formatted file
- Remove any trailing whitespace from column values to avoid formatting issues in output
AI Enhancement
- Enable AI Enhancement for templates where similar content risks sounding repetitive
- The uniqueness threshold defaults to a reasonable level, but you can raise it if your niche demands highly distinct pages
- AI Enhancement consumes extra API tokens per page, so factor that into your API usage budget