Lesson 2 of 6 · about 25 minutes
First deploy and the three environments
The win Your beachhead app answers at a public .vercel.app URL, and a second copy built from a branch answers at its own preview URL.
First, recall
Answer in your head, then open each one to check.
What does the Hobby plan say about commercial use?
Hobby is for non-commercial, personal use only. Taking payments, selling, or showing adverts needs Pro. (Lesson 1)
Which command proves the CLI is logged in?
vercel whoami
The idea: one project, three environments
A project on Vercel is linked to one Git repository. Every push makes a new deployment: an immutable build of that commit with its own URL. Which environment the deployment belongs to depends on what you pushed.
| You do this | You get | Served at |
|---|---|---|
Push or merge to the production branch (main) | Production | your project's .vercel.app domain |
| Push any other branch, or open a pull request | Preview | a generated URL for that branch, and one for that commit |
Run npm run dev on your laptop | Local Development | localhost:3000; nothing reaches Vercel |
One exception: the very first deployment of a new project is always Production, whatever branch it came from.
Preview is the reason this matters. You can try a change on real infrastructure, with real environment variables, and your users never see it. Lessons 3 to 5 lean on that.
Do it
-
Create the app.
--yesaccepts the defaults: TypeScript, Tailwind CSS, ESLint, App Router. It also runsgit initfor you.npx create-next-app@latest beachhead --yes cd beachhead -
Add a health probe. This Route Handler reports which environment it is running in and whether your keys are present. It reports presence, never the values. You will use it in every remaining lesson.
app/api/health/route.ts
export function GET() { return Response.json({ env: process.env.VERCEL_ENV ?? "local", hasLlmKey: Boolean(process.env.ANTHROPIC_API_KEY), hasDatabaseUrl: Boolean(process.env.DATABASE_URL), }); } -
Run it locally. Start the dev server and open
http://localhost:3000/api/health.npm run dev{"env":"local","hasLlmKey":false,"hasDatabaseUrl":false} -
Put it on GitHub. Name the branch
mainfirst, so the lessons match what you see. On a new project Vercel picksmainas the production branch, thenmasterif there is nomain.git branch -M main git add -A git commit -m "Add health probe" gh repo create beachhead --private --source=. --pushNo GitHub CLI? Create an empty repository at github.com/new under your personal account, then
git remote add origin <its URL>andgit push -u origin main. -
Import it into Vercel. Open vercel.com/new, pick the
beachheadrepository, leave the Framework Preset as Next.js, and select Deploy. You have not needed any configuration, and that is the normal case. -
Visit Production. When the build finishes, open your project's domain with
/api/healthon the end.{"env":"production","hasLlmKey":false,"hasDatabaseUrl":false}If
envsayslocalhere, open the project's Environment Variables page and tick Enable access to System Environment Variables, then redeploy. -
Make a Preview. Change anything on a branch and push it.
git switch -c try-preview git commit --allow-empty -m "Trigger a preview" git push -u origin try-previewIn the dashboard, open Deployments, find the new Preview deployment, visit it, and add
/api/health. It says"env":"preview". If the preview asks you to log in to Vercel first, that is Deployment Protection keeping strangers out of your previews; log in with your own account. -
Link your folder to the project. The app was created in the browser, so the CLI does not yet know that this folder belongs to it.
git switch main vercel linkChoose your account and the existing
beachheadproject. This writes a.verceldirectory holding the project and org IDs.create-next-appalready put.vercelin.gitignore.
You now have the same code running in three places and a probe that tells you which is which.
Check yourself
The project already has a production deployment and its production branch is main. You run git push origin fix-typo. Vercel creates…
Vercel creates a preview deployment when you “push a commit to a branch that is not your production branch.” No pull request is needed. Source
You import a brand-new project, and its very first deployment happens to come from a branch called experiment. That deployment is a…
The first deployment of a new project is always Production, “even when you deploy from a branch that is not your production branch,” so that the project can receive its production domain straight away. Source
What does the .vercel directory created by vercel link hold?
“This creates a .vercel directory in your project with the project and org configuration.” It identifies the project; it is not where secrets live. Source
Which environment never runs on Vercel's servers?
Local Development is your own machine. Vercel only stores the Development variables so you can pull them down, which is the subject of the next lesson. Source
Read this Environments in the Vercel docs. Read as far as “Production Environment” and skip the Custom Environments section, which is Pro-only.
Ask your teacher If the import fails, the build log is the first place to look, and you can paste it into your Claude Code session and ask what went wrong.