serve
serve copied to clipboard
Default trailingSlash config breaks relative links
Relative href attributes are not correctly resolved based on the configuration of cleanUrls
and trailingSlash
config.
Scenario
Files:
-
/login/index.html
-
/login/login.ts.html
The index.html has an anchor tag linking to the other page like following:
<a href="login.ts.html">login.ts</a>
(Something like this could be found in an instanbul coverage html report)
This looks to me like a correct link that should correctly link from index.html to login.ts.html.
Observed behavior
- Start
serve
- Open browser on localhost:5000/login/index.html
- The server responds with 301:
Location | /login/index
(this must be the result of thecleanUrls
setting removing the file ending .html) - The browser follows the redirect and requests localhost:5000/login/index.html
- The server responds again with 301, now for:
Location | /login
(is this also part of thecleanUrls
setting? but anyway, settingtrailingSlash
to false changes the target/login/
) - The browser requests localhost:5000/login and gets a result that is rendered
- The browser resolves the relative URL "login.ts.html" as a sibling of "/login" and goes to localhost:5000/login.ts.html
- Serve can not serve the file because this path does not exist.
Expected behavior
Serve should (by default) be configured, so that requesting localhost:5000/login/index.html should settle on one of the following URLs to not break relative URL resolution:
- localhost:5000/login/index.html
- localhost:5000/login/index
- localhost:5000/login/
I am aware that i can configure my serve.json
to disable trailingSlash
. This solves my problem locally but i am arguing for making sure that the default configuration should be changed.
Just wanted to confirm that I've run into similar.
Looks like serve
can't tell the difference between a subpath and a filename that it's stripped the extension from.
Short of broken user-supplied rewrite rules, it's very incorrect for correctly-supplied paths in an HTML to 404, and it's frustrating that this breakage is caused by gold plating.
AFAICT, it's conventional for web servers to add a trailing slash when removing "index.html" from a URL (which keeps relative links within subpaths intact) but not to do the other things serve
attempts.
Thank you to @lukengda for explaining & providing a workaround... I thought I was going crazy, and even switched a static-page project to all absolute paths because I didn't realize the problem was serve
.
Ok, apparently this issue has already been raised a few other times, over a period of years. A couple others:
- https://github.com/vercel/serve-handler/issues/79
- https://github.com/vercel/serve/issues/441
But what I did as a workaround (because I still prefer serve to simplehttpserver): Create a serve.json
with
{
"trailingSlash": true
}
Then I put that in my home folder, and aliased serve
as serve='serve -c ~/serve.json'
.
Edit: the right trailingSlash
setting actually depends on what you're trying to serve. For foo/index.html
you want it on, but for foo.html
you want it off. 🙄
Here's a better workaround:
$ python -m SimpleHTTPServer 5000
I'm encountering the same issue. I have a directory like:
index.html
docs
index.html
images
image1.png
image2.png
...
The docs/index.html
contains references to images/image1.png
. When I open a link to docs/index.html
from the main application index.html
, it is redirected to docs
, and then the relative urls to the images are broken.