name: tanstack-start-vps-static-assets-nginx
description: Fix TanStack Start (Lovable-style) showing blank page / 404 on assets when deployed to VPS — nginx must serve /assets/ directly, not proxy to Node.js.
tags:
- tanstack-start
- vps
- nginx
- static-assets
TanStack Start VPS — Static Assets 404 Fix
Context
When a TanStack Start app (built with target: "node-server") is deployed to VPS and shows:
- - Blank page or loading spinner forever
- - Console errors:
Failed to load resource: 404for all JS/CSS assets - - Assets exist in
dist/client/assets/but return 404 - -
dist/server/— SSR server (handles routing, API, auth) - -
dist/client/— static assets (JS, CSS, images) - - Project:
/var/www/documentos2/app/ - - Client assets:
/var/www/documentos2/app/dist/client/assets/ - - Server entry:
/var/www/documentos2/app/start-server.mjs - - Port: 3010 (DocCorretor)
Root Cause
TanStack Start target: "node-server" builds have two output directories:
The Node.js server (dist/server/server.js) only handles SSR and API routes. It does NOT serve static files. In production, nginx must serve /assets/ directly from dist/client/assets/.
If nginx proxies /assets/ to Node.js, Node returns a 404 because it has no static file handler built in.
Fix: nginx Config
Change nginx location /assets/ from proxy to alias:
`nginx
location /assets/ {
alias /var/www/
expires 1d;
add_header Cache-Control "public, no-transform";
try_files $uri =404;
}
`
Full Working nginx Config Example
`nginx
server {
server_name domain.com;
location /assets/ {
alias /var/www/
expires 1d;
add_header Cache-Control "public, no-transform";
try_files $uri =404;
}
location / {
proxy_pass http://127.0.0.1:
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/
ssl_certificate_key /etc/letsencrypt/live/
}
`
Debug Commands
`bash
Test if assets are reachable directly via nginx
curl -sI https://domain.com/assets/index-nwIlITaw.js
200 = OK, 404 = nginx proxying to Node instead of serving
Check what files exist in the client build
ls /var/www/
Reload nginx after config change
nginx -t && systemctl reload nginx
`
Key Files on This VPS
Distinguishing from Similar Issues
| Symptom | Cause | Fix |
| --------- | ------- | ----- |
| All assets 404, page blank | nginx proxying /assets/ to Node | Change to alias |
| Port EADDRINUSE | Another process on same port | kill -9 , restart |
| Docker "module not found" | Corrupted Docker image | Use node directly |
| Vite build fails Node 18 | Node version too old | nvm use 20 |