feat: serve client static files + SPA fallback in production
This commit is contained in:
+21
-1
@@ -1,6 +1,9 @@
|
|||||||
import express from 'express';
|
import express from 'express';
|
||||||
import cors from 'cors';
|
import cors from 'cors';
|
||||||
|
import path from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
import { errorHandler } from './middleware/errorHandler.js';
|
import { errorHandler } from './middleware/errorHandler.js';
|
||||||
|
import { env } from './config/env.js';
|
||||||
|
|
||||||
// Routes
|
// Routes
|
||||||
import authRoutes from './modules/auth/auth.routes.js';
|
import authRoutes from './modules/auth/auth.routes.js';
|
||||||
@@ -13,11 +16,14 @@ import reservationRoutes from './modules/reservation/reservation.routes.js';
|
|||||||
import billboardRoutes from './modules/billboard/billboard.routes.js';
|
import billboardRoutes from './modules/billboard/billboard.routes.js';
|
||||||
import paymentRoutes from './modules/payment/payment.routes.js';
|
import paymentRoutes from './modules/payment/payment.routes.js';
|
||||||
|
|
||||||
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
// Middleware
|
// Middleware
|
||||||
app.use(cors({
|
app.use(cors({
|
||||||
origin: ['http://localhost:5173', 'http://localhost:3000'],
|
origin: env.NODE_ENV === 'production'
|
||||||
|
? true // same-origin in production
|
||||||
|
: ['http://localhost:5173', 'http://localhost:3000'],
|
||||||
credentials: true,
|
credentials: true,
|
||||||
}));
|
}));
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
@@ -38,6 +44,20 @@ app.get('/api/health', (_req, res) => {
|
|||||||
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
res.json({ status: 'ok', timestamp: new Date().toISOString() });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ─── Static files (production) ───────────────────────
|
||||||
|
// In Docker, client dist is at /app/public
|
||||||
|
// Locally after build, resolve relative to compiled output
|
||||||
|
const publicDir = path.resolve(__dirname, '../public');
|
||||||
|
app.use(express.static(publicDir));
|
||||||
|
|
||||||
|
// SPA fallback — serve index.html for all non-API routes
|
||||||
|
app.get('*', (_req, res, next) => {
|
||||||
|
const indexPath = path.join(publicDir, 'index.html');
|
||||||
|
res.sendFile(indexPath, (err) => {
|
||||||
|
if (err) next(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// Error handler
|
// Error handler
|
||||||
app.use(errorHandler);
|
app.use(errorHandler);
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"build": "20260608-1548",
|
"build": "20260608-1607",
|
||||||
"buildDate": "2026-06-08T15:48:03.9541198+07:00"
|
"buildDate": "2026-06-08T16:07:41.1459281+07:00"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user