name: lovable-vite-build-fix
description: Fix Vite build for Lovable-generated React projects — non-standard entry point, missing index.html after build, post-build copy script
category: web-development
tags: [vite, lovabale, build, react]
Lovable Vite Build Fix
Problem
Lovable-generated React projects (TanStack Start) fail to build correctly with plain vite build because:
- - Root
index.htmlis a placeholder with notags (just) - - The actual entry point is
src/main.tsxbut Vite doesn't know where to find the HTML wrapper - - Build output ends up at
dist/src/index.htmlinstead ofdist/index.html - - The
vite.config.tsreferences@lovable.dev/vite-tanstack-configwhich is only available in Lovable's cloud build environment - - Lovable cloud build environment handles entry point resolution automatically; local Vite does not
- - The
src/index.htmlapproach withinput: "./src/index.html"in rollupOptions allows Vite to find the HTML template - - Always create
scripts/post-build-fix.mjsas a separate file (not inline in package.json) to avoid shell escaping issues with heredocs - - After any code change, rebuild and run the post-build script, then force hard refresh (Ctrl+Shift+R) in browser to clear nginx/vite cache
- -
/var/www/comercialrs/vite.config.ts— stripped of Lovable-specific config - -
/var/www/comercialrs/src/index.html— new entry point - -
/var/www/comercialrs/scripts/post-build-fix.mjs— copies HTML output - -
/var/www/comercialrs/package.json— updated build script - -
vite buildfails with "cannot find module" or produces 0-byte output - - Root
index.htmlis a placeholder with notags - - Build succeeds but
dist/index.htmlis missing - - Project was generated by Lovable and needs to be built locally
Solution
1. Create src/index.html as the entry point
`html
`
2. Configure vite.config.ts without Lovable plugins
`js
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
import path from "path";
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
build: {
outDir: "dist",
assetsDir: "assets",
rollupOptions: {
input: "./src/index.html"
}
},
});
`
3. Post-build fix script (scripts/post-build-fix.mjs)
Since build output goes to dist/src/index.html, copy it to dist/index.html:
`js
import { copyFileSync } from 'fs';
import { dirname, join } from 'path';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const root = join(__dirname, '..');
const src = join(root, 'dist', 'src', 'index.html');
const dst = join(root, 'dist', 'index.html');
copyFileSync(src, dst);
console.log(Copied ${src} -> ${dst});
`
4. Build command
`bash
cd /var/www/comercialrs
rm -rf dist
node ./node_modules/vite/bin/vite.js build
node scripts/post-build-fix.mjs
`
5. Update package.json scripts
`json
"scripts": {
"build": "vite build && node scripts/post-build-fix.mjs"
}
`
Key Lessons
Files involved
Trigger Conditions
Use this when: