Bug in non-trailing slash rewrite

So it looks like your links for your css and js files are not relative. When going to https://gamemaster.pixelastic.com/barrowmaze, the links try to load as image. I think if you change your link and script tags to show href="style.4f8d993218.css" instead of href="./style.4f8d993218.css" (minus the dot and forward slash), the redirect will work in both with and without trailing slashes. Let me know if it does.

Hey everyone,

I was also wondering about this, since adding a trailing slash to folders is a pretty standard web server behavior. (Not sure if it’s an actual standard, but it’s definitely expected behavior in nginx and Apache to do a 301 redirect from /directory to /directory/).

…and after signing up for Netlify Analytics today I ended up at this thread from Google thinking I was doing something wrong, since even it gets confused by this non-standard behavior:

My suggestion would be to just fall in line with what nginx and Apache (and apparently GitHub Pages) do to make things simpler, but this is just my two cents. :slight_smile:

Thanks as always!

Well, there’s a bit of a problem with that - those URL’s will behave differently.

Imagine an index.html file like this, saved in a directory called “my-picture”:

<img src=asset.png>

When called as https://site/my-picture , the “asset.png” should be found in /
When called as https://site/my-picture/ or https://site/my-picture/index.html, the “asset.png” should be found in the my-picture subdirectory. Further, if you have a my-picture.html next to /my-picture/ our Pretty URL’s functionality (and that of site generators like Jekyll) will need to make those behave differently.

So it is a bit more than just “always do this thing I want with trailing slashes”.

All the practical difficulties aside, I have an open feature request to allow you to specify a specific behavior, and I’ve added this thread to the request, so we can let you know if things change.

But today, we don’t have good facilities for doing much about that.

Hey, thanks @Dennis. Unfortunately that doesn’t work as it will still try to load assets from the root. As @fool explains in this thread, a Netlify page served from http://site/foo sees itself as foo.html, not as foo/index.html, so all relative links are actually resolved one directory higher than expected.

I’m trying to find a way around that but have had no luck so far. Any http://site/foo webpage currently serves a broken version (with no style/script) of http://site/foo/. Only workarounds I can think of right now would be to only use absolute urls for loading assets, or redirect the faulty pages with JavaScript. Both are inconvenient and bring their own drawback, though.

I see. The only thing I can think of would be to try redirecting those assets specifically. Something like:

/style.4f8d993218.css https://gamemaster-barrowmaze.netlify.com/style.4f8d993218.css 200!

The drawback would be that you would need to do this for each asset that is 404-ing and for any file whose filename has changed.

That’s unfortunately not doable. The hash in the filenames of my assets is generated based on the file content and changes every time the file changes.

Keeping my redirect file in sync with the current asset list is going to pretty unwieldy as they are in two different repositories and I don’t want this kind of coupling.

Sounds like with all your constraints, it may not be possible to host your site in its current form on netlify. Sorry we don’t have better news for you!

Thanks for the reply.

The workaround I’ll use for now is to handle the redirection with a short snippet of JavaScript in my <head>.

I wrote a method that checks if the current url is in the form of site.com/foo and redirects it to site.com/foo/ (keeping any query string or hash unchanged). I packaged it as an npm module if anyone else wants to use it.

The README even includes a copy-pastable minified version of the code if you just need a quick fix without requiring modules.


Just wanted to chime in and say I have the exact same issue. I have a few reverse proxies of the following form:

/projectname/* https://build-server-example.com/projectname/:splat 200

If one reads the rule literally, it shouldn’t touch the /projectname url, only the /projectname/* urls. However, it tries to reverse-proxy the /projectname url and all my relative urls, styles and scripts break.

If you visit /projectname without the slash, you would expect it to 404, but it breaks instead.

Like pixelastic, I am planning to add a javascript redirect to my HTML pages - however, because I proxy several projects like this, I will have to add this code to several repositories, so it’s not an ideal solution.

1 Like

Hi @maxlaumeister,

Thanks for that additional context. As fool mentioned, there is an enhancement request for the issue described in this thread and we’ll update here if and when it get implemented.

Sorry for jumping in.

I came across a similar issue. My 404 custom page does not display the correct css whenever the url ends with a trailing slash.

Any thoughts on how solving this issue?

Thank you.

I suspect you are loading the css with relative paths (something like a href=file.css or a href=../file.css). Try using absolute paths like a href=/path/to/file.css instead.

I’m also experiencing the same issue. I have a _redirects file containing:

/blog/*  https://my-blog-app.netlify.com/:splat 200

Before Netlify, I was using GitHub pages for deployment of static pages, and if a user would navigate to /blog, they would be redirected to /blog/ so all the relative paths to assets like CSS and JavaScript are correct.

On Netlify this does not happen. The user stays on /blog, and all the relative URLs are now broken rendering the page without CSS and JavaScript.

After reading everything about redirects and trailing slashes (https://docs.netlify.com/routing/redirects/redirect-options/#trailing-slash) on netlify I came across the “Pretty URL” feature which promises: “Rewrite link URLs to pretty URLs (/about.html -> /about, /about/index.html -> /about/)”. This does nothing unfortunately. Why is this mentioned in the redirect docs if it does nothing for redirects?

What this means, to repeat what @brianzelip said earlier:

This means that Netlify cannot be used as a replacement for what GitHub Pages provides in this matter. Using GH Pages, I had the base custom domain (zelip.me) set from my brianzelip.github.io repo, and any other repo I set to be published via Pages, was available at zelip.me/*. In that GH Pages case, no matter if there was a trailing slash or not, EVERYTHING WORKED as expected.

Hopefully there is an ongoing feature request for this already, but I would like to be able to enable “redirect to trailing slash” feature for redirects. The same way GitHub pages/CDN behaves.

There are also a bunch of people using Gatsby that are having issues with this, you can follow the discussion over at their GitHub repo: https://github.com/gatsbyjs/gatsby/issues/9207


Edit: Upon further investigation I realised the “Pretty URL” does help for the rest of the page: eg /about does indeed redirect to /about/ (if about is a directory containing a index.html file), now if only the same could apply for redirects!

Hi @danielstocks, welcome to the Netlify Community!

A great many people (including me) have migrated their GitHub Pages projects to Netlify successfully, so I suspect we can get your setup working, too. It’s hard to help, though, when we can’t try things out. Could you share a link to the site(s) you’re working on?

Hi, Thank you, but I can assure you that this is not working as many people in this thread has described the exact same problem.

https://webcloud-main.netlify.com/ (main page)
https://webcloud-main.netlify.com/Assortment => 200 redirects to => https://webcloud-assortment.netlify.com/

_redirects file:

/Assortment/*  https://webcloud-assortment.netlify.com/:splat 200

As you can see visiting: https://webcloud-main.netlify.com/Assortment is a broken page, visiting https://webcloud-main.netlify.com/Assortment/ everything works as expected. GitHub pages will always redirect to a trailing slash. You can test this with my existing setup here:


^ these are two different repositories on GitHub and two separate GitHub Pages builds.

With that being said: Migrating a single page from GitHub Pages isn’t the issue. It’s trying to migrate the multi-repo one-site/domain setup.

To follow up on this: the only way to get around this now is to inject a JavaScript hack like this at the top of the page.

if(!window.location.pathname.endsWith("/")) {
  window.location = window.location + "/"

This is far from ideal though, Google will still treat my-domain.com/page and my-domain.com/page/ as two seperate URL’s serving duplicate content.

I think the limitation boils down to this https://docs.netlify.com/routing/redirects/redirect-options/#trailing-slash

If it had been possible to do a rewrite rule like this, everything would have been fine:

/Assortment/*  https://webcloud-assortment.netlify.com/:splat 200
/Assortment /Assortment/ 301!

The issue is worse than I thought.

I just found out that:

1.1. If an unknown url ends with a trailing slash (https://www.mywebsite.com/unknownpage/) not only my custom 404 css page is broken but any existing link that’s supposed to take me to one of website page (https://www.mywebsite.com/existingpage) in fact redirects me to another 404 instead (https://www.mywebsite.com/unknownpage/existingpage).
1.2. On the other hand, if an unknown url does not end with a trailing slash (https://www.mywebsite.com/unknowpage) then my custom 404 page css is displayed correctly and any clicked link redirects me to the proper url of an existing page (https://www.mywebsite.com/existingpage).
2. I tried using absolute paths like /css/style.css and it does solve my css issues. However, the problem described in 1.1 still occurs.

Ah, right, @danielstocks I missed that you were requiring a 200 proxy rewrite in your setup. Most folks I know migrating from GitHub Pages use 301 redirects, like:

/Assortment/*   https://assortment.webcloud.se/:splat  301

With that scheme, all links to webcloud.se/Assortment should redirect and display properly, but of course it does change their URL in the address bar. (Incidentally, it does not, however, hurt SEO.)

Personally, I prefer the subdomain pattern (subproject.maindomain.com) over the subdirectory one (maindomain.com/subproject) because I think it signals more clearly that it’s a different site (not just some folder on the main site), and it’s significantly more portable. I totally understand that this isn’t the right choice for everyone, though.

Hi, @tattooseoul. Would you please send us the an actual URL where these issues occur so we can research what is happening?

You can private message (PM) that to one of our support staff if you don’t want to share it publicly. I’ve confirmed that PMs are enabled for your community login. Note, that only one person can see the PM and this will likely mean a slower reply than posting the information publicly. Please feel free to reply to however you prefer though.

Hi @luke. I sent you a PM. Thank you.