A simple learning project: a website with a button that calls a backend API. Both parts are deployed separately on Vercel (free Hobby plan). An optional Neon Postgres database stores the click count.
fullstack-demo/
├── backend/ Express API (runs as a Vercel serverless function)
│ ├── api/index.js All backend routes
│ ├── vercel.json Sends every URL to api/index.js
│ └── package.json
└── frontend/ Vite website
├── index.html
├── src/main.js Button click -> calls the backend
├── .env.example
└── package.json
| Setting | Where | Purpose |
|---|---|---|
VITE_API_URL |
Frontend env var | Tells the website where the backend lives |
FRONTEND_URL |
Backend env var | CORS: only this website may call the API |
DATABASE_URL |
Backend env var (optional) | Connects to the Neon database |
| Method | Route | What it does |
|---|---|---|
| GET | / |
Health check |
| GET | /hello |
Returns a hello message |
| POST | /click |
Counts a click and returns the total |
- Node.js (LTS) and npm
- Git
Use two terminals.
Terminal 1: backend
cd backend
npm install
npm start
Opens at http://localhost:3000
Terminal 2: frontend
cd frontend
npm install
copy .env.example .env (Mac/Linux: cp .env.example .env)
npm run dev
Opens at http://localhost:5173
Windows PowerShell tip: if
npmis blocked, usenpm.cmdinstead (e.g.npm.cmd install).
- Open http://localhost:3000 and check that you see
"status":"Backend is running". - Open http://localhost:5173 and click Call Backend.
- The page should show
Click received by backend! Total clicks: 1. - Watch the backend terminal for log lines, and press F12 in the browser to see the frontend logs.
- Vercel dashboard -> Add New -> Project -> import this repo.
- Set Root Directory to
backend. - Click Deploy and copy the URL.
- Open the URL in the browser to test it.
- Add New -> Project -> import the same repo.
- Set Root Directory to
frontend. - Add the environment variable
VITE_API_URL= your backend URL (no trailing slash). - Click Deploy and copy the URL.
- Backend project -> Settings -> Environment Variables.
- Add
FRONTEND_URL= your frontend URL (no trailing slash). - Deployments -> Redeploy the backend.
- Backend project -> Storage -> create a Neon Postgres database and connect it.
- This adds
DATABASE_URLautomatically. - Redeploy the backend. The root URL should now say
"database":"connected".
- Open the frontend URL and click Call Backend.
- Check the backend logs: backend project -> Logs.
- Open the browser console (F12) to see frontend logs.
| Problem | Fix |
|---|---|
| CORS error in console | Check FRONTEND_URL (exact URL, no trailing slash) and redeploy the backend |
Frontend shows API: NOT SET |
Add VITE_API_URL in Vercel and redeploy the frontend |
| Backend URL shows a Vercel login page | Backend project -> Settings -> Deployment Protection -> turn it off |
| Env var change has no effect | Redeploy; variables only apply to new deployments |
npm blocked in PowerShell |
Use npm.cmd, or run Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned |