import { useState, useEffect, useRef } from "react"; const BRAND = { teal: "#153139", tealLight: "#1d4350", tealDark: "#0e2128", gold: "#B1986B", goldLight: "#c4ad85", warm: "#F8F6F3", warmDark: "#ede9e3", white: "#ffffff", red: "#c0392b", orange: "#e67e22", yellow: "#f1c40f", green: "#27ae60", }; const SCAN_STEPS = [ "Connecting to website...", "Analyzing page structure & meta tags...", "Checking mobile responsiveness...", "Evaluating page speed signals...", "Reviewing local SEO factors...", "Inspecting Google Business Profile signals...", "Analyzing content quality...", "Checking backlink indicators...", "Compiling your personalized report...", ]; function getScoreColor(score) { if (score >= 80) return BRAND.green; if (score >= 60) return BRAND.yellow; if (score >= 40) return BRAND.orange; return BRAND.red; } function getGrade(score) { if (score >= 90) return "A"; if (score >= 80) return "B+"; if (score >= 70) return "B"; if (score >= 60) return "C+"; if (score >= 50) return "C"; if (score >= 40) return "D"; return "F"; } function ScoreCircle({ score, size = 120, strokeWidth = 8, label }) { const radius = (size - strokeWidth) / 2; const circumference = 2 * Math.PI * radius; const offset = circumference - (score / 100) * circumference; const color = getScoreColor(score); return (
{score}
{label &&
{label}
}
); } function CategoryCard({ category, index }) { const [expanded, setExpanded] = useState(false); return (
setExpanded(!expanded)} >
{getGrade(category.score)}
{category.name}
{category.summary}
{category.score}
{expanded && (
{category.findings?.map((f, i) => (
{f.type === "good" ? "✅" : f.type === "warning" ? "⚠️" : "❌"} {f.text}
))} {category.recommendation && (
Keyo Recommendation: {category.recommendation}
)}
)}
); } export default function SEOAuditTool() { const [url, setUrl] = useState(""); const [email, setEmail] = useState(""); const [phase, setPhase] = useState("form"); // form, scanning, report, error const [scanStep, setScanStep] = useState(0); const [report, setReport] = useState(null); const [errorMsg, setErrorMsg] = useState(""); const abortRef = useRef(null); useEffect(() => { const link = document.createElement("link"); link.href = "https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;600;700&family=DM+Sans:wght@400;500;600;700&display=swap"; link.rel = "stylesheet"; document.head.appendChild(link); }, []); useEffect(() => { if (phase !== "scanning") return; const interval = setInterval(() => { setScanStep((s) => (s < SCAN_STEPS.length - 1 ? s + 1 : s)); }, 2800); return () => clearInterval(interval); }, [phase]); const runAudit = async () => { if (!url.trim() || !email.trim()) return; setPhase("scanning"); setScanStep(0); setErrorMsg(""); const cleanUrl = url.trim().replace(/^https?:\/\//, "").replace(/\/$/, ""); const systemPrompt = `You are an expert SEO auditor for Keyo Agency, a Toronto-based digital marketing agency specializing in local SEO for small businesses. Analyze the provided website and return a detailed SEO audit as JSON. Use the web_search tool to find and analyze the website. You MUST respond with ONLY valid JSON (no markdown, no backticks, no explanation). The JSON schema: { "business_name": "string - the business name from the site", "overall_score": number 0-100, "summary": "string - 2 sentence executive summary", "categories": [ { "name": "string - category name", "score": number 0-100, "summary": "string - one line summary", "findings": [ { "type": "good|warning|bad", "text": "string - specific finding" } ], "recommendation": "string - what Keyo can do to help" } ] } Categories to evaluate (provide 6-8 categories): 1. On-Page SEO (title tags, meta descriptions, headings, keyword usage) 2. Local SEO (NAP consistency, local keywords, Google Business Profile signals, schema markup) 3. Mobile Responsiveness (mobile-friendly design, viewport, tap targets) 4. Page Speed & Performance (load time signals, image optimization, core web vitals indicators) 5. Content Quality (content depth, readability, freshness, internal linking) 6. Technical SEO (SSL, sitemap, robots.txt, structured data, canonical tags) 7. Backlink Profile (domain authority signals, referring domains estimate) 8. User Experience (navigation, CTA clarity, design quality) Be specific with findings - reference actual elements you find on the site. Be honest but constructive. Scores should be realistic, not inflated. Most small business sites score 30-65 overall.`; try { const response = await fetch("https://api.anthropic.com/v1/messages", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ model: "claude-sonnet-4-20250514", max_tokens: 4000, system: systemPrompt, tools: [{ type: "web_search_20250305", name: "web_search" }], messages: [ { role: "user", content: `Analyze this website for SEO: ${cleanUrl}\n\nSearch for the website, examine what you can find about it, and provide a comprehensive SEO audit. Remember to respond with ONLY valid JSON.`, }, ], }), }); if (!response.ok) { throw new Error(`API error: ${response.status}`); } const data = await response.json(); // Extract text from response const textContent = data.content ?.filter((block) => block.type === "text") .map((block) => block.text) .join(""); if (!textContent) { throw new Error("No text response received"); } // Parse JSON from response const cleanJson = textContent.replace(/```json\s?|```/g, "").trim(); const parsed = JSON.parse(cleanJson); setReport(parsed); setPhase("report"); } catch (err) { console.error("Audit error:", err); setErrorMsg(err.message || "Something went wrong. Please try again."); setPhase("error"); } }; return (
{/* Header */}
K
Keyo Agency
Free SEO Audit Tool
{/* FORM PHASE */} {phase === "form" && (
Free Analysis

How Does Your Website
Really Perform?

Get a comprehensive SEO audit with actionable insights to help your business rank higher in local search results.

setUrl(e.target.value)} style={{ width: "100%", padding: "14px 16px", borderRadius: 10, border: `1.5px solid ${BRAND.warmDark}`, fontSize: 15, fontFamily: "'DM Sans', sans-serif", color: BRAND.teal, background: BRAND.warm, transition: "all 0.2s", }} />
setEmail(e.target.value)} style={{ width: "100%", padding: "14px 16px", borderRadius: 10, border: `1.5px solid ${BRAND.warmDark}`, fontSize: 15, fontFamily: "'DM Sans', sans-serif", color: BRAND.teal, background: BRAND.warm, transition: "all 0.2s", }} />

Takes about 30 seconds. No credit card required.

{["100+ SEO Checks", "Local SEO Focus", "Actionable Tips"].map((t) => (
{t}
))}
)} {/* SCANNING PHASE */} {phase === "scanning" && (

Analyzing Your Website

{url.replace(/^https?:\/\//, "").replace(/\/$/, "")}

{SCAN_STEPS.map((step, i) => (
{i < scanStep ? "✓" : i === scanStep ? : ""}
{step}
))}
)} {/* ERROR PHASE */} {phase === "error" && (
⚠️

Audit Couldn't Complete

{errorMsg || "We had trouble analyzing that website. Please check the URL and try again."}

)} {/* REPORT PHASE */} {phase === "report" && report && (
{/* Report Header */}
SEO Audit Report

{report.business_name || url.replace(/^https?:\/\//, "")}

{url.replace(/^https?:\/\//, "").replace(/\/$/, "")}

Overall Score

{report.summary}

{/* Score Overview Bar */} {report.categories && (
{report.categories.map((cat, i) => (
{cat.score}
{cat.name.split(" ").slice(0, 2).join(" ")}
))}
)} {/* Category Cards */}

Detailed Findings

Click each category to expand details and recommendations.

{report.categories?.map((cat, i) => ( ))} {/* CTA */}

Ready to Improve Your Rankings?

Keyo Agency specializes in helping local businesses like yours dominate search results. Let's discuss a strategy tailored to your needs.

Book a Free Consultation →
info@keyoagency.com • keyoagency.com
{/* Run Another */}
)}
); }