Vercel Hobby · Beachhead course

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 thisYou getServed at
Push or merge to the production branch (main)Productionyour project's .vercel.app domain
Push any other branch, or open a pull requestPreviewa generated URL for that branch, and one for that commit
Run npm run dev on your laptopLocal Developmentlocalhost: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

  1. Create the app. --yes accepts the defaults: TypeScript, Tailwind CSS, ESLint, App Router. It also runs git init for you.

    npx create-next-app@latest beachhead --yes
    cd beachhead
  2. 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),
      });
    }
  3. Run it locally. Start the dev server and open http://localhost:3000/api/health.

    npm run dev
    {"env":"local","hasLlmKey":false,"hasDatabaseUrl":false}
  4. Put it on GitHub. Name the branch main first, so the lessons match what you see. On a new project Vercel picks main as the production branch, then master if there is no main.

    git branch -M main
    git add -A
    git commit -m "Add health probe"
    gh repo create beachhead --private --source=. --push

    No GitHub CLI? Create an empty repository at github.com/new under your personal account, then git remote add origin <its URL> and git push -u origin main.

  5. Import it into Vercel. Open vercel.com/new, pick the beachhead repository, leave the Framework Preset as Next.js, and select Deploy. You have not needed any configuration, and that is the normal case.

  6. Visit Production. When the build finishes, open your project's domain with /api/health on the end.

    {"env":"production","hasLlmKey":false,"hasDatabaseUrl":false}

    If env says local here, open the project's Environment Variables page and tick Enable access to System Environment Variables, then redeploy.

  7. 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-preview

    In 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.

  8. 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 link

    Choose your account and the existing beachhead project. This writes a .vercel directory holding the project and org IDs. create-next-app already put .vercel in .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…

  • a Production deployment
  • no deployment yet
  • a Preview deployment

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…

  • Production deployment
  • Preview deployment
  • Development deployment

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?

  • your decrypted environment variables
  • project and org configuration
  • cached production build output

“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?

  • Preview
  • Production
  • Development

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.