Get started

The Ad Placement API supports the pre-caching/loading of the interstitial ads. Developers will use the API to signal potential ad breaks/moments in a game or other interactive media, but the precise decisions around when to show ads and which ads to show are delegated to Google.

The Ad Placement API is designed to support AdSense developers using interstitial ads in HTML5 games on the web or within super-apps, or in other interactive media. This guide demonstrates how to integrate the Ad Placement API into a simple game.

Prerequisites

Before you begin, you will need the following:

  • To create these empty files:
    • index.html
    • game.js
  • Python installed on your computer, or a web server to use for testing.

1. Start a development server

Because the Ads Placement API loads dependencies via the same protocol as the page which it is loaded on, you need to use a web server to test your app. The simplest way to start a local development server is to use Python's built-in server.

  1. Using a command line, from the directory that contains your index.html file run:
    python -m http.server 8000
  2. In a web browser, go to http://localhost:8000/

You can also use any other web server, such as the Apache HTTP Server.

2. Create a simple HTML5 canvas game

Modify index.html to create a simple HTML5 canvas element and a button to trigger gameplay. Also add the necessary script tag to load the game.js file.

index.html

<!doctype html>
<html lang="en">
  <head>
    <title>Ad Placement API HTML5 simple demo</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
  </head>
  <body>
    <canvas id="gameContainer" height="300px" width="300px"></canvas>
    <button id="playButton">Play</button>
    <button style="display:none" id="headsButton">Heads</button>
    <button style="display:none" id="tailsButton">Tails</button>

    <script src="game.js"></script>
  </body>
</html>

Modify game.js to play a coin flip game when the "Play" button is clicked.

game.js
class Game {
  constructor() {
    // Define variables
    this.score = 0;
    this.choice = '';

    this.canvas = document.getElementById('gameContainer').getContext('2d');
    this.canvas.font = '24px Arial';

    this.playButton = document.getElementById('playButton');
    this.headsButton = document.getElementById('headsButton');
    this.tailsButton = document.getElementById('tailsButton');

    // On click listeners for the game's buttons.
    this.playButton.addEventListener('click', () => {
      this.erase();
      this.play();
    });

    this.headsButton.addEventListener('click', () => {
      this.choice = 'Heads';
      this.flipCoin();
    });

    this.tailsButton.addEventListener('click', () => {
      this.choice = 'Tails';
      this.flipCoin();
    });

    this.erase();
  }

  // Start the game
  play() {
    this.score = 0;
    this.canvas.fillText('Score: ' + this.score, 8, 26);
    this.canvas.fillText('Heads or Tails?', 66, 150);
    this.playButton.style.display = 'none';
    this.headsButton.style.display = 'inline-block';
    this.tailsButton.style.display = 'inline-block';
  }

  // Flip the coin
  flipCoin() {
    this.headsButton.disabled = true;
    this.tailsButton.disabled = true;
    this.erase();
    this.canvas.fillText('Score: ' + this.score, 8, 26);
    this.canvas.fillText('Flipping coin . . .', 60, 150);

    setTimeout(() => { this.coinLanded() }, 2000);
  }

  // Logic for when the coin lands
  coinLanded() {
    this.headsButton.disabled = false;
    this.tailsButton.disabled = false;
    let sideUp;
    if(Math.random() < 0.5) {
      sideUp = 'Heads';
    } else {
      sideUp = 'Tails';
    }

    if (sideUp === this.choice ) {
      this.win(sideUp);
    } else {
      this.lose(sideUp);
    }
  }

  // Guess the flip correctly
  win(sideUp) {
    this.erase();
    this.score += 1;
    this.canvas.fillText('Score: ' + this.score, 8, 26);
    this.canvas.fillText('It was ' + sideUp + '!', 66, 150);
    this.canvas.fillText('Guess again', 70, 200);
  }

  // Guess the flip incorrectly
  lose(sideUp) {
    this.erase();
    this.canvas.fillText('Sorry, it was ' + sideUp, 50, 100);
    this.canvas.fillText('Your score was ' + this.score, 50, 150);
    this.canvas.fillText('Want to play again?', 45, 200);

    this.playButton.style.display = 'inline-block';
    this.headsButton.style.display = 'none';
    this.tailsButton.style.display = 'none';
  }

  // Erase the canvas
  erase() {
    this.canvas.fillStyle = '#ADD8E6';
    this.canvas.fillRect(0, 0, 300, 300);
    this.canvas.fillStyle = '#000000';
  }
}

const game = new Game();

After completing this step, when you open index.html in your browser (via your development server) you should be able to see the game canvas and "Play" button. If you click Play, the coin flip game should start.

3. Import the Ad Placement API

Next, add the Ad Placement API to your game by inserting a script tag in index.html, before the tag for game.js.

index.html
...

    <canvas id="gameContainer" height="300px" width="300px"></canvas>
    <button id="playButton">Play</button>
    <button style="display:none" id="headsButton">Heads</button>
    <button style="display:none" id="tailsButton">Tails</button>

    <script async
      data-ad-client="ca-pub-123456789"
      data-adbreak-test="on"
      src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js">
    </script>

    <script>window.adsbygoogle = window.adsbygoogle || [];
      const adBreak =  adConfig = function(o) {adsbygoogle.push(o);}
    </script>
    
    <script src="game.js"></script>
  </body>
</html>

4. Make a call to adConfig().

The adConfig() call communicates the game's current configuration to the Ad Placement API. The API then can use this information to filter the types of ads it requests so they are suitable for the game (eg. video ads that require sound if sound is enabled). A call should be made to adConfig() any time this configuration changes, like when a user mutes or unmutes the game. Make a call to adConfig() in the game's constructor, then add a button to mute and unmute the game that makes an additional adConfig() call.

Currently adConfig() only takes the sound parameter which accepts values of 'on' and 'off'. If sound is not set it will default to off. More parameters will be added in future releases of the API.

game.js
class Game {
  constructor() {
    // Define variables
    this.score = 0;
    this.choice = '';
    this.muted = false;

    this.canvas = document.getElementById('gameContainer').getContext('2d');
    this.canvas.font = '24px Arial';

    this.playButton = document.getElementById('playButton');
    this.headsButton = document.getElementById('headsButton');
    this.tailsButton = document.getElementById('tailsButton');
    this.muteButton = document.getElementById('muteButton');

    adConfig({
      sound: 'on',
    });

    // On click listeners for the game's buttons.
    this.playButton.addEventListener('click', () => {
      this.erase();
      this.play();
    });

    this.headsButton.addEventListener('click', () => {
      this.choice = 'Heads';
      this.flipCoin();
    });

    this.tailsButton.addEventListener('click', () => {
      this.choice = 'Tails';
      this.flipCoin();
    });

    this.muteButton.addEventListener('click', () => {
      var soundString = this.muted ? 'on' : 'off';
      this.muteButton.innerHTML = this.muted ? 'Mute sound' : 'Un-mute sound';
      this.muted = !this.muted;
      adConfig({
        sound: soundString,
      });
    });

    this.erase();
  ...

Now, add the mute button to your HTML file.

index.html
...

    <canvas id="gameContainer" height="300px" width="300px"></canvas>
    <button id="playButton">Play</button>
    <button style="display:none" id="headsButton">Heads</button>
    <button style="display:none" id="tailsButton">Tails</button>
    <button id="muteButton">Mute sound</button>

    <script async
      data-ad-client="ca-pub-123456789"
      data-adbreak-test="on"
      src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js">
    </script>
    ...

5. Make a call to adBreak() when the game ends.

The adBreak() call defines an ad placement and it takes an object called a placement config that specifies everything required to show an ad at this point in your game. Supporting different types of ads will require you to initialize different subsets of the placement config. To learn about these subsets, see the adBreak placement config guide.

The adBreak() call defines a placement where an ad could show, i.e., an opportunity to show an ad. Whether an ad actually shows will depend on a number of things:

  • The type of ad placement that you declared.
  • If there have been suitable user interactions prior to this ad placement.
  • Whether a suitable ad exists for the current player, that:
    • Is relevant to them.
    • Is consistent with their data privacy and consent settings.
  • The number of ads the user has seen recently.
  • The control settings you have configured for this game as either:
    • Hints in the tag.
    • On AdSense (Note: the controls available in AdSense will evolve over time)

In this guide we will be adding code for an interstitial ad to be shown when the game restarts. Do so by making a call to adBreak() inside the play() function that will only occur after the game has been played through once. adBreak() must be called as part of a user action like clicking the "Play" button, otherwise the API will not be able to request and display ads. In addition, create functions to be called before and after the ad break, which you will use in the adBreak() placement config. It is important to note that beforeBreak and afterBreak functions will only be called if a suitable ad is found.

game.js
class Game {
  constructor() {
    // Define variables
    this.score = 0;
    this.choice = '';
    this.muted = false;
    this.shouldShowAdOnPlay = false;

...

  // Start the game
  play() {
    if (this.shouldShowAdOnPlay) {
      this.shouldShowAdOnPlay = false;

      adBreak({
        type: 'next',  // ad shows at start of next level
        name: 'restart-game',
        beforeBreak: () => { this.disableButtons(); },  // You may also want to mute the game's sound.
        afterBreak: () => { this.enableButtons(); },    // resume the game flow.
      });
    }

    this.score = 0;
    this.canvas.fillText('Score: ' + this.score, 8, 26);
    this.canvas.fillText('Heads or Tails?', 66, 150);
    this.playButton.style.display = 'none'
    this.headsButton.style.display = 'inline-block'
    this.tailsButton.style.display = 'inline-block'
  }

...

  // Guess the flip incorrectly
  lose(sideUp) {
    this.erase()
    this.canvas.fillText('Sorry, it was ' + sideUp, 50, 100);
    this.canvas.fillText('Your score was ' + this.score, 50, 150);
    this.canvas.fillText('Want to play again?', 45, 200);

    this.playButton.style.display = 'inline-block'
    this.headsButton.style.display = 'none'
    this.tailsButton.style.display = 'none'
    this.shouldShowAdOnPlay = true;
  }

...

  // Erase the canvas
  erase() {
    this.canvas.fillStyle = '#ADD8E6';
    this.canvas.fillRect(0, 0, 300, 300);
    this.canvas.fillStyle = '#000000';
  }

  enableButtons() {
    this.playButton.disabled = false;
    this.headsButton.disabled = false;
    this.tailsButton.disabled = false;
  }

  disableButtons() {
    this.playButton.disabled = true;
    this.headsButton.disabled = true;
    this.tailsButton.disabled = true;
  }

}

const game = new Game();

Your app is now creating ad placements for ads to be displayed! Your own app may have additional appropriate places for ads other than when the game ends. Calling adBreak() there should be similar to how we have done it in this guide. Before releasing your app, it is important to remove the line data-adbreak-test="on" in index.html in order to not use test settings in production.