fix(serve): serve index.html from public subdirectories - #22559
Conversation
| expect(await bothSlashIndexHtml.text()).toContain('both/index.html') | ||
| }) | ||
|
|
||
| test.runIf(isServe)( |
There was a problem hiding this comment.
We should run this test in build as well so that it's consistent.
There was a problem hiding this comment.
Addressed in f1caef5 — removed runIf(isServe) so this test now runs in build as well (the extensionless-alias assertions stay dev-only since the fallback middleware only exists on the dev server).
Verified locally:
pnpm test-serve html→ 65 passedpnpm test-build html→✓ should serve index.html from public subdirectories
There was a problem hiding this comment.
the extensionless-alias assertions stay dev-only since the fallback middleware only exists on the dev server
we should make this behavior consistent in dev and build.
There was a problem hiding this comment.
Done in 472b50b. Dev now mirrors the preview server's html fallback for public files: /foo resolves to /foo.html and /foo/ to /foo/index.html, using the same method/Accept conditions as htmlFallbackMiddleware (instead of sirv's extensions option, which would also resolve /foo → /foo/index.html — something the preview server does not do).
The test assertions now run unconditionally in both serve and build:
pnpm test-serve html→ 65 passedpnpm test-build html→ 55 passed (✓ should serve index.html from public subdirectoriesin both)assets/fs-serveplaygrounds pass in serve as regression checks
avinashkamat48
left a comment
There was a problem hiding this comment.
Adding extensions: ["html"] to the public sirv middleware appears to broaden behavior beyond directory indexes: an explicit request for /foo can now resolve to public/foo.html if that file exists. The PR title/test only covers /subdir/ -> /subdir/index.html, so this extensionless-file fallback may be an unintended public serving change. Please add a test for /file vs /file.html (or avoid the global extensions option and handle only trailing-slash index.html) so the new behavior is intentional.
472b50b to
b0ade3b
Compare
|
Rebased onto latest Review feedback is addressed as follows:
@sapphi-red ready for another look when you have time. |
Serve public/ subdirectory indexes at trailing-slash URLs and align extensionless .html resolution with preview's htmlFallbackMiddleware. When public/foo/bar/index.html exists, /foo/bar/ now serves it (fixes vitejs#6714). For Accept: text/html requests, /foo also resolves to public/foo.html so dev matches preview. Avoids sirv extensions which would also map /foo -> /foo/index.html (preview does not).
b0ade3b to
02638e9
Compare
|
Rebased onto latest Review feedback from June/July is still in this patch:
The previous @sapphi-red ready for another look when you have time. |
Description
Fixes #6714
When
index.htmllives under apublic/subdirectory (e.g.public/foo/bar/index.html), navigating to/foo/bar/now serves that file — matching/foo/bar/index.htmland typical static-server directory index behavior.Also aligns extensionless public HTML resolution between dev and preview:
/foo/bar/public/foo/bar/index.html/foopublic/foo.htmlApproach
Update
servePublicMiddlewareto mirrorhtmlFallbackMiddlewarefor public files only:GET/HEADwithAcceptcontainingtext/htmlor*/*publicFilessetsirvinstance (extensions: [])This deliberately does not use sirv's
extensions: ['html'], which would also map/foo→/foo/index.html(preview does not do that).Tests
Playground
htmlcoverage (serve + build):/subdir/and/subdir/index.html→public/subdir/index.html/public-fileand/public-file.html→public-file.htmlReview follow-ups addressed
extensions: ['html']/ document intentional/file→/file.html— @avinashkamat48Verification
Rebased onto latest
main.