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.
This commit is contained in:
2026-08-02 12:51:09 +02:00
parent ca4f896256
commit e3ec3a8ba3
+8 -1
View File
@@ -25,7 +25,14 @@ export default defineConfig({
},
ssgOptions: {
dirStyle: 'nested',
script: 'async',
// '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,
},
});