import { defineConfig, type PluginOption } from 'vite' import react from '@vitejs/plugin-react' import path from 'path' import fs from 'fs' // SPA fallback middleware - runs after Vite's built-in middleware function spaFallback(): PluginOption { return { name: 'spa-fallback', configureServer(server) { // Return a function to execute after Vite's internal middleware return () => { server.middlewares.use((req, res, next) => { // Skip API routes and file requests if (req.url?.startsWith('/api') || req.url?.includes('.')) { return next() } // Serve index.html for SPA routes const indexPath = path.resolve(__dirname, 'index.html') if (fs.existsSync(indexPath)) { res.statusCode = 200 res.setHeader('Content-Type', 'text/html') let html = fs.readFileSync(indexPath, 'utf-8') server.transformIndexHtml(req.url || '/', html).then(transformed => { res.end(transformed) }).catch(next) } else { next() } }) } }, configurePreviewServer(server) { // Same logic for preview server server.middlewares.use((req, res, next) => { if (req.url?.startsWith('/api') || req.url?.includes('.')) { return next() } const indexPath = path.resolve(__dirname, 'dist/client/index.html') if (fs.existsSync(indexPath)) { res.statusCode = 200 res.setHeader('Content-Type', 'text/html') res.end(fs.readFileSync(indexPath, 'utf-8')) } else { next() } }) } } } export default defineConfig({ plugins: [react(), spaFallback()], root: '.', publicDir: 'public', build: { outDir: 'dist/client', }, server: { host: '0.0.0.0', proxy: { '/api': { target: 'http://localhost:3000', changeOrigin: true, }, }, }, preview: { host: '0.0.0.0', }, resolve: { alias: { '@': path.resolve(__dirname, 'src/client'), '@shared': path.resolve(__dirname, 'src/shared'), }, }, })