How I Built a Programmatic SEO Tool with 126K Pages Indexed in 30 Days (Built with AI Assistance)
Last month I launched GradientGen — a free animated mesh gradient generator built with Next.js. 30 days later, Google has indexed 126,000+ pages.
I want to be completely transparent upfront: I built this almost entirely with AI assistance — primarily Claude (Anthropic) for architecture decisions, code generation, and debugging, and v0.dev (Vercel) for UI components. I'm not a senior developer. I understand the code, I make the decisions, but AI wrote most of it.
I'm sharing this because I think the "built with AI" part is just as interesting as the "126K pages indexed" part. Here's the full story.
What is GradientGen?
GradientGen is a free tool that generates animated mesh gradients, topography patterns, font pairings, color palettes, and contrast checkers. Every combination of colors produces a unique URL:
-
/mesh/ff0000-00ff00-0000ff— red, green, blue mesh gradient -
/font-pairing/inter-and-roboto-on-ffffff-and-000000— font pairing preview -
/topography/ff0000-00ff00/seed123456— topography pattern
Each URL is a fully rendered, interactive page with real CSS export functionality. The page is useful whether or not the user came from Google.
My Development Process with AI
I used Claude as my primary development partner throughout the entire project. Not just for boilerplate — for everything:
- Architecture decisions ("should I use ISR or SSR for this?")
- Debugging production errors from Coolify deployment logs
- SEO strategy ("how do I generate server-side related links so Google can crawl them?")
- Writing the pure JavaScript music theory engine
- Fixing TypeScript errors that blocked deployments
My workflow was essentially: I describe what I want, Claude explains the tradeoffs, we decide together, Claude writes the code, I review and understand it, we deploy.
I also used v0.dev for the initial UI scaffold — it generated the component structure and visual design in minutes, which I then refined with Claude.
What I contributed: product decisions, SEO strategy, infrastructure setup, domain registration, understanding and reviewing every piece of code before deploying it.
Is this "real" development? I think so. The decisions are mine. The understanding is mine. The product is mine. AI is just a very fast, very capable coding partner.
Technical Stack
- Next.js 15 with App Router
- TypeScript — strict mode
- Tailwind CSS
- Deployed on Hetzner VPS via Coolify (self-hosted PaaS)
- Zero external APIs — all generation is pure JavaScript math
The Core SEO Idea
Most programmatic SEO fails because pages are thin — templates with variables swapped in. My approach: every page is a working tool.
When someone visits /mesh/ff0000-00ff00-0000ff, they get:
- A live animated gradient they can interact with
- Real-time CSS export
- Color names and hex codes
- Related gradients for exploration
- Contextual description of the palette
The page is useful whether or not the user came from Google. That's the test I apply to every page.
URL Structure
Colors are hexadecimal — 16,777,216 possible values per color slot. With 2-6 colors per gradient, the combination space is essentially infinite:
/mesh/[hex1]-[hex2]-[hex3]-[hex4]
/topography/[hex1]-[hex2]-[hex3]/seed[number]
/font-pairing/[font1]-and-[font2]-on-[bg]-and-[text]
/palette/[hex1]-[hex2]-[hex3]-[hex4]-[hex5]
/contrast/[hex1]-[hex2]
Each one is a valid, functional, unique page.
How I Got 126K Pages Indexed in 30 Days
1. XML Sitemap at Scale
Dynamic sitemap with app/sitemap.ts — carefully selected color combinations representing the full color space systematically, not randomly.
export default function sitemap(): MetadataRoute.Sitemap {
const urls = generateSitemapUrls()
return urls.map(url => ({
url,
lastModified: new Date(),
changeFrequency: 'monthly',
priority: 0.8,
}))
}
2. Server-Side Internal Linking
Every page shows 12 related gradients generated deterministically from the current page's colors — seeded by the hex codes so the same URL always produces the same related links.
This was a key insight Claude helped me with: the related links need to be rendered server-side so Google sees them without executing JavaScript. Originally they were generated client-side after mount — Google couldn't follow them.
// lib/generate-related-links.ts — runs on the server
export function generateRelatedLinks(hexCodes: string[]): MatrixLink[] {
const rand = pseudoRandomGenerator(hexCodes.join('-'));
const links: MatrixLink[] = [];
for (let i = 0; i < 12; i++) {
// generate 12 deterministic related color combinations
// ...
}
return links;
}
This creates a web of interconnected pages — Google crawls one and finds 12 more, each with 12 more.
3. Rich Unique Metadata for Every Page
No two pages have the same title or description:
export async function generateMetadata({ params }) {
const colorNames = hexCodes.map(hex => getNearestColorName(`#${hex}`));
const seoName = getProgrammaticSeoName(`#${hexCodes[0]}`);
return {
title: `${seoName} Mesh Gradient for #${hexCodes[0].toUpperCase()} | GradientGen`,
description: `Create a visually striking ${seoName} mesh gradient.
Blending ${colorNames.join(', ')}, ideal for UI/UX, branding, and design.`,
};
}
4. Fast Infrastructure
Google crawl budget is influenced by server speed. My VPS responds in ~106ms average.
The tradeoff: ISR caching millions of files hit inode limits on my VPS. The fix — a nightly cron job Claude helped me write:
# Clears ISR cache every night at 3:00 AM
0 3 * * * find /path/to/.next/server/app/ -type f -delete
What the Data Shows After 30 Days
- 126,000+ pages indexed by Google
- 682 impressions in Google Search Console
- 6 clicks (positioning is still low — this is normal for month 1)
- 106ms average server response time
- 100% OK (200) responses
The queries generating impressions:
- Hex color codes (
#f6e7b2,6e6708) - Font names (
monsieur la doulaise,biz udmincho) - Brand queries (
gradientgen)
Exactly the long-tail keywords I was targeting.
What Didn't Work
Bing IndexNow batch mode — pushed all URLs in batches, Microsoft Webmaster flagged it as excessive load. Disabled it.
cacheMaxMemorySize: 0 — tried to prevent ISR cache buildup this way, caused client-side errors. Cron job is more reliable.
Honest Reflections on Building with AI
Building with AI is genuinely different from traditional development. Some honest observations:
What AI is great at:
- Writing boilerplate and repetitive code instantly
- Explaining why something doesn't work
- Suggesting architectural patterns I wouldn't have known
- Debugging cryptic error messages from deployment logs
What AI struggles with:
- Keeping track of complex interdependencies across many files
- Sometimes generates code that looks right but has subtle TypeScript errors
- Can be overconfident about solutions that don't work
The real skill is knowing what to ask. Having a clear mental model of what you want to build, breaking it into logical pieces, and knowing when the AI's suggestion is wrong — that's still the human's job.
I don't think "built with AI" means "anyone can do it without effort." It means the barrier to building real products has dropped significantly. Which I think is a good thing.
What's Next
- Waiting for Google to position the indexed pages for color queries
- Building backlinks through design tool directories
- Launching Chordamo — same programmatic SEO approach, for music chord progressions (12 keys × 8 modes × 28 genres × 6 chord options = 16,128 unique pages)
Questions Welcome
I'm happy to answer questions about any technical or SEO aspect in the comments.
GradientGen is completely free — no account required.
Top comments (0)