Week 6

Deploy Your Site

NYU · Whatever Generative AI Is Doing Now · 2026

SCHEDULE

Week 1 Install and Claude Basics
Week 2 Research and Writing with Claude
Week 3 Chrome Use, Computer Use & MCPs
Week 4 Build Your Own Software, Part 1
Week 5 Build Your Own Software, Part 2: AI Generation Tools
Week 6 Deploy Your Site
Week 7 Demo Day

DEMO DAY — NEXT WEEK

5 minutes each. Show whatever you want: a live demo, slides, a video, a screen recording.

• What you set out to build
• What you actually got working
• Where you struggled and what you learned

Everyone benefits from hearing where you struggled. Struggles are just as valuable as successes.

TODAY

1. Check in on your projects
2. Save your work (databases)
3. What “deploy” actually means
4. Deploy your app
5. Polish & prep for Demo Day

Section 1

Project Check-In

WHERE ARE YOU?

Last week you added a generation feature. Let’s take stock:

• Does your app run locally?
• Is your generation feature working?
• Is your API key server-side (not in the frontend)?
• Is your code committed and pushed to GitHub?

GITHUB IS THE PREREQUISITE

To deploy today, your code needs to be on GitHub.

If it’s not yet, use the steps from last week:
brew install ghgh auth logingh repo creategit push

Ask Claude: “Help me get this project on GitHub.”

Section 2

Save Your Work

Let’s look at saving our drawing state.

THE QUICK-AND-DIRTY OPTION: LOCALSTORAGE

localStorage.setItem('drawing', canvas.toDataURL())

Limits: lives in one browser, on one device. Not good for “save and share.”

DATABASES

A database is a server that stores structured data and lets you read/write it from anywhere over the network.

• Data lives outside any single browser or device
• Multiple visitors can read/write the same data
• Survives redeploys, cache clears, device switches

For our purposes: a persistent place to put drawings where anyone can load them by URL.

NO AUTH REQUIRED

You don’t need users and passwords to save things. Two patterns that work without auth:

Unguessable URLs: save the drawing, get back an ID like /d/a7f3b91c. Anyone with the link can see it. 
Public gallery: everyone’s drawings show up in one feed.

Pick the one that fits your app.

SUPABASE

Free-tier Postgres database + file storage.

Platform-agnostic — works whether you deploy to Vercel, Netlify, or anywhere else.

My default recommendation.

supabase.com

VERCEL POSTGRES / KV / BLOB

Built into Vercel. Zero setup once you’re deploying there.

Postgres for structured data (rows and columns)
KV for simple key-value storage
Blob for files and images

vercel.com/storage

NETLIFY BLOBS

Built into Netlify. Dead simple key-value storage — no separate signup, no connection string.

Good fit for small amounts of data like saved drawings.

docs.netlify.com/blobs

THE SAVE + LOAD FLOW

1. User clicks Save
2. Browser turns the canvas into an image (a data URL)
3. Your API route receives it and writes a row to the database
4. DB returns a new ID
5. App updates the URL to /d/[id]
6. Visiting /d/[id] later → API route reads the row → canvas reloads

WHAT TO ASK CLAUDE

“Add save + load to my drawing app using Supabase. No user auth — each save gets an unguessable ID in the URL. On page load, if there’s an ID in the URL, fetch and render that drawing. Otherwise start with a blank canvas.”

Claude will create the table, write the API routes, and wire up the buttons. Your job is to describe the behavior and test it end-to-end.

DATABASE CREDENTIALS ARE SECRETS TOO

Same rule as your Fal API key:
• Connection string lives in .env, never in frontend code
• All DB calls go through an API route
• You’ll add it to Vercel/Netlify when we deploy later today

If you leak a DB connection string, anyone with it can read and delete your data. Treat it like a password.

Let’s do this in our drawing app now.

Section 3

What “Deploy” Means

Right now your app only exists on your laptop.

Deploying means putting it on a computer that’s always on, at a URL anyone can visit.

LOCALHOST VS PRODUCTION

Localhost (localhost:3000): runs on your machine, only you can see it, stops when you close the terminal.

Production (yoursite.com): runs on a server somewhere, publicly accessible, always on.

STATIC VS DYNAMIC

Static: HTML/CSS/JS built once, served to everyone. Fast, cheap, simple.

Dynamic: server runs code on every request. Needed for API routes, auth, database calls. (Like your generation feature.)

Most modern apps are both: a static frontend with a handful of dynamic API routes. Next.js handles this automatically.

FRONTEND VS BACKEND — WHERE SECRETS LIVE

Anything in the frontend (what the browser loads) is visible to anyone.

Your API keys, database passwords, and anything secret must live in the backend — server-side code the browser never sees.

Section 4

Deploy Your App

You could rent a server and configure it yourself.
Don’t. Use Netlify or Vercel.

VERCEL

Made by the team behind Next.js. If you’re on Next.js, it’s the path of least resistance.

• Tight ecosystem: Postgres, KV, Blob storage all built in
• Great preview deploys for every branch
• Free tier covers hobby projects

NETLIFY

Framework-agnostic — works with Next.js, Vite, plain HTML, anything.

• Great Netlify Functions for serverless endpoints
• Built-in Blobs storage (covered earlier)
• Free tier covers hobby projects

Pick one. Both work. Don’t agonize.

HOW THEY WORK

1. You push code to GitHub
2. Netlify/Vercel detects the push
3. It runs your build command in a fresh environment
4. If the build succeeds, it publishes the output to a URL
5. Every push to main → new deployment

Pull requests get their own preview URL. Broken deploys don’t replace the working one.

WHAT YOU GET FOR FREE

• A public URL (like your-app.vercel.app)
• HTTPS (the little lock icon — browsers require this now)
• A global CDN (your site loads fast everywhere)
• Auto-deploys on every git push
• Preview URLs for every branch
• Build logs when things break

All for $0 on hobby projects.

Demo: deploying our drawing app to Vercel.

Then you do yours.

STEP 1: CODE ON GITHUB

Already done from last week? Great.

If not:
gh repo create --source=. --public --push

You can’t deploy what isn’t on GitHub. Vercel and Netlify both deploy from your repo.

STEP 2: SIGN UP

Go to vercel.com or netlify.com.

“Sign up with GitHub” — it’s the easiest path. It also pre-authorizes access to your repos.

You’ll need to authorize the app to see your repositories. Do it.

STEP 3: IMPORT YOUR REPO

Vercel: Dashboard → “Add New” → Project → pick your repo.

Netlify: Dashboard → “Add new site” → “Import an existing project” → pick your repo.

If you don’t see your repo, click “Adjust GitHub App Permissions” and grant access.

STEP 4: BUILD CONFIG

Both platforms try to auto-detect your framework. For Next.js this usually just works.

What they need to know:
Framework preset (Next.js, Vite, etc.)
Build command (usually npm run build)
Output directory (framework default)

IF IT DOESN’T AUTOFILL

If it autofills, don’t change anything.

If it doesn’t, ask Claude:
“What should my Vercel build settings be for this project?”

STEP 5: ENVIRONMENT VARIABLES

Your .env file — with your fal API key, your DB connection string, anything else secret — is gitignored. So your deployed app has no idea what those values are.

Add each variable in the dashboard:
Vercel: Settings → Environment Variables
Netlify: Site settings → Environment variables

Same names as your .env file. FAL_KEY stays FAL_KEY.

STEP 6: DEPLOY

Click Deploy. Watch the build log scroll.

If it succeeds — you’ll get a URL. Open it. Test your app like a real user.

If it fails — read the log. The error is in there. Copy the relevant part, paste it into Claude, ask it to explain and fix.

WHEN IT BREAKS (AND IT WILL)

Your deploy worked locally but fails in production. Why?

Four common culprits:

• Missing env var
• Case-sensitive filenames
• Hardcoded localhost URL
• Missing package in package.json

MISSING ENV VAR

You added it to .env but not to the Vercel/Netlify dashboard.

Your .env file is gitignored — the deploy never sees it.

Fix: add every key from .env to your host’s dashboard, then redeploy.

CASE-SENSITIVE FILENAMES

Mac and Windows treat Button.jsx and button.jsx as the same file. Linux (where the build runs) does not.

Fix: make sure every import matches the exact filename case.

import Button from './Button'import Button from './button'

HARDCODED LOCALHOST URL

Your frontend is calling http://localhost:3000/api/... in production.

Works on your machine. Doesn’t work for anyone else.

Fix: use a relative path like /api/..., or read the URL from an env var.

MISSING PACKAGE IN PACKAGE.JSON

You ran npm install something locally but never committed the updated package.json.

The deploy runs npm install on a fresh machine — if it’s not in package.json, it won’t be there.

Fix: commit both package.json and package-lock.json, then push.

EVERY ONE OF THESE IS FIXABLE

Your debug loop:

1. Read the build log — the error is in there
2. Copy the relevant part into Claude, ask what’s wrong
3. Push a fix
4. Watch it redeploy

Repeat until green.

WHEN IT BUILDS BUT BREAKS AT RUNTIME

Build succeeded, site loads, but your generation button throws a generic error in the browser. The real error is on the server.

Vercel: Project → Logs tab — every API request
Netlify: Site → Logs → Functions — per-function output

Your console.logs and thrown errors show up here as well.

Section 5

Polish & Prep for Demo Day

YOUR DEMO

Five minutes isn’t long. 

Rough structure:
30 sec: What is this, who’s it for, why did you build it?
2-3 min: Live demo — the happy path
1 min: What broke, what you learned
30 sec: What’s next

Homework

Due Demo Day

HOMEWORK 1: SHIP IT

Your site should be deployed and working by next class.

• Public URL on Vercel or Netlify
• All env vars configured
• Your main feature works end-to-end on the deployed version

HOMEWORK 2: REHEARSE

You don’t need to memorize your demo. You do need to know the shape of it — what you’re showing, in what order, and what you’re going to say.