core
core copied to clipboard
SEO problem due to duplicate response from trailing slash and non trailing slashed version of the url
SEO problem due to duplicate response from trailing slash and non trailing slashed version of the url ..
eg:
the route
Flight::route('/team',function(){
include 'team.php' ;
});
now both
www.debmego.in/team
and
www.debmego.in/team/
give the same http response with code 200
but good SEO practice is to return any one with a http code 301
this should be done inbuil by the framework,, i think
A simple solution which i implemented is as follows
Flight::route('*',function(){ $req = Flight::request(); if(substr($req->url,-1) == '/') { $url = rtrim($req->url,'/'); Flight::redirect($url,301); } return true ; });
Flight::route('/team',function(){ include 'team.php' ; });
Thanks for your contribution shankuandyou!
Somehow that function returns a blank screen with me, are you using https?
Try this one
Flight::route('*',function(){
$request = Flight::request();
if($request->url != '') {
if(substr($request->url,-1) == '/' && strlen($request->url) > 1) {
$url = rtrim($request->url,'/');
Flight::redirect($url,301);
}
}
return true;
});
Thanks, that did it.
@mikecao, any ETA when implementing/fixing this into flight core?
We use Apache, and use an .htaccess file that looks something like this that solves your issue:
RewriteEngine On
RewriteBase /
RedirectMatch 301 ^(.+)/$ $1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . /index.php [L]
I'm sure there are other ways to accomplish this on other web servers as well.
Since I may move my applications around a lot, I prefer to keep everything in the PHP code instead of webserver configuration files. That way, when you move something around from NGINX to Apache, it doesn't break much.
I'm not saying it's not a good way to do it, but I prefer to keep everything in the code.
Ya, there's advantages and disadvantages to each way, whether on Nginx or Apache we're forced to have it redirect our requests to Flight anyways I find it pretty convenient to just add it there.
It's also nice not to have to load the entire framework (albeit a pretty small one), which may register other classes, or make other calls, etc... just to have it redirect you.
Thanks @rkempt, using Apache myself.
You are right on that point. I guess a small checkup of the request_uri before loading the framework would be better in term of performance than doing it in the framework. But your solution is the best, performance-wise, that's for sure.
Just because I ran into a similar problem, I expanded on @frederichoule 's suggestion. The following will work even if there are query strings in the URL.
Flight::route('*', function () {
$request = Flight::request();
if ($request->url != '') {
list($base, $query) = array_pad(explode('?', $request->url, 2), 2, null);
if (substr($base, -1) == '/' && strlen($base) > 1) {
$url = rtrim($base, '/');
if ($query !== null) {
$url .= '?' . $query;
}
Flight::redirect($url, 301);
}
}
return true;
});
I wanted to write a Flight::before('route', function(){});
But I did not get enough time to write it and see if possible.
I'm pretty sure as I was going through all the unit tests for this, that this situation is covered. If it's not covered, lets go ahead and reopen another issue.