A static site for awarding the Big Beautiful Peace Prize. Visitors fill in a recipient's name and achievement, preview the certificate, and send it directly to the recipient's inbox.
Live site: https://bigbeautifulpeaceprize.com
- Static site: Plain HTML/CSS/JS (no build step)
- Hosting: Cloudflare Pages (free tier)
- Certificate rendering & delivery: parchment Cloudflare Worker
- Bot protection: Cloudflare Turnstile (managed challenge widget)
- Source control: GitHub (nopolabs/bbpp)
| Service | Cost |
|---|---|
| Cloudflare Pages | $0 |
| Domain | ~$1 amortized |
| Total fixed cost | ~$0/month |
bbpp/
├── src/
│ ├── index.html # Single-page app — form, preview, confirmation
│ ├── assets/
│ │ └── bbpp-seal.png # Prize seal image used in the certificate
│ ├── _headers # Cloudflare Pages HTTP response headers
│ └── favicon.* # Favicons
└── functions/
└── parchment/
└── [[path]].ts # Catch-all Pages Function: Turnstile guard + parchment proxy
- Visitor fills in recipient name, achievement (optional), and email
- Preview fetches
GET /parchment/render?name=...→ proxied to the parchment worker → returns a certificate PNG - Visitor completes the Cloudflare Turnstile challenge (unlocks the Award the Prize button)
- Award the Prize posts
POST /parchment/issuewith the Turnstile token - The
functions/parchment/[[path]].tsPages Function intercepts the POST:- Verifies the Turnstile token with Cloudflare's
v0/siteverifyAPI - On success, forwards the request to the parchment worker with an API key in the
Authorizationheader
- Verifies the Turnstile token with Cloudflare's
- Parchment renders the certificate and emails it to the recipient via Resend
No build step needed — open src/index.html directly in a browser for UI work.
To develop the Pages Function locally:
npx wrangler pages dev src --compatibility-date=2024-09-23Create a .dev.vars file in the repo root for local secrets (never commit this):
PARCHMENT_BASE_URL=https://parchment-worker-bbpp.danrevel.workers.dev
PARCHMENT_API_KEY=...
TURNSTILE_SECRET_KEY=1x0000000000000000000000000000000AA
The
TURNSTILE_SECRET_KEYvalue above is Cloudflare's "always pass" test secret — use it locally so you don't need to solve a real challenge. Use the real secret in production.
Deployment is automatic — push to main on GitHub and Cloudflare Pages builds and deploys.
- Build command: (none)
- Build output directory:
src
Set these once in Cloudflare (not in source):
npx wrangler pages secret put PARCHMENT_BASE_URL --project-name bbpp
npx wrangler pages secret put PARCHMENT_API_KEY --project-name bbpp
npx wrangler pages secret put TURNSTILE_SECRET_KEY --project-name bbpp| Secret | Value |
|---|---|
PARCHMENT_BASE_URL |
https://parchment-worker-bbpp.danrevel.workers.dev |
PARCHMENT_API_KEY |
BBPP_KEY (must match ISSUE_API_KEY on parchment-worker-bbpp) |
TURNSTILE_SECRET_KEY |
From Cloudflare Turnstile dashboard for site key 0x4AAAAAADCnY8bWziMBe6XP |
The Turnstile site key 0x4AAAAAADCnY8bWziMBe6XP is configured for bigbeautifulpeaceprize.com in the Cloudflare Turnstile dashboard.
The widget is embedded in src/index.html with data-callback="onTurnstileSuccess", which enables the Award the Prize button when the challenge passes.
- The
/parchment/issueendpoint is protected by two layers:- Turnstile — the Pages Function rejects any POST without a valid Turnstile token (prevents bots)
- API key — the parchment worker rejects any request without a valid
Authorization: Bearerheader (prevents direct calls to the worker that bypass Turnstile)
- The parchment worker is only reachable at its
workers.devURL — no custom domain route — so all public traffic flows through the Pages Function