Skip to content

sprawf/geoscore

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

15 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

GeoScore β€” SEO & AI Visibility Audit Tool

GeoScore β€” Free SEO & AI Visibility Audit

A free, open-source SEO and AI-visibility audit tool that analyses any website in under 60 seconds. Built entirely on Cloudflare's free tier (Workers, Pages, D1, KV, Vectorize, Workers AI).

Live demo β†’ geoscoreapp.pages.dev
Example β†’ stripe.com audit


What it audits

Category What's checked
Technical SEO Crawlability, canonical, hreflang, sitemap, robots.txt, security headers, page weight, render-blocking scripts
On-Page SEO Title, meta description, headings, internal links, PageSpeed / Core Web Vitals (mobile + desktop)
Schema Markup JSON-LD detection, coverage gaps, e-commerce schema audit
Content Quality Word count, readability (Flesch), keyword density, FAQ detection
Off-Page SEO Backlink signals, social profile detection, SPF/DMARC/DKIM email security
Domain Authority Domain age, Wikipedia/Wikidata presence, backlink sample
AI Visibility (GEO) Citation prediction β€” simulates whether ChatGPT/Claude/Perplexity would cite your site for relevant queries
Keywords Opportunity keywords by intent (informational, commercial, transactional) with geo-potential flags
Accessibility WCAG 2.1 A/AA checks β€” alt text, labels, skip links, landmarks, heading hierarchy
Security Audit CSP, HSTS, X-Frame-Options, referrer policy, SSL certificate validity
Site Intelligence IP, hosting org, CDN, DNS, MX, carbon footprint estimate
Redirect Chain Hop count, HTTPS redirect, www/non-www normalisation

Computed cards (assembled from module data):

  • SERP snippet preview & character-count warnings
  • Social share card (OG/Twitter) with completeness audit
  • E-E-A-T scorecard
  • Technology stack (Wappalyzer-style)
  • Readability score
  • Font performance
  • DNS & network
  • AI Content Insights (business context, trust scores, freshness, opportunities)
  • llms.txt generator

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     SSE stream      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Cloudflare Pages    β”‚ ◄──────────────────  β”‚  Cloudflare Worker   β”‚
β”‚  (frontend/*)        β”‚                      β”‚  (src/index.ts)      β”‚
β”‚  Static HTML + JS    β”‚  REST + SSE          β”‚                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                      β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
                                              β”‚  β”‚  D1 (SQLite)   β”‚  β”‚
                                              β”‚  β”‚  KV (cache)    β”‚  β”‚
                                              β”‚  β”‚  Vectorize     β”‚  β”‚
                                              β”‚  β”‚  Workers AI    β”‚  β”‚
                                              β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
                                              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Each audit module runs in parallel. Results stream back to the browser via Server-Sent Events so the UI fills in card by card as checks complete.


Fork & Deploy in ~10 minutes

Prerequisites


Step 1 β€” Clone & install

git clone https://github.com/YOUR_USERNAME/geoscore.git
cd geoscore
npm install

Step 2 β€” Authenticate Wrangler

npx wrangler login

This opens a browser window to authorise Wrangler with your Cloudflare account.


Step 3 β€” Create Cloudflare resources

Run each command and note the IDs printed β€” you'll need them in Step 4.

# D1 database
npx wrangler d1 create audit-db

# KV namespaces
npx wrangler kv namespace create AUDIT_KV
npx wrangler kv namespace create BUDGET_KV

# Vectorize index (768 dims = Workers AI embedding size)
npx wrangler vectorize create audit-vectors --dimensions=768 --metric=cosine

Step 4 β€” Configure wrangler.toml

cp wrangler.toml.example wrangler.toml

Open wrangler.toml and replace the placeholder values with the IDs from Step 3:

[[d1_databases]]
database_id = "YOUR_D1_DATABASE_ID"    # ← paste here

[[kv_namespaces]]
binding = "AUDIT_KV"
id = "YOUR_AUDIT_KV_ID"               # ← paste here

[[kv_namespaces]]
binding = "BUDGET_KV"
id = "YOUR_BUDGET_KV_ID"              # ← paste here

Also update the NOMINATIM_USER_AGENT variable with your own contact info (required by OpenStreetMap's terms of use):

[vars]
NOMINATIM_USER_AGENT = "YourAppName/1.0 (you@yourdomain.com)"

Note: wrangler.toml is in .gitignore so your IDs are never committed. Only wrangler.toml.example is tracked.


Step 5 β€” Apply database migrations

# Local development
npm run db:migrate:local

# Remote (production)
npm run db:migrate

Step 6 β€” Point the frontend at your Worker

Open frontend/app.js and update line 1:

// Change this:
const API = 'https://audit-api.sprawf.workers.dev';

// To your Worker's URL (you get this after deploying in Step 7):
const API = 'https://audit-api.YOUR_SUBDOMAIN.workers.dev';

Tip: Your Cloudflare subdomain is shown at dash.cloudflare.com β†’ Workers & Pages β†’ Overview.


Step 7 β€” Deploy

# Deploy the Worker (backend)
npm run deploy

# Deploy the frontend to Cloudflare Pages
npm run deploy:pages

The first deploy:pages run will prompt you to create a new Pages project β€” just accept the defaults.

Your audit tool is now live at https://audit-api.YOUR_SUBDOMAIN.workers.dev (API) and the URL printed by the Pages deploy command (frontend).


Step 8 (optional) β€” Local development

npm run dev

This starts a local Wrangler dev server at http://127.0.0.1:8787. The frontend at frontend/index.html can be opened directly in a browser β€” it will talk to your local Worker.


Optional features

Email alerts (weekly score monitoring)

The tool has a built-in monitoring system that re-audits subscribed domains weekly and emails if the score changes β‰₯5 points. It uses Resend (free tier: 3,000 emails/month).

  1. Sign up at resend.com and get an API key
  2. Add it as a secret (never put it in wrangler.toml):
npx wrangler secret put RESEND_API_KEY

SearXNG (fallback search)

For keyword research, the tool optionally calls a SearXNG instance. Set the URL in wrangler.toml:

SEARXNG_URL = "https://your-searxng-instance.com"

Leave it empty to skip (keyword module uses Workers AI fallback instead).


Environment variables reference

Variable Required Description
NOMINATIM_USER_AGENT Yes Your app name + contact email for OpenStreetMap geocoding API
SEARXNG_URL No URL of a SearXNG search instance
DAILY_BROWSER_BUDGET_SECONDS No Max seconds/day for browser-based checks (default: 540)
RESEND_API_KEY No Resend API key for weekly monitoring alert emails

Project structure

geoscore/
β”œβ”€β”€ frontend/               # Static site (Cloudflare Pages)
β”‚   β”œβ”€β”€ index.html          # Single-page app shell
β”‚   β”œβ”€β”€ app.js              # All UI logic (~3 700 lines)
β”‚   β”œβ”€β”€ print.css           # Print stylesheet
β”‚   β”œβ”€β”€ _headers            # Cloudflare Pages HTTP headers
β”‚   └── _redirects          # Cloudflare Pages redirects
β”‚
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ index.ts            # Worker entry point & router
β”‚   β”œβ”€β”€ lib/
β”‚   β”‚   β”œβ”€β”€ bot-detection.ts  # WAF/CAPTCHA page detection
β”‚   β”‚   β”œβ”€β”€ cache.ts          # KV audit caching
β”‚   β”‚   β”œβ”€β”€ http.ts           # Fetch with timeout helper
β”‚   β”‚   β”œβ”€β”€ llm.ts            # Workers AI wrapper
β”‚   β”‚   β”œβ”€β”€ rate-limit.ts     # Per-IP rate limiting via KV
β”‚   β”‚   β”œβ”€β”€ sse.ts            # Server-Sent Events helpers
β”‚   β”‚   └── types.ts          # Shared TypeScript types (Env, etc.)
β”‚   β”‚
β”‚   β”œβ”€β”€ modules/            # One file per audit module
β”‚   β”‚   β”œβ”€β”€ accessibility.ts
β”‚   β”‚   β”œβ”€β”€ ai_content_insights.ts
β”‚   β”‚   β”œβ”€β”€ authority.ts
β”‚   β”‚   β”œβ”€β”€ content_quality.ts
β”‚   β”‚   β”œβ”€β”€ crux.ts           # Chrome UX Report (CrUX) API
β”‚   β”‚   β”œβ”€β”€ domain_intel.ts
β”‚   β”‚   β”œβ”€β”€ geo_predicted.ts  # AI citation prediction
β”‚   β”‚   β”œβ”€β”€ keywords.ts
β”‚   β”‚   β”œβ”€β”€ off_page_seo.ts
β”‚   β”‚   β”œβ”€β”€ on_page_seo.ts
β”‚   β”‚   β”œβ”€β”€ recommendations.ts
β”‚   β”‚   β”œβ”€β”€ redirect_chain.ts
β”‚   β”‚   β”œβ”€β”€ resolver.ts
β”‚   β”‚   β”œβ”€β”€ schema_audit.ts
β”‚   β”‚   β”œβ”€β”€ security_audit.ts
β”‚   β”‚   β”œβ”€β”€ site_intel.ts
β”‚   β”‚   β”œβ”€β”€ ssl_cert.ts
β”‚   β”‚   └── technical_seo.ts
β”‚   β”‚
β”‚   β”œβ”€β”€ prompts/            # AI prompt templates
β”‚   β”‚
β”‚   └── routes/             # HTTP route handlers
β”‚       β”œβ”€β”€ audit.ts        # Main audit orchestrator (SSE streaming)
β”‚       β”œβ”€β”€ businesses.ts
β”‚       β”œβ”€β”€ chat.ts         # AI chat about audit results
β”‚       β”œβ”€β”€ feedback.ts     # User corrections + learning
β”‚       β”œβ”€β”€ fix.ts          # AI-generated fix guides
β”‚       β”œβ”€β”€ history.ts      # Score history per domain
β”‚       β”œβ”€β”€ llms_gen.ts     # llms.txt generator
β”‚       └── search.ts       # Domain search
β”‚
β”œβ”€β”€ migrations/             # D1 SQL schema migrations
β”‚   β”œβ”€β”€ 0001_init.sql
β”‚   β”œβ”€β”€ 0002_seed_uae.sql
β”‚   └── 0003_learning.sql
β”‚
β”œβ”€β”€ wrangler.toml.example   # Config template (copy β†’ wrangler.toml)
β”œβ”€β”€ tsconfig.json
└── package.json

Cloudflare free tier limits

This project is designed to run comfortably within Cloudflare's free tier:

Resource Free limit Typical usage
Workers requests 100,000/day ~1 request per audit
Workers CPU time 10ms per request Each module is async I/O, minimal CPU
D1 reads 5M/day ~50 reads per audit
D1 writes 100K/day ~5 writes per audit
KV reads 100K/day 1–2 reads per audit (cache check)
KV writes 1,000/day 1 write per audit (cache store)
Workers AI ~10K neurons/day Used for keyword + GEO + AI insights modules
Pages builds 500/month 1 per frontend deploy

For high-traffic use, the AI modules (geo_predicted, keywords, ai_content_insights) are the first to hit limits. They fall back gracefully when quota is exceeded.


Contributing

Pull requests welcome. Each module is isolated in src/modules/ β€” adding a new audit check means creating a new file and wiring it in src/routes/audit.ts.


License

MIT β€” do whatever you want with it. Attribution appreciated but not required.

About

Free, open-source SEO & AI visibility audit tool. Built on Cloudflare Workers + Pages + D1 + Workers AI. Fork & deploy in ~10 minutes on the free tier.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors