Sổ tay kỹ thuật

Vite app deploy dưới URI prefix sau Nginx

troubleshooting#nginx#vite#cloudflare-tunnel· cập nhật 2026-10-28

Xử lý trắng trang, 404 asset và lỗi Mixed Content khi chạy app Vite dưới /app/ phía sau Nginx hoặc Cloudflare Tunnel.

Sửa trang này
Mục lục

Triệu chứng chính: truy cập https://tools.example.net/app/ thấy trang trắng, console báo GET /assets/index-xxx.js 404 hoặc Mixed Content: ... requested an insecure resource 'http://...'.

Lỗi thường gặp

Triệu chứng Nguyên nhân Cách xử lý
Asset 404 tại /assets/... Vite build với base: '/' Đặt base: '/app/' trong vite.config.ts
Refresh trang con bị 404 Nginx không fallback về index.html try_files $uri $uri/ /app/index.html;
Mixed Content Backend sinh URL http:// vì không biết TLS đã terminate ở tunnel Gửi X-Forwarded-Proto https, app đọc header này
API gọi sai /api thay vì /app/api Hard-code đường dẫn tuyệt đối Dùng import.meta.env.BASE_URL
Redirect về http://...:8080 proxy_redirect mặc định giữ port upstream absolute_redirect off;

Cấu hình đúng

vite.config.ts
import { defineConfig } from 'vite'
 
export default defineConfig({
  base: '/app/',
})
/etc/nginx/conf.d/tools.conf
server {
    listen 80;
    absolute_redirect off;
 
    location = /app { return 301 /app/; }
 
    location /app/ {
        alias /srv/app/dist/;
        try_files $uri $uri/ /app/index.html;
    }
 
    location /app/api/ {
        proxy_pass http://127.0.0.1:8000/;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-Prefix /app;
    }
}

Kiểm tra nhanh

curl -sI https://tools.example.net/app/ | head -1
curl -s https://tools.example.net/app/ | grep -o 'src="[^"]*"'   # phải bắt đầu bằng /app/
nginx -t && systemctl reload nginx

Với Cloudflare Tunnel, cloudflared luôn nói chuyện HTTP với origin. Hãy để Nginx gắn X-Forwarded-Proto https thay vì tin header từ client.