From b24c09766d7a355337c58d11cc9936b51a884898 Mon Sep 17 00:00:00 2001 From: Sam Dunster Date: Thu, 25 Sep 2025 11:27:20 +1000 Subject: [PATCH] feat(server): Make SPA fallback try each directory component SPA fallback tries looking for a corresponding index.html for each directory component all the way down to root. --- .../src/node/server/middlewares/htmlFallback.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/vite/src/node/server/middlewares/htmlFallback.ts b/packages/vite/src/node/server/middlewares/htmlFallback.ts index b61b44bf061180..1a57bd84dc1d39 100644 --- a/packages/vite/src/node/server/middlewares/htmlFallback.ts +++ b/packages/vite/src/node/server/middlewares/htmlFallback.ts @@ -63,8 +63,20 @@ export function htmlFallbackMiddleware( } if (spaFallback) { - debug?.(`Rewriting ${req.method} ${req.url} to /index.html`) - req.url = '/index.html' + // remove a path component at a time from pathname and check for + // the presence of a corresponding index.html + let workingPathname = pathname + while (true) { + const filePath = path.join(root, workingPathname, 'index.html') + if (fs.existsSync(filePath)) { + const newUrl = workingPathname + '/index.html' + debug?.(`Rewriting ${req.method} ${req.url} to ${newUrl}`) + req.url = newUrl + return next() + } + if (workingPathname === '/') break + workingPathname = path.dirname(workingPathname) + } } next()