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
/foobut 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.writeHeadinstead of settingreq.url, since resolving relative path innested/index.htmlcreated error (another inconsistency with preview but more like desired behavior)<root>/nested/:./main.tsxinnested/index.html-><root>/nested/main.tsx<root>/nested:./main.tsxinnested/index.html-><root>/main.tsx(Missing!)Edit If nested route has its own router (ex. react-router), using relative path in
nested/index.htmlcreates same problem above in its subpath (<root>/nested/abc) Changed./main.tsxto/nested/main.tsxinnested/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-domfor 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.locationdirectly 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
baseURLThis 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