---
title: "Deploy to Production"
description: "Run vercel deploy at the project root and watch both the Next.js frontend and the FastAPI backend ship together under one domain. No extra config, no second project, no manual env vars."
canonical_url: "https://vercel.com/academy/python-on-vercel/deploy-to-prod"
md_url: "https://vercel.com/academy/python-on-vercel/deploy-to-prod.md"
docset_id: "vercel-academy"
doc_version: "1.0"
last_updated: "2026-05-11T07:05:19.541Z"
content_type: "lesson"
course: "python-on-vercel"
course_title: "Python on Vercel"
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 Production

# Deploy to Production

You've already done the hard part. The project structure is what Vercel expects: Next.js at the root, Python in `api/`, dependencies declared in `package.json` and `pyproject.toml`. `vercel dev` has been running everything under one URL. Shipping to production is the same command without the `dev`.

## Outcome

Deploy the combined project to Vercel with `vercel deploy --prod` and confirm both the Next.js frontend and the FastAPI backend are live under a single domain.

## Fast Track

1. `cd starter` (the project root)
2. `vercel deploy --prod`
3. Open the deployment URL and visit both `/` and `/api/items`

## Hands-On

### Deploy

From the `starter/` root:

```bash
vercel deploy --prod
```

The project is already linked from `vercel dev` in Section 2, so the CLI skips the setup prompts and starts building. A few seconds later:

```
✓ Deployed to production.

https://hazel-home.vercel.app
```

One URL. Both apps.

### What Vercel auto-detected

While the deploy was running, Vercel did three things without being told:

- **Detected Next.js** from `package.json`. Built the app with Turbopack, served `/` and any other app-router routes as the main frontend.
- **Detected Python functions** in `api/`. Installed `pyproject.toml` dependencies, packaged `api/index.py` as a serverless function, and routed `/api/*` requests to it.
- **Wired routing** so `/` and `/api/*` share one domain. Same-origin everywhere, no CORS, no rewrites.

No `vercel.json`. No framework preset to pick manually. The project structure is the config.

### Verify the frontend

Open the deployment URL in a browser:

```
https://hazel-home.vercel.app
```

The furniture listing loads with real data from FastAPI. The server component built the URL from `process.env.VERCEL_URL` (auto-injected in production), fetched `/api/items` from the same deployment, and rendered the list.

### Verify the backend directly

Hit the backend path:

```
https://hazel-home.vercel.app/api/items
```

FastAPI returns the same JSON it's been returning all along. Same app, different host.

### What you didn't have to do

Pause and notice the things that aren't here:

- No second Vercel project for the Python backend
- No CORS config, because there's no cross-origin call
- No `BACKEND_URL` or `API_URL` env var to set by hand, because the frontend and backend share a domain
- No coordination between two dashboards. One project, one log stream, one team

The Python-and-Next.js deployment story that usually takes two projects and a stack of environment variables becomes one command.

\*\*Note: Cold starts\*\*

Vercel runs Python functions as serverless. The first request after a period
of inactivity may take an extra second or two while the function initializes.
Subsequent requests are fast.

\*\*Note: Flask and Django work the same way\*\*

Same pattern, different framework. Put Flask in `api/index.py` with a
top-level `app = Flask(__name__)`, and Vercel picks it up. Django uses its
own preset, but the project layout (Python in `api/`, JavaScript at the root)
is the same.

## Try It

Verify the full stack:

```bash
curl https://hazel-home.vercel.app/api/items
```

```json
[{"id":1,"name":"Fernwood Sectional","category":"Seating","price":2499.0,"in_stock":true},...]
```

```bash
curl -s https://hazel-home.vercel.app | grep "Fernwood"
```

```
Fernwood Sectional
```

The first confirms FastAPI is serving data at `/api/items`. The second confirms the Next.js server component fetched from FastAPI, rendered the result, and returned HTML to the browser.

## Troubleshooting

**Deploy succeeds but `/api/items` returns a 404:** The FastAPI routes don't include the `/api` prefix. Open `starter/api/index.py` and confirm the routes are `@app.get("/api")` and `@app.get("/api/items")`, not `/` and `/items`.

**Deploy fails with "No module named fastapi":** `pyproject.toml` isn't at the project root or dependencies aren't declared. Check that `starter/pyproject.toml` exists and lists `fastapi` under `dependencies`.

**Frontend loads but items don't appear:** The fetch is failing. Check the deployment logs in the Vercel dashboard. The most common cause is `process.env.VERCEL_URL` being unexpectedly undefined. The `VERCEL_URL` variable is injected automatically on all plans, but if you're testing preview deployments from a branch, double-check the Vercel dashboard shows it as a system env var.

**You want to clean up:** When you're done with the course, you can delete the `hazel-home` project from the Vercel dashboard to remove the deployment.

## Done-When

- [ ] `vercel deploy --prod` succeeds from the `starter/` root
- [ ] `https://hazel-home.vercel.app` loads the furniture listing page
- [ ] `https://hazel-home.vercel.app/api/items` returns the FastAPI JSON
- [ ] You can confirm the frontend is actually fetching from the backend (edit `api/index.py`, redeploy, see the change)

## Solution

```bash
cd starter
vercel deploy --prod
```

One command, both apps, one domain. The Python backend and the Next.js frontend live in the same Vercel project, and you never had to touch a second deployment target.


---

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