Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I get AngularJS to use different controllers for Facebook OpenGraph scraper?

I have an AngularJS application that is served up using http-server

I want my the meta-tags (og:title, og:description, og:image) to be populated dynamically for Facebook and other scrapers (like Slack) to post rich-links on social media sites. However, it is tricky because those scrapers do their scraping of the original HTML page before angular dynamically inserts the proper values. So the scrapers see the placeholder values.

One solution to this problem is described here. Basically: feed the scraper-bots static HTML with desired og fields already populated. I would like to do that. But unlike that author, I'm not using apache. In http-server there is no .htaccess file that I'm aware of.m

I use UI-Router and $state-provider to handle the URLs provided to my application like this:

  $stateProvider.state('splash',
      {
          url: '/',
          templateUrl: 'html/splash.html',
          controller: 'SplashCtrl',
          data: {
              meta: {
                'title': 'My Title',
                'description': 'My Description'
              }
          }
      }
  );

Is there some way I can create a state such that scraper-bots will be sent to a different controller than normal human users using a web-browser? How?

like image 540
Saqib Ali Avatar asked May 30 '17 04:05

Saqib Ali


1 Answers

We had the same problem with one of our web applications. We solved it by making some of the following changes. It involves making changes in both the frontend and the backend.

The first problem in this case is, angular uses /#/ as the separator to determine routes and history. If you share a link that has the # char, anything after it will be ignored and not be sent to the server. To dynamically generate metadata for social sites, we need the part after #. So, we eliminate the /#/ altogether.

angular.module('myApp', [])
    .config(function($locationProvider) {
        $locationProvider.html5Mode(true);  // 
    });

Ref: https://docs.angularjs.org/api/ng/provider/$locationProvider

Setting this will make sure your URLs will now change from http://app_host/#/my_url to http://app_host/my_url

Just to make sure AngularJS now understands how to interpret its routes, you need to set the base path for your application

<html>
    <head>
        <base href="/">
    </head>
</html>

With this config, your sharable links now will land on your backend server, where you always return the same index.html file, but with dynamic meta tags based on the extra path params you receive.

like image 166
bugs_cena Avatar answered Nov 10 '22 01:11

bugs_cena