Run both services locally
We have two working applications and two terminals running development servers. With Services configured, vercel dev will start FastAPI and Next.js together and route requests through one local URL.
Outcome
Configure Vercel Services and run the storefront and FastAPI routes through one local URL.
Hands-on exercise 2.1
Configure the services
Stop the standalone Next.js and FastAPI servers. In a terminal at the repository root, enter the student project:
cd starterCreate vercel.json here, beside frontend/ and backend/:
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"services": {
"frontend": {
"root": "frontend/",
"framework": "nextjs",
"bindings": [
{
"type": "service",
"service": "backend",
"format": "url",
"env": "BACKEND_URL"
}
]
},
"backend": {
"root": "backend/",
"framework": "fastapi",
"entrypoint": "main:app"
}
},
"rewrites": [
{
"source": "/api",
"destination": {
"service": "backend"
}
},
{
"source": "/api/(.*)",
"destination": {
"service": "backend"
}
},
{
"source": "/(.*)",
"destination": {
"service": "frontend"
}
}
]
}Vercel builds each application listed in services separately. Each root is relative to this configuration file. The backend's main:app entrypoint identifies the FastAPI application we ran in Section 1.
The top-level rewrites direct /api and /api/* to the backend. The final catch-all sends other requests to Next.js. Their order matters: the API rules must come before the frontend rule. These rules preserve the request path, so /api/items reaches FastAPI's /api/items route.
Give the frontend a backend address
The bindings entry is inside frontend, the service making the request. It grants the frontend internal access to backend and supplies its URL as BACKEND_URL at runtime. Vercel generates this value for local development and each deployment; we do not add it to an .env file.
The public rewrite lets us open /api/items in a browser. In the next lesson, the internal binding will let the Next.js Server Component fetch that inventory directly from the backend. The service bindings documentation explains how these internal requests work.
The API rewrites deliberately expose our sample inventory wherever the deployment is accessible. A binding grants internal access; application-level authentication belongs in the service code when an API needs it.
Start the local services
Run the CLI from starter/, the directory containing vercel.json:
vercel dev -LThis one command starts both FastAPI and Next.js. We no longer need to run uv run fastapi dev main.py and npm run dev (which starts next dev) in separate terminals. The CLI also supplies the BACKEND_URL binding.
The -L flag runs Services locally without linking a cloud project. Use the URL the CLI prints, normally http://localhost:3000. Keep this single process running while working on the next lesson.
Try It
In another terminal, open the storefront and request the backend. Replace port 3000 if the CLI selected another port:
curl http://localhost:3000/api
curl http://localhost:3000/api/itemsThe first returns the Hazel Home API message. The second returns eight furniture items. Open http://localhost:3000 to see the storefront, which still uses mock data.
A browser can now reach both applications through one origin. We do not need CORS middleware for these same-origin requests.
Commit
From starter/, save the Services configuration:
git add vercel.json
git commit -m "feat(services): configure frontend and FastAPI backend"Troubleshooting
The CLI rejects services or bindings: Update with npm install -g vercel@latest. This course uses the current services model, not the earlier experimentalServices configuration.
The frontend loads but /api/items returns 404: Check that the API rewrites precede the frontend catch-all, the destination names match the service keys, and backend/main.py defines /api/items. The public rewrite does not strip /api.
A service root cannot be found: Run vercel dev -L from starter/. Both service directories must be siblings of vercel.json.
FastAPI's /docs page is missing on port 3000: Our public rules send /docs to Next.js. The API docs from Section 1 were served by the standalone FastAPI server on port 8000. Use /api/items to check the backend through Services.
A port is busy: Stop the standalone servers from Section 1 with Ctrl+C, then restart the Services command.
Done-When
starter/vercel.jsondefinesfrontendandbackendwith the correct roots- The frontend declares a
BACKEND_URLbinding to the backend - API rewrites precede the frontend catch-all
- One
vercel dev -Lprocess starts both apps, with the standalone servers stopped - The local storefront loads and
/api/itemsreturns eight items through the same origin
Solution
The complete vercel.json above configures both applications for local development and deployment. From the directory containing that file, run:
vercel dev -LWas this helpful?