Search code examples
facebooklaravelmiddleware

Detect Facebook Crawler in middleware


I have several pages in my laravel app that I need to share link in Facebook.

Thing is, when I share it, Facebook get the properties og:image from login page, as it is redirect by my middleware.

I saw here that I must detect Facebook User Agent and redirect to a public page that should only have the openGraph properties to render link in Facebook.

Is it the only way?

I will end up creating a middleware, with a switch inside, to manage all the differents publics pages I have, it is not so nice...

Any idean how should I do that???


Solution

  • I solved it creating my own Middleware : RedirectCrawlers

        <?php
    
    namespace App\Http\Middleware;
    
    use App\Tournament;
    use Closure;
    use Illuminate\Support\Facades\Route;
    
    class RedirectCrawlers
    {
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request $request
         * @param  \Closure $next
         * @return mixed
         */
        public function handle($request, Closure $next)
        {
            $crawlers = [
                'facebookexternalhit/1.1',
                'facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)',
                'Facebot',
                'Twitterbot',
            ];
    
            $userAgent = $request->header('User-Agent');
    
            if (str_contains($userAgent, $crawlers)) {
                switch (Route::getCurrentRoute()->getPath()) {
                    case "tournaments/{tournament}/register":
                        $tournament = Tournament::where('slug', $request->tournament)->first();
                        return view('public/register', compact('tournament'));
                }
            }
            return $next($request);
        }
    }
    

    Then I created a resources/views/public/register.blade.php

    <meta property="og:title" content="{{trans('core.competitors_register') }}"/>
    
    
    <meta name="description" content="Registrate en el torneo {{ $tournament->name }}"/>
    <meta property="og:description" content="Registrate en el torneo {{ $tournament->name }}"/>
    <meta property="og:type" content="website"/>
    <meta property="og:image" content="https://kendozone.com/wp-content/uploads/2016/04/home.jpg"/>
    <meta property="og:image:secure_url" content="https://kendozone.com/wp-content/uploads/2016/04/home.jpg"/>
    <meta property="og:url" content="{{$request->url()}}"/>
    <meta property="fb:app_id" content="780774498699579"/>
    
    <meta name=" twitter:title" content="{{trans('core.competitors_register')}}"/>
    <meta name="twitter:image" content="https://kendozone.com/wp-content/uploads/2016/04/home.jpg"/>
    <meta name="twitter:card" content="summary"/>
    <meta name="twitter:description" content="Registrate en el torneo {{ $tournament->name }}"/>
    

    that is a public page, that just have info needed to share to Facebook.

    Then in App\Http\Kernel.php I add the route inside $middlewareGroups in 'web', before Authenticate Middleware, so that it redirect it to the public page :

            \App\Http\Middleware\RedirectCrawlers::class,
    

    Solution exists in stackOverflow, like commented, but none of them for Laravel 5.3!

    Hope it helps!