Setup/Framer project
Worker URL Not set yet Edit

Let's get your academy live

Five sections, about 35 minutes. Each one has a short video and exactly what to copy. Work top to bottom — by the last section you're taking payments.

0 of 5 complete
1
Set up the Framer project
Copy the template into your own Framer account.
3 min
Remixing the template3:05
Remix the starter into your account

Your remix link drops a full copy — landing page, dashboard, and auth screens — into your Framer account. You'll wire it up over the next sections.

framer.com/projects/Course-Maker-Starter?remix=jr-8842Copy
Go at your own pace — nothing is locked.
2
Set up FrameAuth
Make purchase the only way in, then grant access by tag.
10 min
FrameAuth: checkout & access9:20
1Set Account Creation to Checkout

In FrameAuth, open Account Creation — it controls how new users can create accounts and whether they need approval. Set it to Checkout. This makes purchase the only way to get an account: nobody can sign up for the web app without first buying. There's no open registration to gate after the fact.

2Map a tag to your digital product

Create a tag for full access (e.g. members) and attach it to the digital product people buy. When a purchase completes, FrameAuth issues an account and applies that tag automatically — the tag is what corresponds to "this person paid for the product." You'll copy the tag's ID into the Worker in the next section.

No payment code in your Worker. FrameAuth handles checkout, account creation, and tagging. Your Worker only ever reads whether a visitor carries the access tag.

3
Set up the Cloudflare Worker
One Worker, ready to go. Deploy it and set its URL.
8 min
Deploying your Worker7:40

What is a Worker? A Cloudflare Worker is a tiny piece of backend code that runs securely on Cloudflare's global edge network. It acts as the bridge for your app — generating protected download links, securely sending emails via Resend, and validating users so you never have to expose sensitive API keys in your frontend code.

1Paste the Worker and deploy

This is the only Worker you need — the same one in Library → Worker, where you set your submission limits. In Cloudflare open Workers & Pages → Create → Edit code, clear the default, paste this, and hit Deploy. Don't edit it.

2Add your FrameAuth variables

Under Settings → Variables and Secrets, add these three. Mark FRAMEAUTH_API_KEY as encrypted.

TypeName
PlaintextACADEMY_TAG
SecretFRAMEAUTH_API_KEY
PlaintextFRAMEAUTH_BASE
3Save your Worker URL here

After deploying, Cloudflare shows a URL ending in .workers.dev. Paste it below — it saves to your Dashboard so every component you add later just works. No pasting URLs into code.

https://
Saved to your Dashboard
4
Set up R2 storage
Where your downloadable files live, gated.
6 min
Creating & binding an R2 bucket5:30
1Create the bucket

In Cloudflare go to R2 → Create bucket. Name it exactly this — names can't be changed later:

course-downloadsCopy
2Bind it to your Worker

Open your Worker → Settings → Bindings → Add → R2 bucket. Set the variable name to FILES and choose course-downloads. That binding is what lets the Worker hand out secure, expiring download links.

Variable name:  FILESCopy

The bucket name must match exactly. Anything other than course-downloads and downloads return "file not found" until the names line up.

5
Set up email with Resend
Verify your domain and add your API keys to the Worker.
9 min
Verifying your domain in Resend5:10

This step is required. Until your domain is verified, Resend won't send on your behalf and welcome emails and receipts will bounce or land in spam. Do this before wiring the Worker.

1Add your domain in Resend

In Resend go to Domains → Add Domain and enter the domain you'll send from. Resend gives you a set of DNS records to add at your registrar (Cloudflare, Namecheap, GoDaddy, etc.).

2Add the DKIM, SPF, and DMARC records

Copy each record Resend shows into your DNS. DKIM signs your mail, SPF authorizes Resend's servers to send for you, and DMARC (optional but recommended) tells inboxes how to treat anything that fails. Then flip Enable Sending on.

3Wait for the green checks

DNS can take a few minutes to a couple of hours to propagate. When every record shows a green check in Resend, your domain is verified and you're ready for the next step.

Wiring Resend into the Worker3:40
4Add your two Resend secrets

No new Worker — open your existing one under Settings → Variables and Secrets and add these. Only credentials live here; your email addresses are set in Library → Worker, not as variables.

TypeName
SecretRESEND_API_KEY
PlaintextAUDIENCE_ID
5Set your email addresses in the Worker

In Library → Worker, fill in Notify email (where submissions are sent) and From address (using the domain you just verified). They're baked into the Worker code — re-copy and redeploy after changing them.

Email is optional. Skip all of this and everything still works — uploads and forms succeed, contacts just won't be emailed or added to your audience. Add it whenever you're ready.

After this, send yourself a test purchase — you're live.

Components

Drop-in Framer code components, already wired to your Worker — your saved Worker URL is baked into the code when you copy it, so there's nothing to paste into props. The gated ones read the signed-in member's email (via your template's CaptureEmail override) and the Worker verifies it against FrameAuth, so access and limits follow the member, not the browser.

File Uploader FileUploader

Gated file upload to your R2 bucket. The Worker verifies the signed-in member against FrameAuth before accepting, and the per-period limit is keyed on the member — so clearing the browser doesn't reset it. Confirmation step, progress ring.

Member-verifiedPer-member limitLight / dark
14 props
Submit
Gated Form GatedForm

A configurable form — your own fields, an optional terms/agreement modal, and the same per-member limit. The Worker verifies membership before accepting; submissions are emailed to you via Resend.

Member-verifiedTerms modalLight / dark
18 props
Gated Video Player GatedVideo

A members-only lesson player for CMS pages. It auto-detects the page slug, the Worker verifies the member and returns the unlisted YouTube id — so the id never sits in your page. Custom controls, YouTube chrome hidden.

Member-verifiedAuto slug id hidden server-side
13 props
Join the Discord
Gated Discord GatedDiscord

A members-only "Join the Discord" button. It verifies the signed-in member against FrameAuth, then the Worker hands back your private invite — which lives server-side and never appears in your page.

Member-verifiedInvite hidden server-sideLight / dark
10 props
name@email.com
Subscribe
Email Signup EmailSignup

A two-step email then name capture that adds the contact to your Resend audience. Public — no membership needed. Animated, compact, drops onto any page.

Resend audienceLight / dark
10 props

Worker

This is the single serverless engine behind every Course Maker component. It verifies membership, takes file uploads and form submissions into your R2 bucket, sends email through Resend, and enforces your submission limits. You deploy it once — paste the whole file into a Cloudflare Worker and hit Deploy.

Submission limits

Controls how often each member can use the File Uploader and Gated Form. The limit is keyed on the verified member (not the browser), so it can't be reset by clearing storage. Resets on a calendar schedule, not from when someone signed up. Change these and the Worker code below updates instantly; re-copy and redeploy to apply.
Limit submissions
On — capped per interval below
Reset every

Email

Where form and upload submissions get sent, and the From address on outgoing email. These are baked into the Worker code below — only your Resend API key is a separate Cloudflare secret. Leave blank to skip notification emails entirely.

Video lessons & Discord invite

You set these in their own components — open Components and click Get code on the Gated Video Player (slugs & YouTube links) or Gated Discord (your invite link). Whatever you enter there is baked into the Worker code below. After changing either, re-copy and redeploy this Worker.
worker.js

        

Email Templates

Beautiful HTML email templates to use with Resend. Download the raw HTML files and paste them directly into your Resend email workflows. The styling matches your academy's premium dark theme.

Welcome Email welcome-email.html

The perfect welcome email for new members. Includes a nice hero section, a link to the academy, and next steps.

HTML Template
Resend Ready Download
Newsletter Email newsletter-email.html

A beautifully formatted template for broadcasting updates and new content drops to your audience.

HTML Template
Resend Ready Download

All videos

Every setup video in one place. Rewatch any section on its own.

Settings

Your Dashboard values. The Worker URL here is what every component uses.

Worker URL

Saved once, used everywhere. Components read this automatically — you never paste it into code.
https://
Saved

Academy

Read-only — pulled from your FrameAuth project.
Bedroom Artist Academy · tag_616cbbcf…1162a8