core icon indicating copy to clipboard operation
core copied to clipboard

SEO problem due to duplicate response from trailing slash and non trailing slashed version of the url

Open sudiptadeb opened this issue 9 years ago • 11 comments

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

sudiptadeb avatar May 13 '15 07:05 sudiptadeb

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' ; });

sudiptadeb avatar May 13 '15 07:05 sudiptadeb

Thanks for your contribution shankuandyou!

frederichoule avatar May 27 '15 00:05 frederichoule

Somehow that function returns a blank screen with me, are you using https?

Conver avatar Sep 23 '15 17:09 Conver

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;
});

frederichoule avatar Sep 23 '15 18:09 frederichoule

Thanks, that did it.

@mikecao, any ETA when implementing/fixing this into flight core?

Conver avatar Sep 23 '15 18:09 Conver

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.

rdkempt avatar Sep 23 '15 19:09 rdkempt

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.

frederichoule avatar Sep 23 '15 20:09 frederichoule

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.

rdkempt avatar Sep 23 '15 20:09 rdkempt

Thanks @rkempt, using Apache myself.

Conver avatar Sep 23 '15 20:09 Conver

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.

frederichoule avatar Sep 23 '15 20:09 frederichoule

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.

josevh avatar Mar 17 '17 18:03 josevh

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.

n0nag0n avatar Jan 03 '24 21:01 n0nag0n