mcamara / laravel-localization

Easy localization for Laravel
MIT License
3.36k stars 512 forks source link

give the ability to choose the redirect type (ex: 301) to improve SEO. #881

Open ZakariaTlilani opened 1 year ago

ZakariaTlilani commented 1 year ago

Is your feature request related to a problem? Please describe. yes, it is. When choosing to activate 'hideDefaultLocaleInURL' which removes the default locale short name in the URL (ex: /fr ) and while having a 302 redirect hard coded that means all link are "temporary redirect", the entire website has a duplicate (according to the crawlers -ex: google), which is very harmfull to the websites SEO. the bigger the website the worst the issue gets.

Describe the solution you'd like i think what would be best is to simply allow the coder to choose by setting another variable in config file.

petrosit commented 1 year ago

Upvote! This makes sense!

@ZakariaTlilani I have a workaround for this: I created a custom middleware with this logic:

$url = $request->fullUrl();

$appUrl = Env::get('APP_URL'); $stripped = Str::replace($appUrl, "", $url); $parsedUrl = parse_url($stripped); $path = $parsedUrl["path"];

if (Str::startsWith($path, "/de/")) { $noDe = Str::replaceFirst("de/", "", $url); session(['locale' => 'de']); return redirect()->to($noDe, 301); }

Whereas "/de/" is my default locale.

But of course a proper solution would be great! Like a config param to set the HTTP code.

ZakariaTlilani commented 1 year ago

@petrosit yes, this seems one of the good solutions. some of my clients want the default language abrivation to be show in there URL, others don't so my solution was similar to your's the only difference is i made a bool variable and linked it to my nova admin panel so the app manager can choose as they wish. i think this solution can be standard as this is just a package but an env variable could do it and would be enough.

franky-ds commented 5 months ago

The package uses 302 by default. Here is my custom middleware to convert 302's to 301's. It returns only one redirect to 301.

public function handle($request, Closure $next)
    {
        $response = $next($request);

        // check if the response is a 302 redirect
        if ($response instanceof RedirectResponse && $response->getStatusCode() === 302) {

            // keep 302 for domain root
            if ($request->path() == '/') {
                return $response;
            }

            // set status code to 301
            $response->setStatusCode(301);
        }

        return $response;
    }