blog jun 16, 2026 · 4 min read

Deploy on Vercel in 3 minutes, properly

Deploying to Vercel takes three minutes. That's not the interesting part — the interesting part is that most people spend the three minutes and skip the fifteen that make the deployment professional. Then the project ends with a support ticket instead of a handoff: the domain half-connected, secrets pasted into the repo, the client emailing screenshots of a preview URL that stopped working. Here's the whole setup, in order, the way it happens on every project my studio ships.

The three minutes

Two ways in. The CLI is the fastest first contact:

npm i -g vercel
vercel login
vercel        # links the folder to a new project, deploys a preview
vercel --prod # deploys to production

First run asks a few questions — project name, framework (it detects Next.js), build settings (accept the defaults). Forty seconds later you have a live URL ending in .vercel.app. That's the demo-grade deployment, and if all you needed was "show someone the thing", you're done.

For client work, do it the second way: connect the git repository. Push your repo to GitHub, then in the Vercel dashboard choose Add New → Project → Import and pick the repo. From that moment the rule is beautifully simple:

  • push to main → production deploys
  • push to any other branch → a preview deploys

No FTP, no "did you upload the new version?", no deploy scripts. The repository is the source of truth, which means git history is your rollback plan — a bad deploy is fixed by reverting a commit, and Vercel's dashboard has an instant rollback button besides. This is the single biggest professionalism upgrade available for zero effort: your deployment story becomes "it's automatic and reversible."

Domains without the support ticket

The .vercel.app URL is for you, not the client. A client project isn't delivered until it's on their domain, and this is where most handoffs go sideways — so get the ownership right before touching DNS.

The rule: the client owns the domain. Registered in their account, on their card, at their registrar. If you register it for them "to be helpful", you've created a dependency that outlives the project — in three years, when you've moved on, their website dies with your forgotten renewal email. If the domain currently sits in an old developer's account (this is astonishingly common), making the transfer happen is part of the job. Budget an annoying week of registrar emails for it.

The DNS itself is two records. In the Vercel project: Settings → Domains, add clientname.com and www.clientname.com (or from the CLI, vercel domains add clientname.com). Vercel then shows you exactly what it wants at the registrar, which is:

A      @      76.76.21.21
CNAME  www    cname.vercel-dns.com

Add those two records in the registrar's DNS panel, wait for propagation (minutes usually, up to an hour sometimes), and Vercel provisions the SSL certificate itself — no certificate purchasing, no renewal cron, no padlock questions from the client ever. Set one of the two domains (I use the bare one) as primary so the other redirects to it; Vercel offers this as a toggle. One canonical URL matters for SEO and for not looking sloppy.

While it propagates, resist the urge to keep re-saving records — that's how people break a working setup. Check what the world actually sees instead:

nslookup clientname.com        # should return 76.76.21.21
nslookup www.clientname.com    # should point at cname.vercel-dns.com

If those answers are right and the site still isn't up, it's cache, not you. Make coffee, not changes.

Environment variables

Every real project has secrets — an email API key, a database URL, an analytics ID. Two rules, both non-negotiable.

They never go in the repository. Not "temporarily", not commented out. A key that touches git history is compromised history, and scrubbing git history is a miserable afternoon. Locally they live in .env.local, which Next.js reads automatically and which must be listed in .gitignore (Next's default template already does this — don't undo it).

On Vercel they live in Settings → Environment Variables, or from the CLI:

vercel env add RESEND_API_KEY production
vercel env pull .env.local   # syncs the project's dev vars to your machine

Note the production at the end — Vercel keeps three environments (production, preview, development), and the separation is a feature, not bureaucracy. The preview site should use test keys: the client clicking around a preview should never trigger a real payment or a real customer email. Test keys in preview, live keys in production, and one more habit that separates professionals from hobbyists: the site must build with no env vars at all. Guard every integration so a missing key degrades gracefully instead of crashing — the contact form logs instead of sending, analytics no-op. You'll deploy from a fresh machine one day and thank yourself.

Preview deployments

This is the feature that changes the client relationship, and most people use it by accident or not at all.

Every branch push gets its own URL — full site, real data rules, shareable. So the review loop becomes: client asks for changes, you build them on a branch, you send one link. "Here's the new pricing section: https://client-site-git-new-pricing-yourteam.vercel.app — approve it and it goes live." The client reviews the actual thing on their actual phone, not a screenshot or a promise. Production stays untouched until the word "approved" arrives in writing, at which point merging the branch is the deployment. Approval and release become the same click.

Two refinements. Vercel drops a bot comment with the preview link on every GitHub pull request, so the links find themselves. And if the project is sensitive, Settings → Deployment Protection puts previews behind a login or password so the half-finished redesign isn't publicly crawlable.

The handoff

Last fifteen minutes of the project, usually skipped, always regretted. A deployment isn't delivered until the client can survive your disappearance.

My checklist before the final invoice:

  • Access: client has (or their business account has) ownership or membership on the Vercel project and the GitHub repo. Their infrastructure should not live exclusively inside your personal accounts. Transfer or invite — Vercel supports both.
  • Domain: in the client's registrar account, both variants connected, primary redirect set, SSL green.
  • Secrets: every env var documented in a one-page handoff note — what it is, where it's set, where to rotate it. Not the values; the map.
  • The two-line ops manual: "To change the site, edits go through me (or any developer) via the GitHub repo. To roll back, Vercel dashboard → Deployments → Promote a previous one." That paragraph has prevented more panicked calls than everything else combined.

Whether you then hand over the keys entirely or keep a small monthly retainer for changes is a business choice — I've done both, and the retainer is usually better for both sides. But it has to be a choice, not a hostage situation created by sloppy account ownership.

Three minutes to deploy. Fifteen to deploy properly. The gap between those two numbers is roughly the gap between "I made you a website" and "I delivered you a website" — and only one of them gets you the referral.

The AI code review checklist is free.
One page — the review pass from module 12: invented APIs, skipped edge cases, error handling that only looks like it.
Get the checklist