Files
convert/frontend/vite.config.js
T
anthony e3ec3a8ba3 fix(seo): load the entry module with defer instead of async
window.__VITE_REACT_SSG_HASH__ (read by every route's data loader to fetch
static-loader-data-manifest-<hash>.json) is set by a plain inline <script>
placed later in the document body. With script: 'async', the module script
in <head> can start executing as soon as it finishes downloading, racing
ahead of the HTML parser reaching that later inline script — intermittently
reading the hash as undefined depending on network/cache timing, and
producing a 404 on .../static-loader-data-manifest-undefined.json followed
by a React hydration crash (error #418).

'defer' guarantees the module only executes after the full document,
including that inline script, has been parsed — this removes the race
structurally rather than just making it less likely.
2026-08-02 12:51:09 +02:00

39 lines
1.4 KiB
JavaScript

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import fs from 'node:fs';
import path from 'node:path';
import { listAllRoutePaths } from './src/data/routePaths.js';
const SITE_URL = 'https://convert.ombrora.com';
function writeSitemap(outDir) {
const paths = listAllRoutePaths();
const lastmod = new Date().toISOString().slice(0, 10);
const urls = paths
.map((p) => ` <url>\n <loc>${SITE_URL}${p}/</loc>\n <lastmod>${lastmod}</lastmod>\n </url>`)
.join('\n');
const sitemap = `<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n${urls}\n</urlset>\n`;
fs.writeFileSync(path.join(outDir, 'sitemap.xml'), sitemap);
}
export default defineConfig({
plugins: [react()],
server: {
proxy: {
'/api': 'http://localhost:3000',
},
},
ssgOptions: {
dirStyle: 'nested',
// 'defer' (not 'async'): the entry module reads window.__VITE_REACT_SSG_HASH__,
// which is set by a plain inline <script> placed later in the document body.
// An async module can start executing as soon as it's fetched, racing ahead
// of the parser reaching that later inline script — intermittently reading
// it as undefined depending on network/cache timing. defer guarantees the
// module only runs after the full document (including that inline script)
// has been parsed.
script: 'defer',
onFinished: writeSitemap,
},
});