Most developers think about SEO the wrong way.
They write blog posts. They optimise their landing page. They add meta tags and hope Google notices.
That's broadcasting. You're shouting into the void and waiting.
There's a better move: interception.
Find the exact moment a developer is in pain. Meet them there. Solve it. Let the tool speak for itself.
That's what I spent the last week building for PasteCheck — a mobile-first code linter I built entirely from my Android phone.
Here's the exact system.
The core insight
Developers don't search for "code linter." They search for their error.
- "Cannot read properties of undefined JavaScript"
- "Python indentation error fix"
- "Unexpected token JavaScript"
These are high-intent, emotionally charged searches. Someone's code is broken. They're frustrated. They want a fix in the next 30 seconds.
If you can intercept that search with a page that actually solves the problem — and then naturally introduces your tool — you don't need to advertise. You're already inside the moment.
The architecture
I built a config-driven SEO page system. One template. One data file. Zero duplicated JSX.
The data file: src/data/fixPages.ts
Every page is a config object:
{
title: "How to fix: Cannot read properties of undefined in JavaScript",
slug: "cannot-read-properties-of-undefined",
language: "JavaScript",
summary: "This error means your code tried to access a property on a value that is undefined...",
whyItHappens: "JavaScript allows variables to exist without a value...",
brokenExample: `async function getUser() { ... }`,
fixedExample: `async function getUser() {
if (!data.profile) { return; }
console.log(data.profile.name);
}`,
commonCauses: [
"Accessing nested properties before checking the parent exists",
"An API call returned null or an empty object",
...
],
primaryCtaCopy: "Check your code and see the exact error line",
searchIntent: "error-fix",
}
The template: ErrorFixPage.tsx
One component renders all 20 pages. Title, summary, broken example, fixed example, common causes, CTA — all pulled from config. Change the data, get a new page. No copy-paste, no drift between pages.
The route: /fix/:slug
Dynamic route via Wouter. One line in App.tsx:
<Route path="/fix/:slug" component={ErrorFixPage} />
SEO: canonical tags via react-helmet-async
Every page gets its own canonical, meta title, and description. No duplicate content risk.
20 pages in one sprint
The first 20 pages cover:
- 11 JavaScript errors (the biggest search volume)
- 6 Python errors
- 2 HTML errors
- 1 CSS error
Each page took about 20 minutes to write. The template handles everything else.
All 20 submitted to Google Search Console on May 28. Currently discovering. The compounding starts now.
What else shipped this week
The SEO engine wasn't the only thing. Here's the full v2.18–v2.33 sprint:
UX:
- Two-column desktop layout — input left, results right. Mobile untouched.
- First 3 errors expand automatically on check
- "All errors fixed ✓" state — only triggers when previous check had errors
- Ctrl+Enter keyboard shortcut
- First-time onboarding snippet — pre-filled broken JS on first visit
- Check button loading state
Infrastructure:
- Fixed a critical black screen bug —
setHistorywas outside asetTimeoutclosure. Vite's minifier renamed the variable reference in production. Silent in dev. Blank page in prod. - Closed a Pro bypass vulnerability on the
/successpage - Extended Stripe webhook to handle subscription cancellations and failed payments
- Enabled Dependabot
Distribution:
- Listed on AlternativeTo — already the highest-quality traffic source in GA (1m 31s avg engagement)
- Full violet rebrand sitewide
The numbers so far
Two weeks post-launch:
- 126 total users
- UK users: 2m 43s avg engagement, 84% engagement rate, 81% of all events — the real market
- US users: 1s avg engagement — launch traffic, not retention
- AlternativeTo sending better-quality sessions than Reddit or Dev.to
- Organic search: 94% engagement rate on 18 sessions — early SEO working
The SEO pages haven't indexed yet. That's week 3.
The strategic frame
This isn't about gaming Google. It's about being genuinely useful at the exact moment someone needs help.
Every fix page is a real explanation written for a real error that real developers actually hit. The CTA into PasteCheck is natural — "want to find this exact line in your code?" — because that's what the tool does.
20 pages compounds. 50 pages compounds heavily. 100 pages becomes a moat.
Built entirely from an Android phone.
PasteCheck is a free mobile-first code linter. Paste your JavaScript, TypeScript, Python, HTML, or CSS — see your errors instantly, in plain English. pastecheck.co.uk
Top comments (0)