---
title: "Deploy to Vercel"
description: "Push the tracker to Vercel, add the Resend env var, deploy, place a production order, and tour the managed Workflows dashboard."
canonical_url: "https://vercel.com/academy/workflow-foundations/deploy-to-vercel"
md_url: "https://vercel.com/academy/workflow-foundations/deploy-to-vercel.md"
docset_id: "vercel-academy"
doc_version: "1.0"
last_updated: "2026-10-16T17:18:12.769Z"
content_type: "lesson"
course: "workflow-foundations"
course_title: "Workflow Foundations"
prerequisites:  []
---

<agent-instructions>
Vercel Academy — structured learning, not reference docs.
Lessons are sequenced.
Adapt commands to the human's actual environment (OS, package manager, shell, editor) — detect from project context or ask, don't assume.
The lesson shows one path; if the human's project diverges, adapt concepts to their setup.
Preserve the learning goal over literal steps.
Quizzes are pedagogical — engage, don't spoil.
Quiz answers are included for your reference.
</agent-instructions>

# Deploy to Vercel

# Deploy to Vercel

Your workflow already works in production. You just haven't deployed it yet.

That's the whole pitch of running Workflows on Vercel: the code you've written, the directives you've sprinkled, the `start()` call you wired up, none of it changes between local and prod. The Vercel platform spins up the queue infrastructure, the persistence layer, and the dashboard automatically the moment you deploy.

This lesson is short. Push the code. Add your environment variable. Wait for the build. Then place a real pizza order and watch the production dashboard show the same timeline you saw locally, just with more confidence.

## Outcome

Deploy the pizza tracker to Vercel with your Resend key configured. Place an order against the production URL and find the run in the Workflows dashboard.

## Fast Track

1. Push your repo to GitHub.
2. Import it at [vercel.com/new](https://vercel.com/new). Add `RESEND_API_KEY` as an environment variable.
3. Visit your production URL, place an order, and find the run under the **Workflows** tab in your Vercel project.

## Hands-on exercise

**1. Push to GitHub.**

```bash
git init
git add .
git commit -m "feat: pizza tracker with first workflow"
git branch -M main
git remote add origin <your-repo-url>
git push -u origin main
```

**2. Import to Vercel.**

Go to [vercel.com/new](https://vercel.com/new) and pick your repo. Vercel detects the Next.js app and proposes default settings. Before you click **Deploy**:

- Expand **Environment Variables** and add `RESEND_API_KEY` with the same value you used locally.
- If the **Region** picker is available on your project, choose **Washington D.C. (iad1)**. Workflows runs there at launch; anything else adds round-trip latency.

Click **Deploy**. The first build takes a couple of minutes.

**3. Open the production app.**

Once the deploy is green, visit your production URL. Place an order using a real email address (yours, probably) so you can confirm the email actually arrives.

**4. Find the run.**

In the Vercel dashboard, open your project. Click the **Workflows** tab in the sidebar. You'll see a list of runs, with the most recent one at the top.

```
processOrder · completed · 1m ago
  workflowRunId: wrun_aB3xK9pL2nM
  duration: 412ms
```

Click into it. The timeline view looks like the local dashboard, but the data is persisted by Vercel, not your laptop:

```
processOrder              completed   412ms
  └─ sendOrderConfirmation  completed   389ms
       input:  { id: "f8c2…", pizza: "Sal's Special", ... }
       output: undefined
       attempts: 1
```

## Try It

Place a few orders. Try a name that isn't Marge's, a different pizza, a different size. Each one creates a new run.

Now try a deliberately bad email like `not-an-email`. The Resend call fails, the step throws a `FatalError`, and the run shows up red in the dashboard with the error message attached:

```
processOrder              failed   201ms
  └─ sendOrderConfirmation  failed   195ms
       error: FatalError: Resend failed: Invalid `to` field
       attempts: 1
```

Notice the `attempts: 1`. `FatalError` told the runtime: don't retry, this won't work. We could have thrown a regular `Error` and the runtime would have tried again three more times. We'll exercise that distinction in 4.1 and 4.2.

\*\*Warning: Don't expect retries on FatalError\*\*

If you swap out `FatalError` for a regular `throw new Error(...)`, the same broken email would burn through four attempts (one initial plus three retries) before failing. This is intentional. `FatalError` is how you opt out of retries for failures you know won't recover.

## Commit

```
chore(deploy): wire up Vercel deployment with Resend env var
```

## Done-When

- [ ] The pizza tracker is deployed to a Vercel project
- [ ] `RESEND_API_KEY` is set as an environment variable on Vercel
- [ ] Placing an order in production sends a real email
- [ ] The **Workflows** tab in your Vercel project shows the run with step-level inputs and outputs

## Solution

No new code in this lesson. The deploy is a configuration step, not a code change. If your local app worked at the end of 1.3, your deployed app works the same way.

The big shift isn't in your code. It's that you now have a fully managed durable execution layer running your workflows. No queue you have to babysit. No database you have to migrate. No retry logic you have to write. The platform handles it. You write directives.

That's the floor we'll build on for the rest of the course.


---

[Full course index](/academy/llms.txt) · [Sitemap](/academy/sitemap.md)
