vite: Inconsistent URL trailing slash behavior between dev and preview servers
Describe the bug
Multi-page apps created with Vite do not behave consistently between dev and build preview when visiting nested URLs that do not have a trailing slash.
Using the following folder structure:
├── package.json
├── vite.config.js
├── index.html
└── nested
└── index.html
Expected: Both dev and build servers have consistent behavior when visiting <root>/nested
Actual: Dev server shows index.html
from root when visiting <root>/nested
; must use <root>/nested/
instead. Build preview, however, shows nested/index.html
when visiting <root>/nested
.
Reproduction
https://github.com/noahmpauls/vite-bug-multipage-url
System Info
System:
OS: Windows 10 10.0.19043
CPU: (8) x64 Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz
Memory: 1.02 GB / 7.75 GB
Binaries:
Node: 14.15.5 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.5 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
npm: 6.14.11 - C:\Program Files\nodejs\npm.CMD
npmPackages:
vite: ^2.7.2 => 2.7.13
Used Package Manager
npm
Logs
No response
Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn’t already an issue that reports the same bug to avoid creating a duplicate.
- Make sure this is a Vite issue and not a framework-specific issue. For example, if it’s a Vue SFC related bug, it should likely be reported to https://github.com/vuejs/vue-next instead.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- The provided reproduction is a minimal reproducible example of the bug.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 21
- Comments: 15 (1 by maintainers)
We’ve hit this inconsistency moving from Create React App/Craco to Vite.
We used to have
/foo
but to try and make production and development closer we’re going to have to change all our production urls to/foo/
to match development.Seems an annoying rule?
Was trying to work this out locally and wrote a plugin that seems to fix it:
https://gist.github.com/emma-k-alexandra/47ef18239e8a1e517160aff591e8132d
Example config:
This should be configurable in order to properly emulate a production CDN which could be configured either way.
Had same issue, here’s another solution using regex
Regex represents
/@fs/*
,/@react-refresh
,/@vite/client
, …)Chose to useres.writeHead
instead of settingreq.url
, since resolving relative path innested/index.html
created error (another inconsistency with preview but more like desired behavior)<root>/nested/
:./main.tsx
innested/index.html
-><root>/nested/main.tsx
<root>/nested
:./main.tsx
innested/index.html
-><root>/main.tsx
(Missing!)Edit If nested route has its own router (ex. react-router), using relative path in
nested/index.html
creates same problem above in its subpath (<root>/nested/abc
) Changed./main.tsx
to/nested/main.tsx
innested/index.html
, inconsistency above became not required thus reverted to settingreq.url
.As an easy workaround for simple cases you may get away with just adding a simple redirect in your main/root app from the nested app’s URL without trailing slash to the same URL with trailing slash.
For example in my React project to workaround this issue for one nested app (app using
react-router-dom
for routing) I basically added a route in the main app with path'/nested'
and set the route element to a component<RedirectToNestedSite />
which is defined like so:That’s why my suggested workaround modifies
window.location
directly to make the browser do the navigation (including full page load) instead of using client side routing to navigate. Client side routing is only used here to trigger the browser native navigation when the user arrives on the problematic URL without trailing slash (the case that loads the wrong bundle initially, but here the wrong bundle with the workaround knows what to do and redirects to the correct one).I refactor this to something similar:
EDIT: This does not work with
base
URLThis works fine but doesn’t return assets(css styles, javascript or typescript files) in the directory so I upgraded the plugin to this:
Now that Nuxt is also using vite, I imagine this is going to cause a lot more headaches