A production-ready MVP that analyzes any public website for performance (Lighthouse Core Web Vitals) and conversion potential (Claude AI), returning a structured report with scores, issues, and prioritized improvements.
| Layer | Technology |
|---|---|
| Framework | Next.js 14 (App Router) |
| Styling | Tailwind CSS |
| Scraping | Playwright (Chromium) |
| Performance | Lighthouse / PageSpeed Insights API |
| AI Analysis | Anthropic Claude API |
| Database | Supabase (PostgreSQL) |
| Deployment | Vercel |
web-analyzer/
├── app/
│ ├── layout.tsx # Root layout + metadata
│ ├── page.tsx # Landing page + inline report
│ ├── globals.css # Global styles + CSS variables
│ ├── analyze/
│ │ └── page.tsx # Dedicated /analyze?url= page
│ └── api/
│ └── analyze/
│ └── route.ts # POST /api/analyze — main pipeline
├── components/
│ ├── UrlInput.tsx # URL input + loading steps
│ └── ReportCard.tsx # Full report display
├── lib/
│ ├── scraper.ts # Playwright scraping logic
│ ├── lighthouse.ts # Lighthouse + PageSpeed fallback
│ ├── aiAnalysis.ts # Claude AI prompt + parsing
│ └── supabase.ts # DB client + report persistence
├── utils/
│ └── scoreCalculator.ts # Score grading + CWV helpers
├── .env.example # Environment variable template
├── next.config.js
├── tailwind.config.ts
└── package.json
- Node.js 18+
- npm or yarn
- A publicly accessible website URL to test with
git clone <your-repo-url>
cd web-analyzer
npm install
postinstallautomatically runsplaywright install chromiumto download the browser binary.
cp .env.example .env.localEdit .env.local and fill in:
# Required — Claude AI
ANTHROPIC_API_KEY=sk-ant-...
# Optional — Supabase persistence
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-keyIf you want reports persisted to a database:
- Create a project at supabase.com
- Go to SQL Editor and run:
create table public.reports (
id uuid primary key default gen_random_uuid(),
url text not null,
timestamp timestamptz not null default now(),
perf_score integer,
conv_score integer,
full_report jsonb,
created_at timestamptz default now()
);
alter table public.reports enable row level security;
create policy "Allow anon insert" on public.reports
for insert to anon with check (true);
create policy "Allow anon select" on public.reports
for select to anon using (true);- Copy the URL and anon key from Project Settings → API into
.env.local
npm run dev- Paste any public URL into the input field (e.g.
stripe.com) - Click Analyze Website
- Watch the step-by-step progress indicators
- View your full report:
- Performance Score — from Lighthouse Core Web Vitals
- Conversion Score — from Claude AI analysis
- CWV Metrics — LCP, FID, CLS, TTFB
- Headline & CTA Feedback — specific AI critique
- Trust Signal Audit — what's missing
- Top Issues — ordered by severity
- Recommended Improvements — ordered by impact
Vercel's serverless functions have a 50 MB code size limit and no persistent Chrome binary. Playwright's bundled Chromium alone is ~300 MB, which means you need hosted alternatives for production.
Replace runLighthouse with runPageSpeedInsights in app/api/analyze/route.ts:
// In app/api/analyze/route.ts — change:
import { runPageSpeedInsights } from "@/lib/lighthouse";
// Then in the handler:
performanceData = await runPageSpeedInsights(url);Free tier: 25,000 requests/day. Get an API key at Google Cloud Console for higher limits.
Add to Vercel environment variables:
PAGESPEED_API_KEY=your-key # optional — works without it
Replace Playwright with Browserless hosted browser:
// In lib/scraper.ts — replace chromium.launch() with:
import { chromium } from "playwright-core";
const browser = await chromium.connectOverCDP(
`wss://chrome.browserless.io?token=${process.env.BROWSERLESS_TOKEN}`
);Sign up at browserless.io — free tier available.
- Push to GitHub
git init
git add .
git commit -m "initial commit"
git remote add origin https://github.com/your-username/web-analyzer.git
git push -u origin main-
Import to Vercel
- Go to vercel.com/new
- Import your GitHub repository
- Vercel auto-detects Next.js
-
Add environment variables
In Vercel dashboard → Project → Settings → Environment Variables:
ANTHROPIC_API_KEY = sk-ant-...
NEXT_PUBLIC_SUPABASE_URL = https://...
NEXT_PUBLIC_SUPABASE_ANON_KEY = ...
SUPABASE_SERVICE_ROLE_KEY = ...
PAGESPEED_API_KEY = ... (if using Option A)
BROWSERLESS_TOKEN = ... (if using Option B)
- Increase function timeout (requires Vercel Pro)
In app/api/analyze/route.ts the line export const maxDuration = 60 is already set. On the free Hobby plan, functions timeout at 10s — upgrade to Pro for 60s.
- Deploy
vercel --prodOr push to main — Vercel auto-deploys.
Request body:
{ "url": "https://stripe.com" }Response (200):
{
"url": "https://stripe.com",
"timestamp": "2024-07-15T10:30:00.000Z",
"performance": {
"score": 87,
"metrics": {
"lcp": 1.8,
"fid": 42,
"cls": 0.04,
"ttfb": 312,
"tti": 3.2,
"speedIndex": 2.1
},
"categories": {
"accessibility": 94,
"seo": 91,
"bestPractices": 88
}
},
"aiAnalysis": {
"conversion_score": 82,
"headline_feedback": "Stripe's headline 'Financial infrastructure for the internet' is clear...",
"cta_feedback": "The 'Start now' CTA is prominent but lacks urgency...",
"trust_signal_feedback": "Strong social proof with recognizable logos...",
"conversion_improvements": [
"Add a free trial or money-back guarantee above the fold",
...
],
"issues": [
"Hero section lacks a secondary CTA for users not ready to sign up",
...
]
},
"scrapedData": {
"title": "Stripe | Financial Infrastructure for the Internet",
"metaDescription": "...",
"headings": ["Financial infrastructure...", ...],
"buttons": ["Start now", "Contact sales", ...],
"visibleText": "..."
}
}Error responses:
400— Invalid URL422— Website unreachable500— AI analysis failed
In lib/aiAnalysis.ts:
model: "claude-opus-4-5", // Most capable, slower
model: "claude-sonnet-4-5", // Good balance (recommended)
model: "claude-haiku-4-5-20251001", // Fastest, cheapestTo run only performance (skip AI):
- Comment out the AI analysis step in
route.ts
To run only AI (skip Lighthouse):
- Comment out the Lighthouse step in
route.ts
In lib/lighthouse.ts, change:
onlyCategories: ["performance"]
// to:
onlyCategories: ["performance", "accessibility", "seo", "best-practices"]| Service | Free Tier | Cost per 1000 analyses |
|---|---|---|
| Anthropic Claude (Sonnet) | $5 free credits | ~$1.50 |
| Supabase | 500MB storage free | Free for MVP |
| Vercel | 100GB bandwidth free | Free for MVP |
| PageSpeed API | 25K req/day free | Free |
Total: ~$1.50 per 1000 analyses using Claude Sonnet.
- Auth — Clerk or Supabase Auth for user accounts
- Report history — Dashboard showing past analyses
- Scheduled monitoring — Weekly re-analysis with email alerts
- PDF export — Download report as branded PDF
- Competitor comparison — Side-by-side analysis of 2 URLs
- Payments — Stripe for credits-based or subscription model
- White-label — Custom branding for agency resale
"Failed to load website"
- URL must be publicly accessible (no VPN-only sites, localhost, or private IPs)
- Some sites block headless browsers — try a different URL to test
Lighthouse returns all nulls
- On Vercel, Lighthouse can't run — switch to
runPageSpeedInsights()inroute.ts - Locally, ensure Chrome/Chromium is installed:
npx playwright install chromium
Analysis times out
- Vercel Hobby plan has a 10s function limit — the analysis needs ~30s
- Upgrade to Vercel Pro, or split the scraping and analysis into separate API routes
Claude API errors
- Check your
ANTHROPIC_API_KEYin.env.local - Ensure you have API credits at console.anthropic.com