Project: SPA and API Gateway
Introduction
This project runs a single domain with a Vite/React static frontend at / and a Spring Boot or Node API at /api/. Nginx routes by path—the standard production pattern for hello_code full-stack apps.
Prerequisites
- Location Matching and Routing
- Proxying Spring Boot and Node.js
- Built frontend
dist/and API on127.0.0.1:8080(or:3000)
Architecture
text
https://app.example.com/
/ → /var/www/app (SPA)
/api/... → proxy → 127.0.0.1:8080Step 1: Deploy Frontend
bash
sudo mkdir -p /var/www/app
sudo rsync -av ./dist/ /var/www/app/
sudo chown -R www-data:www-data /var/www/appStep 2: Start Backend on Localhost
Spring Boot:
bash
java -jar app.jar --server.address=127.0.0.1 --server.port=8080Or Node on 8080—adjust proxy_pass port if using 3000.
Confirm:
bash
curl http://127.0.0.1:8080/api/healthStep 3: Nginx Config
/etc/nginx/sites-available/app:
nginx
Code explanation:
/api/strip prefix if backend serves/usersnot/api/users—match your API designtry_files ... /index.html— SPA client routes
Enable and test:
bash
sudo ln -sf /etc/nginx/sites-available/app /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
curl http://app.example.com/api/health
curl -I http://app.example.com/Step 4: HTTPS
bash
sudo certbot --nginx -d app.example.comCORS: Backend vs Nginx
| Approach | When |
|---|---|
Backend CORS (@CrossOrigin, Express cors) | Same domain /api/ — often no CORS needed |
| Nginx add_header | Split domains (api. vs www.) or legacy setups |
Same-origin SPA + /api/ avoids browser CORS for fetch to relative /api/....
If API on different subdomain:
nginx
add_header Access-Control-Allow-Origin "https://www.example.com" always;Prefer configuring CORS in the API for dynamic origins.
Acceptance Checklist
- SPA loads at
/ - Client route
/dashboardrefresh works (not 404) -
curl https://app.example.com/api/...returns JSON - No 502 when API running; clear 502 when API stopped (expected)
-
sudo nginx -tclean
FAQ
API 404 through proxy?
Fix proxy_pass trailing slash vs backend context path.
Frontend calls wrong URL?
Use relative /api/... in frontend env, not hardcoded :8080.
WebSocket on same host?
Add upgrade headers under /api/ws/ location—WebSocket chapter.