This repository provides a simple, less-distracting frontend for Hot Deals posted on https://forums.redflagdeals.com.
The frontend is a Vite/Vue 3 app. Cloudflare Pages serves the static output, Pages Functions serve /topics.json, /html, and /admin/refresh from Cloudflare KV, and a scheduled Cloudflare Worker refreshes cached topics to avoid excessive requests to RedFlagDeals itself.
flowchart TD
Browser[Browser] -->|GET /| Pages[Cloudflare Pages static assets]
Browser -->|GET /topics.json| TopicsFn[Pages Function: /topics.json]
Browser -->|GET /html| HtmlFn[Pages Function: /html]
TopicsFn -->|read topics.json| KV[(Cloudflare KV: TOPICS_KV)]
HtmlFn -->|read topics.json| KV
Cron[Cloudflare Cron Trigger<br/>every 5 minutes] --> RefreshWorker[Scheduled Worker: rfd-fyi-refresh]
RefreshWorker -->|fetch topic pages| RFD[RedFlagDeals API]
RefreshWorker -->|fetch redirect rules| Redirects[Redirect rules JSON]
RefreshWorker -->|write topics.json| KV
AdminPages[Manual refresh<br/>POST /admin/refresh] --> TopicsRefreshFn[Pages Function: /admin/refresh]
AdminWorker[Manual refresh<br/>GET /refresh] --> RefreshWorker
TopicsRefreshFn -->|fetch topic pages| RFD
TopicsRefreshFn -->|fetch redirect rules| Redirects
TopicsRefreshFn -->|write topics.json| KV
Install dependencies and log in to Cloudflare:
npm ci
npx wrangler loginCreate a KV namespace and a preview namespace:
npx wrangler kv namespace create TOPICS_KV
npx wrangler kv namespace create TOPICS_KV --previewCopy the returned namespace IDs into both:
wrangler.tomlworker/wrangler.toml
Build and deploy the Pages app:
npm run build
npm run pages:deploy
# or
npm run build && just deploy-pagesDeploy the scheduled refresh Worker:
npm run worker:deploy
# or
just deploy-workerDeploy both:
just deployThe Worker runs every 5 minutes and writes the latest topics to KV. Pages reads that cached JSON at /topics.json and renders a no-JavaScript view at /html.
Optional manual refresh endpoints:
# For the Pages /admin/refresh endpoint
npx wrangler pages secret put REFRESH_SECRET --project-name rfd-fyi
curl -X POST -H "Authorization: Bearer $REFRESH_SECRET" https://<your-pages-domain>/admin/refresh
# For the Worker /refresh endpoint
npx wrangler secret put REFRESH_SECRET --config worker/wrangler.toml
curl -H "Authorization: Bearer $REFRESH_SECRET" https://rfd-fyi-refresh.<your-subdomain>.workers.dev/refreshRun the unit test suite:
npm test -- --runRun coverage:
npm run test:coverage -- --runRun linting and a production build:
npm run lint
npm run buildGitHub Actions runs npm ci, tests, linting, and build on every push and pull request.
Run the Cloudflare Pages build locally, including Pages Functions:
npm run pages:devWrangler serves the app at:
http://localhost:8788
Local Pages KV starts empty, so the app may initially show no deals. Seed local KV by calling the manual refresh endpoint in another shell:
curl -X POST -H "Authorization: Bearer dev" http://localhost:8788/admin/refreshA successful refresh returns something like:
{"refreshed":1000}After that, these local endpoints should return populated data:
http://localhost:8788/topics.json
http://localhost:8788/html
To run the scheduled refresh Worker locally:
npm run worker:devFor frontend-only Vite development:
npm run serveThe Vite dev server proxies /topics.json and /html to the configured production Pages origin by default, so it should show live deals without seeding local KV. Override with VITE_API_ORIGIN if needed:
VITE_API_ORIGIN=http://localhost:8788 npm run serve