Your own viral giveaway, running in your accounts, for $0. One careful pass through these steps and you're live.
Version 3
π¦ READ THIS FIRST β WHICH ZIP GOES WHERE
The file giveawaykit-site-v3-β¦.zip goes to a Cloudflare Pages project named
giveawaykit-contest β a NEW project, created in YOUR Cloudflare account (Step 4).
Never upload it over some other site's project. The full-kit zip is just the whole folder
(this installer + the site/ and worker/ folders) for your files β it doesn't get uploaded anywhere.
π§ͺ Fresh-account / no-domain TEST MODE
Just want to try it first β maybe on a brand-new Cloudflare account, with no domain at all?
That's a perfect first run. Here's the shortcut path:
A brand-new Cloudflare account works fine. The first time you create a Worker,
Cloudflare will ask you to pick your workers.dev subdomain (something like
yourname.workers.dev). That's normal β every account does it once. Pick anything you like.
You do NOT need a custom domain β not for the test, not even for a real launch.
Your site gets a complete free address, giveawaykit-contest.pages.dev, and your API gets
giveawaykit-api.<your-subdomain>.workers.dev. Those addresses work on their own, forever.
A custom domain (Step 4, optional) is just nicer branding, later.
Skip Step 3 (Resend) entirely on your first run. The contest page, the admin, entries,
bonuses and the draw all work β emails simply stay off until email is set up. Nothing breaks.
Switching emails on later is easy: verify one domain you own in Resend (Step 3).
The DNS records for that domain go wherever that domain's DNS actually lives β that might be a
different Cloudflare account, or GoDaddy, or anywhere else. That's fine and normal: the Worker doesn't care
which account holds the DNS. The only rule: MAIL_FROM must be an address on that verified domain.
So the test path is simply: Step 1 β Step 2 β Step 4 β Step 5, and add Step 3 whenever you're ready for emails.
0Overview β what you're about to build
You will create 4 free things, all in YOUR OWN accounts:
βοΈ A Cloudflare D1 database (your entrants live here)
βοΈ A Cloudflare Worker (the engine)
π A Cloudflare Pages site (the contest page people see)
βοΈ A Resend API key (sends the emails β optional on day one, see Test Mode)
Time: about 10β15 minutes. Cost: $0. The best part:
everything stays yours. No platform can shut your contest down, raise its price, or hold your list hostage β
because none of it runs on anyone else's system but yours.
1The database (Cloudflare D1)
In Cloudflare, go to Storage & Databases β D1 SQL Database β Create database.
Name it exactly: giveawaykit
That's it. Leave it completely EMPTY.
β οΈ Never paste SQL anywhere. There is no schema file to run and nothing to
import. The Worker builds its own tables, by itself, the first time it is called. An empty database is the
correct starting point β if a step ever asks you for SQL, you're on the wrong screen.
2The engine (Cloudflare Worker)
In Cloudflare, go to Workers & Pages β Create β Worker, name it
giveawaykit-api and click Deploy
(the temporary "Hello World" page is normal).
First time on this account? Cloudflare may first ask you to choose your
workers.dev subdomain. That's a one-time, normal step for every new account β pick a name and continue.
Open the Worker β Edit code β select all β delete β paste the entire contents of
worker/worker.js from this kit β Deploy.
Add your variables & secrets: Worker β Settings β Variables and Secrets β Add:
ADMIN_KEY
Secret. A password you invent β it opens your contest admin. Keep it somewhere safe.
RESEND_API_KEY
Secret. From Step 3. Skip it for now if you're in Test Mode β add it later, same screen.
MAIL_FROM
Text. Your sender, like Your Brand <contest@yourdomain.com> β the address must be on your Resend-verified domain (Step 3).
SITE_BASE
Text, optional. Your contest's public address (from Step 4, e.g. https://giveawaykit-contest.pages.dev). You can come back and add it after Step 4.
Write down your Worker address β it looks like
https://giveawaykit-api.<your-subdomain>.workers.dev. You'll need it in Step 4.
3Email (Resend) β optional on day one
In Test Mode? Skip this whole step for now and come back when you want emails on.
Create a free account at Resend.
Domains β Add domain β add a domain you own.
Resend shows you a few DNS records to add. Add them where that domain's DNS lives:
If the domain's DNS is on Cloudflare: DNS β Records β Add record, one by one.
If it's at GoDaddy or another registrar: add them there instead. Either way is fine β
the DNS does not need to live in the same Cloudflare account as your contest.
Wait for the domain to show Verified in Resend (usually a few minutes).
API Keys β Create API Key β permission: Sending access β copy the key into
RESEND_API_KEY back in Step 2, and make sure MAIL_FROM is an address on this verified domain.
π‘ How email behaves: until the domain is verified and the key is set,
the contest still works perfectly β the Worker simply skips sending, safely, with no errors for your visitors.
The moment both are in place, every automated email (confirmation, mid-contest reminder, final-24-hours, winner,
non-winner) starts working instantly. No code change, no redeploy of the site.
4The contest page (Cloudflare Pages)
Open site/app.js in any text editor. Right at the top, one clearly marked line says
const API_BASE = "https://YOUR-WORKER.workers.dev"; β replace the address with
your Worker address from Step 2. Save. That's the only code edit in the whole install.
Zip the CONTENTS of the site/ folder (the 4 files themselves at the top of the
zip β not a folder inside the zip). The kit also ships a ready-made zip:
giveawaykit-site-v3-β¦.zip β but if you edited app.js, re-zip your edited files.
In Cloudflare: Workers & Pages β Create β Pages β Upload assets β create a
NEW project named giveawaykit-contest
β upload the zip β Deploy.
Your contest now lives at https://giveawaykit-contest.pages.dev. Done β that address is complete on its own.
Optional β your own custom domain
Whenever you're ready: in the Pages project, Custom domains β Set up a domain and attach your
domain or a subdomain (like contest.yourdomain.com). Purely branding β everything works exactly the same
on the free pages.dev address.
π Need a domain for your contest?
Buy it wherever you like β a domain is optional, and the free pages.dev address
works forever. Our recommendation if you do buy one: register it at Namecheap, keep the domain there,
then add it to Cloudflare for free DNS (you just change the nameservers at Namecheap to the ones
Cloudflare gives you). That registrar-there / DNS-on-Cloudflare split is the exact setup this kit is built for β
and it keeps your domain independent of your hosting.
Affiliate note: if you buy through our link, we may earn a small commission β at no extra cost to you. Thank you for supporting the project. π
5Launch check π
Open your Pages address (giveawaykit-contest.pages.dev or your custom domain). You should see
your giveaway page with a generated cover β no broken anything.
Open /admin.html on the same address and log in with your ADMIN_KEY.
On this first visit, the database builds itself β tables, settings, and one starter prize
("Grand Prize β $100 Gift Card") appear on their own.
In the admin's Quick-create: set your real prize, your dates, your Facebook links,
your brand name and colours.
Make a test entry with your own email on the public page.
If email is set up (Step 3): open the confirmation email and click the confirmation link β
you're now eligible in your own draw, and the whole chain is proven.
π You're live. Share your contest link anywhere β your Facebook Page, your site, your
emails. Every entrant gets their own referral link, and the sharing starts working for you.
β¨ After you install β make it yours
The contest already works. These touches make it yours β all in the admin, no code:
The admin speaks FR or EN. Top-right of the admin, the FR | EN pills switch the
interface. Your contest content (titles, prizes, rules, emails) is separate: fill the FR and EN fields of each, as before.
Your public page speaks FR, EN and ES. Visitors get FR | EN | ES pills. The whole frame β
buttons, labels, fine print β is pre-translated in all three and flips instantly. Your content follows per language where
you've written it; Spanish visitors see your English content (no Spanish content fields, by design β nothing is ever
half-translated or left blank).
Two consents, one list. The entry form has TWO checkboxes: the required contest consent, and an
optional marketing one. The optional one never affects who can enter or win β it builds you a
permission-based email list (watch the Mkt column in the entrants table, and the CSV export).
People who entered before this feature existed simply count as "no".
Courriel libre β write any email. Admin β the Courriels (Emails) card β
Courriel libre (Free-form email): any subject, any message, to Tous les participants
(All entrants) or Marketing seulement (Marketing only) via the Envoyer Γ (Send to) selector.
Favourite use: during the contest, one partner spotlight a day β one email, one partner, their prize centre stage.
Your QR code β website, poster, everywhere. Admin β the Code QR (QR code) card: your contest's QR code,
generated right in the admin β no outside service. Download the PNG for anything printed, paste the ready-made
snippet on your website, or open the printable poster (your logo, your colours, one big QR) for the counter or the window.
YouTube & TikTok bonuses. Paste your YouTube and TikTok links in the settings: two new bonus
actions appear beside Facebook and Instagram β subscribe / follow, worth bonus entries (+2 each by default, adjustable like the others).
Relaunch β a new edition in one click. Contest over? Admin β Relancer ce concours (Relaunch): the finished
edition β entrants and winners β is archived safely, the lists start empty, and everything else (prizes, partners, emails, colours)
stays in place, ready for the next round. That's the monthly rhythm: a small giveaway every month, bigger ones around the holidays.
The admin shows a one-line summary of the last archive.
Emails that send themselves. In the Courriels card, tick the auto-send options for the mid-contest reminder
and/or the final-24-hours email, and they go out on schedule by themselves. One smart rule: if you already sent that email by hand,
the automatic one stays quiet β no duplicates, ever. The card shows each one's state (off / scheduled / sent, with the date).
π Troubleshooting
Emails aren't arriving
Is the domain Verified in Resend? (DNS records can take a few minutes.)
Is RESEND_API_KEY actually saved on the Worker (Step 2), with Sending access?
Does MAIL_FROM use an address on that verified domain? A mismatch here is the #1 cause.
Check the spam folder once β then check the three items above again. It's almost always one of them.
The admin won't log me in
You're typing your ADMIN_KEY β the password you invented in Step 2. Check for caps/typos.
Changed it on the Worker? Give it a few seconds and try again.
The page is stuck on "opening soon" / looks empty
API_BASE in site/app.js still says YOUR-WORKER, or has a typo β it must be your exact Worker address, then re-zip and re-upload.
Is the Worker deployed with the kit's worker.js (not "Hello World")? Re-check Step 2.
Is the DB binding in place, pointing at the giveawaykit database?
I'm seeing an old version of the page
Re-upload the zip to the same Pages project (giveawaykit-contest), then hard-refresh
(Ctrl/Cmd + Shift + R). Browsers and CDNs cache hard β this is normal, not a bug.
π
This installer is Version 3 β everything in Version 2, plus Instant Win prizes, your QR code (PNG, website snippet, printable poster), the winners wall, YouTube & TikTok bonus actions, one-click Relaunch for the next edition, and reminder emails that send themselves.
If you got stuck on any step β even for a minute β please write down which step and what confused you
and send it back to us. The next version gets fixed from real installs like yours, and your notes are exactly
what makes it better. Thank you! π