This document outlines how to verify each Cloudflare enhancement feature.
- Deploy to Cloudflare Pages (push to main or preview deploy)
- Ensure secrets are set in CF dashboard:
BUTTONDOWN_API_KEYTURNSTILE_SECRET_KEY
Test: Check response headers on any page
curl -I https://jvalentini.pages.dev/Expected Headers:
X-Frame-Options: DENYX-Content-Type-Options: nosniffReferrer-Policy: strict-origin-when-cross-originPermissions-Policy: interest-cohort=()
Verify: Use securityheaders.com for a grade.
Test: Check for Link header on HTML pages
curl -I https://jvalentini.pages.dev/blog/Expected: Link header with font preload directives
Verify: Check Chrome DevTools → Network → filter for fonts, look for "early" in initiator column.
Test: Submit the newsletter form on any page
- Go to https://jvalentini.pages.dev/
- Enter email in newsletter form
- Complete Turnstile (should be automatic)
- Click Subscribe
Expected:
- Success message appears
- Email shows up in Buttondown dashboard
- If already subscribed: "Already subscribed!" message
API Test:
curl -X POST https://jvalentini.pages.dev/api/subscribe \
-H "Content-Type: application/json" \
-d '{"email": "test@example.com"}'Test: Newsletter form shows Turnstile widget
- Load any page with newsletter
- Turnstile widget should render (dark theme, compact)
- Submit without completing → should fail with "Bot verification failed"
Verify: Check Cloudflare Dashboard → Turnstile → Analytics
Test: Check for A/B cookie and headers
curl -I https://jvalentini.pages.dev/ -c cookies.txt
cat cookies.txt # Look for ab_bucket=A or ab_bucket=BExpected Headers:
X-AB-Bucket: AorX-AB-Bucket: BX-Visitor-Timezone: America/New_York(varies)X-Visitor-Country: US(varies)X-Visitor-LocalTime: 3:45 PM(varies)
Test: Headers contain visitor timezone info
curl -I https://jvalentini.pages.dev/Expected: X-Visitor-Timezone header with IANA timezone
Frontend Usage: The LocalTime.astro component converts dates to visitor's local timezone automatically.
Test: Default short links work
curl -I https://jvalentini.pages.dev/go/github
curl -I https://jvalentini.pages.dev/go/twitter
curl -I https://jvalentini.pages.dev/go/rssExpected: 302 redirect to target URL
Create Custom Link (requires ADMIN_KEY secret):
curl -X POST https://jvalentini.pages.dev/api/links \
-H "Authorization: Bearer YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"slug": "mylink", "url": "https://example.com"}'Test: Page views are tracked
- Visit any page
- Check Cloudflare Dashboard → Workers & Pages → blog → Analytics Engine
Query data via API:
curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/analytics_engine/sql" \
-H "Authorization: Bearer {api_token}" \
-d "SELECT * FROM blog_analytics LIMIT 10"Test: View counts are stored
# Get view count for a page
curl "https://jvalentini.pages.dev/api/track?path=/blog/worklog"
# Increment view count
curl -X POST https://jvalentini.pages.dev/api/track \
-H "Content-Type: application/json" \
-d '{"path": "/blog/worklog", "event": "pageview"}'Expected: JSON with path and count
Test: Dates render in visitor's timezone
- Visit a blog post
- Check date display
- Hover over date for full timestamp
Expected: Shows relative time (e.g., "2d ago") with local timezone tooltip
Run this after every deploy:
# 1. Headers present
curl -sI https://jvalentini.pages.dev/ | grep -E "X-Frame|X-Content-Type|X-AB-Bucket"
# 2. Short links work
curl -sI https://jvalentini.pages.dev/go/rss | grep "location"
# 3. API responds
curl -s https://jvalentini.pages.dev/api/track?path=/ | jq .
# 4. Newsletter endpoint exists
curl -sX POST https://jvalentini.pages.dev/api/subscribe \
-H "Content-Type: application/json" \
-d '{"email": ""}' | jq .| Issue | Solution |
|---|---|
| Newsletter returns 500 | Check BUTTONDOWN_API_KEY secret is set |
| Turnstile always fails | Check TURNSTILE_SECRET_KEY secret is set |
| Short links 404 | Ensure KV namespace is bound in wrangler.toml |
| View counts not updating | Ensure D1 database is bound and migration ran |
| No timezone headers | Middleware may not be running - check functions/_middleware.ts |