-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Routing] Trailing slash redirection prevents routes to be matched #32996
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
It looks like the doc needs to be updated! |
Hi @nicolas-grekas |
Yes, that's correct. |
closing here then @Jean-ita please open an issue in the documentation repository if there is something to improve, thanks |
When was that change introduced? I thought the redirection only happens when no other route matches. |
I think it's useful to have the possibility to have |
@Tobion , @javiereguiluz and everyone else: don't you think that this should be at least configurable? Otherwise we run into bc issues when migrating from older version and also into SEO issue, considering /foo and /foo/ are different pages in terms of SEO |
Hi,
Thanks |
Two parts in this comment: 1.I've reopened the code to figure out the behavior I implemented/fixed last year regarding trailing slashes. TL;DR, I think there is no bug despite the recent comments. The behavior can be described has such: trailing slash redirections have a higher priority than route ordering. There is one exception: when a variable is put at the end of a route, and when this variable has a requirement that makes a trailing slash a MUST or a DON'T, then the redirection happens last when applicable (see part 2. below). The behavior dates back to the origin of the components, you can verify: the For static routes, this was not the case and route ordering could apply. That's surely why the documentation states this (obsolete) behavior. But this was inconsistent (why would priority of redirection change when adding a variable?!?), and is now fixed. The behavior is the result of several expectations. One example is from you @javiereguiluz, and critical for symfony.com, if you remember this issue (#29287): when a route for In my opinion, that elephant is now properly modelled with the behavior we have, all grasped in test cases that link back to issues that explain how this should behave in edge cases too, reported as BC breaks when some changes broke the corresponding use cases. I wish nobody else to spend the time I've burned on this. Note that I'm not saying another model doesn't exist. I'm only saying that the problem is harder than what you think, and I consider it solved personnaly. Could be because I'm lazy, you'll tell, show me the code :) 2.Back to the topic: How can one have better control of the trailing slash redirections? First of all, a global flag would be inappropriate to me. Global behavior changes might break expectations of e.g. third party bundles (same reasoning as why php.ini settings are bad for global behavior control.) As I mentionned earlier, it is possible to force a route to NOT match with (or without) a trailing slash. Here is how (the underscore could be replaced by any random var name):
WIth these two routes, I agree this is not very user friendly but you can use it immediately if you need to, it won't have any performance overhead. We could also imagine a way for the router to generate this for us. I don't know precisely how, but this should still give a path forward if anyone wants to invest time in improving this. Could be "just" documented also. |
Note that there is another way to describe the behavior of the router regarding trailing slashes: routes with and without trailing slashes are considered canonically equivalent. |
To me the implementation we had at one point (#29287) to only do the redirect when nothing else matches was really simple and really easy to understand and would also be really simple to disable if people wanted. Now it's complex with alot of edge cases to cover old behavior. But the bc breaks are still there, just in a different place, as pointed out in
And this explains all the issues that have been opened about the trailing slashes. But the current behavior is done and changing it would maker other people unhappy again. So let's just try to live with it and document it. |
Thanks @nicolas-grekas and @Tobion for your feedbacks. I understand your point about BC here. However I will double check that this behavior is fully consistent across implementations (I had a case lately where behavior was slightly different between dev and prod regarding trailing slashes, I'm not sure if it's fully fixed with #33244). However I disagree about the global flag. A 3rd party bundle should not rely on this trailing slash redirection. It already cannot rely on the generated path for a route, so it cannot rely on this trailing slash management. And it should not. |
I don't understand the issue with trailing slashes: the generator always creates URLs that use the canonical version. If you define |
The real issue with SEO is that it's slightly different to have a 404 page changed to a 200 (when I create a matching route), than a 301 changing to a 200. Google poorly handle 30X, especially on news or AMP 3rd party cache.
This example is pretty simple, but things are more complicated when you add placeholders. I cannot share much details here, but a similar issue caused a massive SEO bug on a very important day lately. The router was not the issue, but similar assumptions have been made and search engines were basically lost.
Because it will. Somebody will hit this url one day or another. Probably sooner that you think. We have a lot of 404 every day from url which never existed. If it comes from chrome, you can be sure that googlebot will come and check on it. In conclusion, you summarize what the framework should not do, there is no good reason to do that: "routes with and without trailing slashes are considered canonically equivalent". Routes with and without trailing slashes are different routes. |
Please continue the discussion on #33342 |
Symfony version(s) affected: 4.3.3
Description
When using yaml to configure routes, if I have 2 routes that only differs on the trailing slash (/foo and /foo/) only the first one in the yaml file works, the second one always redirect to the first one.
This happens with hard coded routes (
/foo
) or with wildcards (/{param}
)The documentation says this should not happen: https://symfony.com/doc/current/routing.html#routing-trailing-slash-redirection
How to reproduce
The routing yaml file is:
The text was updated successfully, but these errors were encountered: