Lab status: openField guideEXP-WEB-01

Launch a website. Seriously simple.

A click-by-click field guide to putting a real business website online, with its own address, a database for form submissions, automatic emails, and a newsletter. No coding background needed. Work through the tabs left to right and tick each step as you go.

Cloudflare GitHub Supabase Resend Mailchimp
0 of 0 steps done
§ 00 — Before you begin

The big picture.

Five free services, each with one job. You'll create an account on each one using your business email, then connect them.

About 2–3 hours totalAll free to startDomain about $10–15/yr
EXP-01 · Files

GitHub

The filing cabinet. Holds your website's files.

EXP-02 · Hosting

Cloudflare

The storefront. Shows your site to the world at your own address.

EXP-03 · Data

Supabase

The notebook. Saves what visitors send you, like contact forms.

EXP-04 · Mail

Resend

The mail carrier. Sends one-to-one automatic emails like "new message" alerts.

EXP-05 · Marketing

Mailchimp

The megaphone. Sends newsletters and promotions to your whole list.

Calibrate the instructions

Your details

Type these in once and every instruction in this guide fills them in for you. They stay in your own browser and are never sent anywhere.

  1. Gather your supplies

    • Your business email and access to its inbox (you'll click lots of verification links).
    • Your phone, for two-step login codes.
    • A password manager (Bitwarden, 1Password, or your browser's built-in one). You'll create five passwords and two secret keys.
    • A domain name idea, or the login for a domain you already own.
  2. Use your business email for every sign-up

    Sign up for all five services with . Keeping everything under one business email means you can hand the business off later or add a helper without untangling personal accounts.

    Best setup: an email at your own domain (like ). Mailchimp needs one to send newsletters reliably. If your business email is a Gmail address, the Cloudflare tab shows how to get a free address at your domain.
  3. Learn the two rules of secret keys

    Some services give you a long code called an API key. Think of it like a house key.

    • Save it in your password manager the moment you see it. Most services only show it once.
    • Never paste a secret key into your website files or GitHub. You'll put it in Cloudflare's locked "Secrets" box instead.
§ 01 — Cloudflare · account and domain

Claim your address.

Cloudflare will host your site and manage your domain's settings (called DNS). We start here because the email services need those settings later.

15 minutesFree plan
  1. Create your account

    Go to dash.cloudflare.com/sign-up. Enter and a strong password. Open the verification email and click the link.

  2. Turn on two-step login

    Click the person icon (top right) → Profile → Authentication → Two-Factor Authentication. Scan the code with an authenticator app and save the backup codes in your password manager.

  3. Get your domain

    If you don't own one yet: in the left menu choose Domain Registration → Register Domains. Search for , add it to your cart and check out. Cloudflare sells domains at cost with no markup, and it's set up automatically.

    If you already own one elsewhere (GoDaddy, Namecheap, Squarespace…): click Add a domain, type , pick the Free plan, and continue. Cloudflare shows you two "nameservers." Log in where you bought the domain, find "Nameservers," choose "Custom," and paste in Cloudflare's two. Changes can take up to 24 hours; Cloudflare emails you when the domain is Active.

    Already have email at this domain? Before switching nameservers, open DNS → Records in Cloudflare and make sure the records called MX were copied over. If they're missing, your email will stop working. Copy them from your old provider if needed.
  4. Optional: a free email address at your domain

    Only needed if your business email is a Gmail/Outlook address. Open your domain → Email → Email Routing → Get started. Create an address like hello@ and forward it to your existing inbox. Cloudflare adds the needed records for you.

    Skip this if you already use Google Workspace or Microsoft 365 at your domain.
§ 02 — GitHub · your website's files

Set up the filing cabinet.

Every file of your website lives here. When you change a file, your live site updates on its own within a minute or two.

15 minutesFree plan
  1. Create your account

    Go to github.com/signup and sign up with . Pick a username that matches your business. Enter the code GitHub emails you.

    GitHub will ask you to turn on two-step login. Do it now with the same authenticator app.

  2. Create a repository (your site's folder)

    Click the + at the top right → New repository.

    • Repository name: something like website
    • Visibility: Private is fine
    • Tick Add a README file

    Click Create repository.

  3. Add your home page

    Already have website files (from a designer or a site builder export)? Click Add file → Upload files, drag them in, then click Commit changes. Your main page must be named index.html.

    Starting fresh? Click Add file → Create new file. Name it index.html, paste the starter page below, then click Commit changes. It already has a contact form and a spot for your newsletter signup.

    index.html
    <!doctype html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <title></title>
      <style>
        body { font-family: system-ui, sans-serif; max-width: 640px; margin: 40px auto; padding: 0 16px; line-height: 1.6; }
        input, textarea, button { display: block; width: 100%; margin: 6px 0 16px; padding: 10px; font: inherit; }
        button { background: #FF6B35; color: #fff; border: 0; border-radius: 8px; cursor: pointer; }
      </style>
    </head>
    <body>
      <h1></h1>
      <p>Welcome! Tell people what you do here.</p>
    
      <h2>Contact us</h2>
      <form method="POST" action="/api/contact">
        <label>Name <input name="name" required></label>
        <label>Email <input name="email" type="email" required></label>
        <label>Message <textarea name="message" rows="4"></textarea></label>
        <button type="submit">Send</button>
      </form>
    
      <h2>Join our newsletter</h2>
      <!-- Paste your Mailchimp signup form here (see the Mailchimp tab) -->
    </body>
    </html>
  4. Add a thank-you page

    Click Add file → Create new file, name it thanks.html, paste this, and click Commit changes. Visitors land here after sending the contact form.

    thanks.html
    <!doctype html>
    <html lang="en">
    <head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Thank you</title></head>
    <body style="font-family: system-ui, sans-serif; max-width: 640px; margin: 40px auto; padding: 0 16px;">
      <h1>Thanks! We got your message.</h1>
      <p>We'll reply soon. <a href="/">Back to the home page</a></p>
    </body>
    </html>
§ 03 — Cloudflare Pages · publish

Put it on the internet.

Connect GitHub to Cloudflare Pages. From now on, every change you save in GitHub goes live automatically.

10 minutesFree plan
  1. Start a Pages project

    In Cloudflare's left menu choose Compute → Workers & Pages → Create application. Pick the Pages option, then Connect to Git.

    Only see "Workers"? Cloudflare moves its buttons around. Look for a small link like "Looking to deploy Pages? Get started." This guide's contact form needs Pages.
  2. Let Cloudflare see your GitHub

    Click Connect GitHub. On the GitHub screen choose Only select repositories, pick your website repository, and click Install & Authorize.

  3. Deploy

    Select your repository → Begin setup. Use these settings:

    • Project name: your business name (this becomes your free test address)
    • Framework preset: None
    • Build command: leave empty
    • Build output directory: leave empty

    Click Save and Deploy. In about a minute you'll get an address ending in .pages.dev. Open it. That's your site, live!

    Using a site builder or framework (Astro, Next.js, Vite)? Pick it from the preset list and Cloudflare fills in the build settings.
  4. Use your own domain

    Open your project → Custom domains → Set up a custom domain. Type and click Activate domain. Repeat with www. so both versions work.

    Wait a few minutes, then visit https://. The padlock means it's secure. Cloudflare handles that for free.

§ 04 — Supabase · database

A place to save everything.

Supabase is your database. We'll make one table that stores every message sent through your contact form, so nothing gets lost in an inbox.

15 minutesFree plan
  1. Create your account

    Go to supabase.com → Start your project. The easiest choice is Continue with GitHub, which uses the account you just made. Or sign up with .

  2. Create an organization and project

    Name the organization and choose the Free plan. Then create a project:

    • Name: website
    • Database password: click Generate a password and save it in your password manager
    • Region: the one closest to your customers

    Click Create new project and wait about two minutes.

  3. Create your contacts table

    In the left menu open SQL Editor. Paste the code below and click Run. You should see "Success."

    SQL · creates the table and lets your form add rows
    create table public.contacts (
      id bigint generated always as identity primary key,
      created_at timestamptz not null default now(),
      name text,
      email text not null,
      message text
    );
    
    alter table public.contacts enable row level security;
    grant insert on public.contacts to anon;
    
    create policy "Website visitors can send messages"
      on public.contacts for insert
      to anon
      with check (true);

    In plain English: this makes a "contacts" table and lets your website add messages, but not read or delete anyone's data.

  4. Copy your project address and public key

    Click Project Settings (gear icon, bottom left). Under Data API copy the Project URL (looks like https://abcd1234.supabase.co). Under API Keys copy the Publishable key (starts with sb_publishable_).

    Save both in your password manager. You'll use them on the Contact form tab.

    Leave the secret key alone. The key starting with sb_secret_ can read and delete everything. You don't need it for this guide. Never share it.
  5. See your messages anytime

    Open Table Editor → contacts. Every form submission appears as a new row. You can export them with the Export button as a spreadsheet file.

§ 05 — Resend · automatic emails

Hire a mail carrier.

Resend sends emails from your website automatically, like "You've got a new message" alerts, receipts and login links. They come from your own domain, so they land in inboxes instead of spam.

20 minutes + waitingFree plan
  1. Create your account

    Go to resend.com/signup and sign up with . Confirm your email.

  2. Add your domain

    Click Domains → Add Domain. Type , choose the region closest to you, and click Add. Resend shows a short list of records (codes) that prove you own the domain.

  3. Add the records to Cloudflare

    Easy way: if Resend shows an Auto configure or "Sign in to Cloudflare" button, click it and approve. Done.

    Manual way: open a second browser tab with Cloudflare → your domain → DNS → Records. For each row in Resend, click Add record and copy the Type, Name and Value exactly. Leave TTL on Auto.

    TypeName (example)What it does
    TXTresend._domainkeyYour email "signature" (DKIM)
    MXsendHandles bounced emails
    TXTsendLists who may send for you (SPF)

    Back in Resend, click Verify DNS Records. It can take from a few minutes to a few hours. You'll see a green Verified.

  4. Add a DMARC record (helps both Resend and Mailchimp)

    In Cloudflare DNS → Records, first check there isn't already a TXT record named _dmarc. There can only be one. If none exists, click Add record: Type TXT, Name _dmarc, and this value:

    DMARC value
    v=DMARC1; p=none; rua=mailto:
  5. Create your API key

    Click API Keys → Create API Key. Name it website, choose Sending access, select your domain, and click Add.

    Copy it now. It starts with re_ and Resend only shows it once. Paste it straight into your password manager.
  6. Optional: send Supabase login emails through Resend

    Only if you'll add customer logins later. In Supabase open Authentication → Emails → SMTP Settings, switch on custom SMTP and enter:

    Hostsmtp.resend.com
    Port465
    Usernameresend
    Passwordyour Resend API key
    Sender emailnoreply@
    Sender name
§ 06 — Connect the pieces

Make the form work.

One small file ties it all together. When someone fills in your form, it saves the message to Supabase and emails you through Resend.

15 minutesCopy and paste only
  1. Add the form handler file in GitHub

    In your website repository click Add file → Create new file. In the name box type exactly functions/api/contact.js. Typing the slashes creates the folders for you. Paste the code below and click Commit changes.

    functions/api/contact.js
    export async function onRequestPost({ request, env }) {
      const form = await request.formData();
      const name = String(form.get("name") || "").slice(0, 200);
      const email = String(form.get("email") || "").slice(0, 200);
      const message = String(form.get("message") || "").slice(0, 5000);
    
      if (!email.includes("@")) {
        return new Response("Please go back and enter a valid email.", { status: 400 });
      }
    
      // 1. Save the message in Supabase
      const saved = await fetch(env.SUPABASE_URL + "/rest/v1/contacts", {
        method: "POST",
        headers: {
          apikey: env.SUPABASE_KEY,
          "Content-Type": "application/json",
          Prefer: "return=minimal"
        },
        body: JSON.stringify({ name, email, message })
      });
      if (!saved.ok) {
        return new Response("Sorry, your message could not be saved. Please email us instead.", { status: 500 });
      }
    
      // 2. Email yourself through Resend
      await fetch("https://api.resend.com/emails", {
        method: "POST",
        headers: {
          Authorization: "Bearer " + env.RESEND_API_KEY,
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          from: env.FROM_EMAIL,
          to: env.NOTIFY_EMAIL,
          reply_to: email,
          subject: "New website message from " + (name || email),
          text: "Name: " + name + "\nEmail: " + email + "\n\n" + message
        })
      });
    
      // 3. Send the visitor to the thank-you page
      return Response.redirect(new URL("/thanks.html", request.url).toString(), 303);
    }
  2. Give Cloudflare your keys

    In Cloudflare open Workers & Pages → your project → Settings → Variables and Secrets → Add. Add these five, one at a time, for Production:

    Variable nameTypeValue
    SUPABASE_URLTextYour Supabase Project URL
    SUPABASE_KEYTextYour Supabase publishable key
    RESEND_API_KEYSecretYour Resend key (starts with re_)
    FROM_EMAILText <noreply@>
    NOTIFY_EMAILText

    Names must match exactly, capital letters included. Click Save.

  3. Redeploy so the keys take effect

    Keys only apply to the next update. Go to your project's Deployments tab, click the ⋯ menu on the newest one, and choose Retry deployment.

  4. Test it

    Visit https://, fill in the contact form with your own details, and send. Within a minute you should see:

    • the thank-you page,
    • a new row in Supabase → Table Editor → contacts,
    • an email in (check spam the first time and mark it "Not spam").
    Row saved but no email? Check that Resend says Verified and that FROM_EMAIL uses your domain. Resend's Logs page shows why an email failed.
§ 07 — Mailchimp · marketing emails

Grow your list.

Mailchimp collects newsletter signups on your site and sends your promotions, announcements and welcome emails to everyone at once.

25 minutesFree plan
  1. Create your account

    Go to mailchimp.com and choose the Free plan. Sign up with and confirm it.

    Mailchimp asks for a business mailing address. Anti-spam law requires one in every marketing email footer. A PO box or registered agent address works if you'd rather not share your home.

  2. Set up your audience

    Your "audience" is your mailing list. Mailchimp creates one for you. Go to Audience → Settings → Audience name and defaults. Set the from-name to and the from-email to .

  3. Verify and authenticate your domain

    Click your profile icon → Account & billing → Domains → Add & Verify Domain. Enter , then type in the code Mailchimp emails you.

    Next click Start Authentication and choose Cloudflare as your provider. Mailchimp shows two or three records (mostly CNAME records named like k2._domainkey). Add each one in Cloudflare DNS → Records, then click Authenticate Domain.

    Important: when adding a CNAME record in Cloudflare, click the orange cloud so it turns grey ("DNS only"). If it stays orange, Mailchimp can't verify it. You already added the DMARC record on the Resend tab, so skip it here if Mailchimp asks.
  4. Put a signup form on your website

    Go to Audience → Signup forms → Embedded form. Adjust the fields if you like, then click Continue and Copy code.

    In GitHub open index.html, click the pencil icon to edit, find the line that says Paste your Mailchimp signup form here, paste the code right under it, and click Commit changes. Your site updates in about a minute.

  5. Send new subscribers a welcome email

    Go to Automations and choose the Welcome new subscribers template. Write a short hello (who you are, what they'll get, maybe a discount code), then turn it on.

    Free plan limits change often. If an automation shows a lock icon, it needs a paid plan. A simple first newsletter works on the free plan.
  6. Know who sends what

    EmailSent by
    Newsletters, promotions, announcementsMailchimp
    Welcome series for subscribersMailchimp
    Contact form alerts, receipts, password resetsResend
    Your day-to-day replies to customersYour business inbox
§ 08 — Final check

Pre-launch checklist.

Run through these before you tell the world. Each one takes a minute.

  1. Your site opens on both addresses

    https:// and https://www. both load, with a padlock in the address bar. Check on your phone too.

  2. Contact form test passes

    A test message shows up in Supabase and as an email in your inbox.

  3. Newsletter test passes

    Sign up with a personal email. You should get Mailchimp's confirmation and welcome emails, and see yourself under Audience → All contacts.

  4. Domain shows green everywhere

    Resend says Verified. Mailchimp says Authenticated. Cloudflare says Active.

  5. Secrets are safe

    In GitHub, use the search box in your repository to search for re_ and sb_secret. Nothing should come up. If a key ever lands in GitHub, delete it in Resend or Supabase and make a new one.

  6. Two-step login is on for all five accounts

    Cloudflare, GitHub, Supabase, Resend and Mailchimp. All passwords and keys are in your password manager.

  7. Add a privacy policy page

    Because you collect names and emails, add a short privacy.html page in GitHub explaining what you collect and why, and link to it from your home page. Free generators online can draft one for you.

  8. Keep Supabase awake

    Free Supabase projects pause after about a week with no activity. A steady trickle of form submissions keeps it awake. If it pauses, open the project in Supabase and click Restore.

§ 09 — Bonus · share it

Host this guide yourself.

This whole guide is one file. Put it on your own Cloudflare account and share the link with anyone building their own site.

5 minutesNo GitHub needed
  1. Get the file

    Save this page to your computer. In your browser choose File → Save Page As and pick Webpage, HTML only. Name it index.html and put it in a new folder named something like launch-guide.

  2. Upload it to Cloudflare

    In your personal Cloudflare account go to Workers & Pages → Create application → Pages → Upload assets (sometimes labeled "Drag and drop your files").

    Give the project a name like website-launch-guide, click Create project, drag in your launch-guide folder, and click Deploy site.

  3. Share the link

    You'll get an address like website-launch-guide.pages.dev. Send it to anyone. Each person's details and checkmarks are saved only in their own browser, so nobody sees anyone else's info.

    Want it on your own domain? Use Custom domains in the project, like the Go live tab shows.

  4. Update it later

    Edit the file, then in the project click Create deployment and upload the folder again.