Tazcreates
Tazcreates is the commission site for Tazmeen Zabiyaan, a portrait artist based in Canada working in acrylic, oil pastel, and ink. It is one page — gallery, pricing, process, FAQ — ending in a commission form that is a public endpoint anyone can post to, deployed on Cloudflare Workers under a 3 MiB free-plan script budget.
- Client
- Tazcreates
- Timeline
- 2026
- Role
- Full-Stack Engineer
- gzipped removed from the Worker payload
- 820 KBgzipped removed from the Worker payload
- reduction in compiled script size
- 21%reduction in compiled script size
- free-plan Workers script limit
- 3 MiBfree-plan Workers script limit
- checks before an email is sent
- 5checks before an email is sent
Key takeaways
- Cloudflare Pages could not host this site: @cloudflare/next-on-pages is deprecated and does not support Next 16, so the build moved to @opennextjs/cloudflare on Workers.
- Rendering the social card once at build time into public/og.png removed 820 KB gzipped from the Worker payload, because next/og pulls resvg.wasm and yoga.wasm into the runtime graph.
- The commission endpoint runs five checks — schema parse, honeypot, per-IP rate limit, server-side Turnstile verification, then send — before any email leaves, and the recipient address is always read from the environment rather than the request body.

The problem
A commission form is the whole business case for an artist's site, and it is also the part that attracts abuse: it is a public endpoint that spends money on every send and can be pointed at arbitrary recipients if it is written carelessly. The deployment added a second constraint. The original Cloudflare Pages build failed outright — @cloudflare/next-on-pages is deprecated and has no Next 16 support — and the Workers plan that replaced it caps a compiled script at 3 MiB gzipped, which the first build exceeded.
The approach
The site migrated to @opennextjs/cloudflare, which compiles the Next output into a Worker plus a static asset directory. Getting under the script limit was a measurement exercise, not a guess: deleting unreachable files moved the payload zero bytes because Next never bundled them, while moving the social card out of next/og and into a build-time script removed 820 KB. Static assets are served from Cloudflare's asset store and do not count against the limit. The commission route re-parses every submission against the same Zod schema the form uses, treats a filled honeypot as a silent success so bots learn nothing, rate-limits per IP before spending a Turnstile call, verifies the captcha token server-side and fails closed on a verification outage, and only then sends — always to the configured address, never to one supplied in the payload.
What it does
- Single-page build: hero, masonry gallery with lightbox, pricing tiers, commission process, FAQ
- Commission form validated by one Zod schema shared between the client and the API route
- Honeypot, per-IP rate limit, and server-verified Cloudflare Turnstile in front of every send
- Resend + React Email delivery, with a best-effort confirmation back to the visitor
- Reduced-motion-aware marquee and scroll reveals
- Server-rendered JSON-LD and a build-time Open Graph card
- Deployed to Cloudflare Workers via OpenNext, with the custom domain pinned in wrangler.jsonc
Stack
Outcome
Compiled Worker script reduced 21%, from 3,833,495 to 3,013,678 bytes gzipped, fitting the 3 MiB free-plan limit
Commission requests reach the artist by email instead of only through Instagram direct messages
Deployed on Cloudflare Workers after the deprecated Pages adapter blocked the original build
References
- Tazcreates
- OpenNext Cloudflare adapter — OpenNext
- Cloudflare Turnstile — Cloudflare
Tazcreates — questions
Common questions about Tazcreates and how it was built.
Building something similar?
I'm open to new opportunities and project work.