Share Fundraising Calculator
An embeddable ROI calculator for nonprofit paid media campaigns with branded PDF reports.
Full-Stack Developer
2025
Next.js · TypeScript · Puppeteer · Vercel Blob
Problem
A nonprofit marketing agency needed a lead generation tool that clients could embed on their Webflow sites. The calculator estimates ROI for paid advertising across two funnel strategies and generates downloadable reports for lead capture.
- —Must work embedded on third-party Webflow sites with unknown origins
- —PDF reports need to match the branded web design exactly—custom fonts, layout, colors
- —Slider interactions need to feel instant despite recalculating ROI across four time horizons
Key Decisions
Client-side calculations
useMemo-based calculation engine instead of API calls for slider updates
11 interdependent variables recalculated on every slider move. Server roundtrips would add 200ms+ latency per interaction. All math runs client-side; API only handles file generation.
Puppeteer for PDF generation
Browser automation over lightweight PDF libraries
Client required exact visual parity between web and PDF. Puppeteer renders actual HTML with embedded Base64 fonts (FuturaPT family), reusing the same styles. Trade-off: ~5s cold starts on serverless, but eliminates manual layout recreation.
IIFE widget bundle
Self-contained esbuild bundle with absolute API URLs
Widget runs inside iframes on unknown Webflow domains. Relative URLs resolve to the wrong origin. Bundle is fully self-contained, uses absolute production URLs, and exposes a single global entry point. iframe-resizer handles dynamic height adjustment.
Embedding on third-party sites
Webflow embedding required CORS headers with wildcard origin (embedding domains are unknown at deploy time). Preflight OPTIONS requests required explicit handling in addition to POST routes.
Rate limiting by IP broke when all requests came through Webflow's CDN. Fixed by checking x-forwarded-for, x-real-ip, and cf-connecting-ip headers in priority order.
Lead data flows to Google Sheets (no database). If Sheets API fails, files still generate—graceful degradation keeps the lead capture working.

Outcomes
- —Slider interactions under 20ms with 11-variable calculation engine
- —Works on any Webflow site—tested across three client domains
- —PDF/CSV generation with 3 req/min rate limiting and automatic 14-day cleanup
- —Lead data logged to Google Sheets with graceful fallback if API unavailable