Google Adsense and Google Publisher Tag AngularJS Integration

Category : Code, Analytics

Date : March 25, 2016

What is GPT ? Google Publisher Tags (GPT) is an advertising embedding library using which you can create dynamically ad requests. GPT can customize ad type, ad size, ad size, and even user custom ads.

Out of the three modes of GPT we are working Asynchronous type of ad rendering. This mode is particularly well suited for single page applications as we dont want to fetch everything in a single request but instead based on the custom criteria.

Here is a sample of the code that is a implementation of ad slots across 3 routes using a simple directive.

… which is shown in the screenshot below: ![SPA GPT Adsense]({{ site.url }}/assets/img/demos/adsense-example.png)

We have used a very old version of Angular with Angular Route and also have included bootstrap for some basic styling. Here we have generated one slot for each route and re-navigating to visited routes will return empty as ad slot is already rendered.

<!DOCTYPE html>
<html lang="en" ng-app="adsApp">

    <meta charset="UTF-8">
    <title>Adsense Test</title>
    <link rel="stylesheet" href="//" />

<body ng-controller="mainController">
    <nav class="navbar navbar-default">
        <div class="container">
            <div class="navbar-header">
                <a class="navbar-brand" href="/">Adsense Example</a>
            <ul class="nav navbar-nav navbar-right">
                <li><a href="#"> Home</a></li>
                <li><a href="#about"> About</a></li>
                <li><a href="#contact"> Contact</a></li>
    <div id="main">
        <div ng-view></div>

<script src="//"></script>
<script src="//"></script>

<script type="text/javascript" src="XYZ_ProviderURL"></script>

  var adsApp = angular.module('adsApp', ['ngRoute']);

  adsApp.config(function($routeProvider) {

          .when('/', {
          templateUrl: 'view/home.html',
          controller: 'mainController'

      .when('/about', {
          templateUrl: 'view/about.html',
          controller: 'aboutController'

      .when('/contact', {
          templateUrl: 'view/contact.html',
          controller: 'contactController'

  adsApp.controller('mainController', function($scope) {

      $scope.message = 'Home Page Data';


  adsApp.controller('contactController', function($scope) {

      $scope.message = 'contact Page Data';


  adsApp.controller('aboutController', function($scope) {

      $scope.message = 'About Page Data';


  adsApp.controller('AdsenseController', function($scope, $routeParams) {

      $scope.message = 'AdsenseController Page Data';

      var gads = document.createElement("script");
      gads.async = true;
      gads.type = "text/javascript";
      var useSSL = "https:" == document.location.protocol;
      gads.src = (useSSL ? "https:" : "http:") + "//";
      var node = document.getElementsByTagName("script")[0];
      node.parentNode.insertBefore(gads, node);

      var gptAdSlots = [];
      googletag.cmd.push(function() {
          var mapping = googletag.sizeMapping().
          addSize([1336, 294], [728, 90]).
          addSize([0, 0], [468, 60]).build();

          googletag.defineSlot('/XYZ123/Your_Personal_leaderboard', [728, 90], $scope.adClient).addService(googletag.pubads());

          googletag.pubads().collapseEmptyDivs(true, true);


  adsApp.directive('adsense', function() {
      return {
          restrict: 'E',
          replace: true,
          template: "<div id='{{adClient}}'>.</div>",
          scope: {
              adClient: '@'
          controller: 'AdsenseController'


We also a three different partials for the each route. One of them about.html is something like this.

<div class="text-center">
  <h1>About Page</h1>
  <p>{{ message }}</p>
  <adsense ad-client="div-gpt-ad-XXXYYYZZZ-ID"></adsense>


With googletag.pubads().refresh(slot); you should be able to refresh and continuous update the ad based on interactivity.

Check out the working demo here.

If you have any questions, comments or suggestions, feel free to join the discussion below!