codezero-be / laravel-localized-routes

⭐️ A convenient way to set up and use localized routes in a Laravel app.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Redirect request with default locale to omitted locale url

gaetan-hexadog opened this issue · comments

commented

Hi,

Thanks a lot for this wonderful package.
I want to use the omittedd_locale capability but I'd like to automatically redirect url containig the default locale to an url without it to use the omitted_locale behavior.
Ex: /en/about should redirect to /about when omitted_locale option is set to en.

I didn't find a way to do that with package config so I created the following middleware which is registered in the Kernel.php $middleware property.

<?php

declare(strict_types=1);

namespace Hexadog\Framework\Http\Middleware;

use Closure;
use CodeZero\LocalizedRoutes\Facades\LocaleConfig;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;

class UrlDefaultLocaleRedirect
{
    /**
     * Handle an incoming request.
     *
     * @param Request $request
     * @param Closure $next
     * @return mixed
     * @throws Exception
     */
    public function handle(Request $request, Closure $next)
    {
        $slug = $request->segment(1);

        // If supported locales is a simple array like ['en', 'nl']
        // just return the slug and let the calling code check if it is supported.
        if (!LocaleConfig::hasLocales()) {
            return $next($request);
        }

        // Find the locale that belongs to the custom domain or slug.
        // Return the original slug as fallback.
        // The calling code should validate and handle it.
        $domain = $request->getHttpHost();
        $locale = LocaleConfig::findLocaleByDomain($domain) ?? LocaleConfig::findLocaleBySlug($slug) ?? $slug;

        if ($locale === Config::get('localized-routes.omitted_locale')) {
            $segments = $request->segments();
            array_shift($segments);

            return redirect()->to(implode('/', $segments));
        }

        return $next($request);
    }
}

Is there any other way to manage that without having to use this middleware ?

Hi,

This should be possible by using the auto redirect feature.

Set the config option redirect_to_localized_urls to true, and register the following fallback route with the FallbackController at the end of your routes/web.php file.

Route::fallback(\CodeZero\LocalizedRoutes\Controllers\FallbackController::class);
commented

I already use it but unfortunately if I set up the omitted_locale to en (for ex) and type /en/about/ url in my browser I get the 404 not found error. It's because this route is considered as a fallback route apparently.

The omitted_locale config works for the other way (recognizing /about url as en/about internally)

That's weird. I just did a sanity check and tried it on a project.
It's working as expected here.
There are also tests for this, but maybe I missed something.

In the FallbackController, this should return the /about URL:

$localizedUrl = Route::localizedUrl();

That route should exist so it shouldn't be a fallback.

It's important that the Fallback route is the very last route you register, because it's a catch all.

Also, I pushed a bug fix yesterday. I don't think it's related, but you never know.
Is the SetLocale middleware applied to the Fallback route?

commented

You're right the issue was the place were I declared Route::fallback(\CodeZero\LocalizedRoutes\Controllers\FallbackController::class);

Thanks a lot for your help.