A standalone TypeScript Cloudflare Worker API that scans websites and returns comprehensive health reports.
Live API: https://wwwmw.captainpragmatic.com Frontend: https://captainpragmatic.com/tools/website-health-scanner
- 8 Diagnostic Checks: SSL, DNS, PageSpeed, Server Response, Mobile, HTTPS, Availability, Email Config
- 100-Point Scoring System: Automatic health score with color-coded levels
- Real-Time Analysis: 6-15 second response time with parallel check execution
- Smart Recommendations: Actionable advice based on specific issues found
- CORS Ready: Pre-configured for frontend integration
src/
├── index.ts # Main handler & request routing
├── types.ts # TypeScript interfaces
├── services/ # Diagnostic services (6 modules)
│ ├── ssl-check.ts # HTTPS/TLS verification
│ ├── dns-speed.ts # DNS resolution timing
│ ├── pagespeed-check.ts # Google PageSpeed API
│ ├── server-response.ts # TTFB measurement
│ ├── availability-check.ts # Up/down status
│ └── email-config.ts # MX record lookup
└── utils/ # Helper functions
├── validation.ts # URL validation
├── cors.ts # CORS headers
├── errors.ts # Error responses
└── scoring.ts # Score calculation & recommendations
Scan a website and return health report.
Parameters:
url(required): Website URL to scan (http:// or https://)
Response:
{
"url": "https://example.com",
"timestamp": "2024-01-15T10:30:00Z",
"overallScore": 85,
"scoreLevel": "GOOD - Minor improvements needed",
"scoreColor": "#17a2b8",
"checks": {
"ssl": { "status": "pass", "message": "...", "score": 10, "details": {} },
"dns": { "status": "pass", "message": "...", "score": 10, "details": {} },
"serverResponse": {
"status": "pass",
"message": "...",
"score": 15,
"details": {}
},
"pageSpeed": {
"status": "warn",
"message": "...",
"score": 10,
"details": {}
},
"mobile": {
"status": "pass",
"message": "...",
"score": 15,
"details": {}
},
"https": { "status": "pass", "message": "...", "score": 10, "details": {} },
"availability": {
"status": "pass",
"message": "...",
"score": 15,
"details": {}
},
"email": { "status": "pass", "message": "...", "score": 10, "details": {} }
},
"criticalIssues": [],
"recommendations": ["Consider optimizing images..."]
}Status Codes:
200: Scan successful400: Invalid URL or missing parameter404: Endpoint not found500: Internal server error
Health check endpoint.
Response:
OK
- Node.js 18+
- Cloudflare account with Workers enabled
- Google Cloud account for PageSpeed API
-
Clone and install dependencies:
git clone https://github.com/captainpragmatic/wwwmw.git cd wwwmw npm install -
Login to Cloudflare:
npx wrangler login
-
Get Google PageSpeed API Key:
- Go to https://console.cloud.google.com/apis/credentials
- Enable "PageSpeed Insights API"
- Create Credentials → API Key
- Restrict key to PageSpeed Insights API
- Copy the key
-
Configure secrets for local development:
# Wrangler uses .dev.vars for local development secrets echo "GOOGLE_PAGESPEED_API_KEY=your_api_key_here" > .dev.vars
Note:
.dev.varsis git-ignored. Never commit API keys!
# Start dev server
npm run dev
# Test endpoints
curl "http://localhost:8787/health"
curl "http://localhost:8787/?url=https://google.com"-
Add GitHub Secrets:
- Go to https://github.com/captainpragmatic/wwwmw/settings/secrets/actions
- Add
CLOUDFLARE_API_TOKEN:- Cloudflare Dashboard → My Profile → API Tokens
- Create Token → "Edit Cloudflare Workers" template
- Zone Resources: Include → captainpragmatic.com
- Copy token → Add as secret
- Add
GOOGLE_PAGESPEED_API_KEY:- Use API key from setup step above
-
Deploy:
git add . git commit -m "Update worker" git push origin main # GitHub Actions automatically deploys!
-
Monitor deployment:
- Go to https://github.com/captainpragmatic/wwwmw/actions
- View deployment logs
# Deploy to production
npm run deploy# Set secrets in Cloudflare Workers
npx wrangler secret put GOOGLE_PAGESPEED_API_KEY
# Paste your API key when promptedConfigure custom domain in Cloudflare Dashboard:
- Log into Cloudflare
- Select domain:
captainpragmatic.com - Go to: Workers & Pages → Routes
- Add route:
wwwmw.captainpragmatic.com/*→ Worker:wwwmw-api
Or configure via wrangler.toml (already set):
routes = [
{ pattern = "wwwmw.captainpragmatic.com/*", zone_name = "captainpragmatic.com" }
]# Health check
curl https://wwwmw.captainpragmatic.com/health
# Scan a site
curl "https://wwwmw.captainpragmatic.com/?url=https://google.com"
# Test different scenarios
curl "https://wwwmw.captainpragmatic.com/?url=http://example.com" # HTTP site
curl "https://wwwmw.captainpragmatic.com/?url=invalid" # Invalid URL
curl "https://wwwmw.captainpragmatic.com/" # Missing param- Response time: 6-15 seconds (mostly waiting on PageSpeed API)
- CPU time: <5ms (under Cloudflare's 10ms limit)
- All checks return real data
- CORS headers present
- Errors are user-friendly
Total: 100 points
| Check | Points | Criteria |
|---|---|---|
| SSL | 10 | HTTPS enabled & valid certificate |
| DNS | 10 | <200ms=pass, 200-500ms=warn, >500ms=fail |
| Server Response | 15 | TTFB <200ms=pass, 200-500ms=warn, >500ms=fail |
| PageSpeed | 15 | Score ≥90=pass, 50-89=warn, <50=fail |
| Mobile | 15 | Derived from PageSpeed mobile score |
| HTTPS | 10 | Secure protocol & valid SSL |
| Availability | 15 | 2xx status code |
| Email Config | 10 | MX records configured |
Score Levels:
- 85-100: EXCELLENT - Great website health! (green #28a745)
- 70-84: GOOD - Minor improvements needed (blue #17a2b8)
- 50-69: NEEDS WORK - Several issues to fix (yellow #ffc107)
- 0-49: POOR - Serious problems detected (red #dc3545)
View analytics in Cloudflare Dashboard:
- Workers & Pages → wwwmw-api → Analytics
- Metrics: Requests, CPU time, errors, duration
Real-time logs:
npx wrangler tailFree tier (up to 100k requests/day):
- Cloudflare Workers: $0
- Google PageSpeed API: $0 (25,000 queries/day free)
Expected usage:
- <10k requests/month initially
- $0/month cost
- Check Cloudflare Workers logs:
npx wrangler tail - Verify
GOOGLE_PAGESPEED_API_KEYsecret is set - Check PageSpeed API quota: https://console.cloud.google.com/apis/api/pagespeedonline.googleapis.com/quotas
- Verify CORS origin in
src/utils/cors.ts - Check response headers include
Access-Control-Allow-Origin
- API has 30-second timeout
- Slow sites may exceed this
- System gracefully degrades (returns warning with 8 points)
- Cloudflare DNS-over-HTTPS may be blocked in some networks
- Check firewall rules
src/index.ts- Main entry point, routes requestssrc/services/- Each check is isolated in its own modulesrc/utils/- Shared utilities (validation, scoring, CORS)src/types.ts- TypeScript type definitions
- Create service file:
src/services/new-check.ts - Export async function returning
CheckResult - Import in
src/index.tsand add toPromise.all() - Update scoring in
src/utils/scoring.ts - Add points to total (adjust other checks to maintain 100 points)
- TypeScript strict mode enabled
- Async/await for all I/O
- 5-30 second timeouts on external calls
- Graceful degradation on API failures
- Never expose API keys in responses
See: https://github.com/captainpragmatic/captainpragmatic.com
Update assets/js/tools/website-scanner-alpine.js:
async scan() {
this.isScanning = true;
try {
const response = await fetch(
`https://wwwmw.captainpragmatic.com/?url=${encodeURIComponent(this.inputs.url)}`
);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
this.results = this.formatResults(data);
this.showResults = true;
} catch (error) {
alert(`Scan failed: ${error.message}`);
} finally {
this.isScanning = false;
}
}MIT
Issues: https://github.com/captainpragmatic/wwwmw/issues Main site: https://captainpragmatic.com