## Generate a nonce

A "nonce" is a single encrypted string generated by PAL using the `NonceLoader`.
The PAL SDK requires each new stream request to be accompanied by a newly
generated nonce. However, nonces may be reused for multiple ad requests within
the same stream. To see a sample app that uses PAL to generate a nonce, download
the HTML5 example from [GitHub](https://github.com/googleads/googleads-pal).

To generate a nonce using the PAL SDK, create an HTML file and add the
following:

#### pal.html

    <html>
    <head></head>
    <body>
      <div id="placeholder-video"></div>
      <button id="generate-nonce">Generate Nonce</button>
      <script src="//imasdk.googleapis.com/pal/sdkloader/pal.js"></script>
      <script src="pal.js"></script>
    </body>
    </html>

Then, create a JavaScript file and add the following:

#### pal.js

    let videoElement;
    let nonceLoader;
    let managerPromise;
    let nonceManager;
    let playbackStarted = false;

    /**
     * Initializes the PAL loader.
     */
    function init() {
      const videoElement = document.getElementById('placeholder-video');
      videoElement.addEventListener('mousedown', (e) => void onVideoTouch(e));
      videoElement.addEventListener('touchstart', (e) => void onVideoTouch(e));
      videoElement.addEventListener('play', () => {
        if (!playbackStarted) {
          sendPlaybackStart();
          playbackStarted = true;
        }
      });
      videoElement.addEventListener('ended', () => void sendPlaybackEnd());
      videoElement.addEventListener('error', () => {
        console.log("Video error: " + videoElement.error.message);
        sendPlaybackEnd();
      });

      document.getElementById('generate-nonce')
          .addEventListener('click', generateNonce);

      // PAL automatically determines whether limited ads apply based on the TCF data
      // found on the page. You can optionally use the `forceLimitedAds` parameter
      // to manually enable limited ads regardless of the TCF data.
      const consentSettings = new goog.pal.ConsentSettings();
      nonceLoader = new goog.pal.NonceLoader(consentSettings);
    }

    /**
     * Generates a nonce with sample arguments and logs it to the console.
     *
     * The NonceRequest parameters set here are example parameters.
     * You should set your parameters based on your own app characteristics.
     */
    function generateNonce() {
      const request = new goog.pal.NonceRequest();
      request.adWillAutoPlay = true;
      request.adWillPlayMuted = false;
      request.continuousPlayback = false;
      request.descriptionUrl = 'https://example.com';
      request.iconsSupported = true;
      request.playerType = 'Sample Player Type';
      request.playerVersion = '1.0';
      request.ppid = 'Sample PPID';
      request.sessionId = 'Sample SID';
      // Player support for VPAID 2.0, OMID 1.0, and SIMID 1.1
      request.supportedApiFrameworks = '2,7,9';
      request.url = 'https://developers.google.com/ad-manager/pal/html5';
      request.videoHeight = 480;
      request.videoWidth = 640;

      managerPromise = nonceLoader.loadNonceManager(request);
      managerPromise
          .then((manager) => {
            nonceManager = manager;
            console.log('Nonce generated: ' + manager.getNonce());
          })
          .catch((error) => {
            console.log('Error generating nonce: ' + error);
          });
    }

    init();

## Attach your nonce to the ad request

To use the generated nonce, append your ad tag with a `givn` parameter and the
nonce value, before making your ad requests.

> [!CAUTION]
> **Caution:** If you previously provided a nonce using the `paln` parameter, it is strongly recommended to migrate to `givn` and stop sending `paln`. If both parameters are included, it is undefined behavior regarding which nonce one is used.

#### pal.js

      /\*\*
    \* The ad tag for your ad request, for example:
    \* https://pubads.g.doubleclick.net/gampad/ads?sz=640x480\&iu=/124319096/external/single_ad_samples\&ciu_szs=300x250\&impl=s\&gdfp_req=1\&env=vp\&output=vast\&unviewed_position_start=1\&cust_params=deployment%3Ddevsite%26sample_ct%3Dlinear\&correlator=
    \*
    \* For more sample ad tags, see https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/tags
    \*/
    const DEFAULT_AD_TAG = "Your ad tag";

      ...

      managerPromise = nonceLoader.loadNonceManager(request);
      managerPromise
          .then((manager) => {
            nonceManager = manager;
            console.log('Nonce generated: ' + manager.getNonce());
            // Append the nonce to the ad tag URL.
    makeAdRequest(DEFAULT_AD_TAG + "\&givn=" + nonceString);
          })

If you are requesting and rendering ads from Google, you must render
the [AdChoices](https://support.google.com/My-Ad-Center-Help/answer/12155764) icon and overlay.
For details about parsing the VAST response and rendering icons, see
[AdChoices icon and overlay](https://developers.google.com/ad-manager/pal/html5/wta).

## Track playback events

Lastly, you need to implement various event handlers for your player. For
testing purposes, you can attach these to button click events, but in a real
implementation, these would be triggered by the appropriate player events:

#### pal.js

    /**
     * Informs PAL that an ad click has occurred. How this function is
     * called will vary depending on your ad implementation.
     */
    function sendAdClick() {
      nonceManager?.sendAdClick();
    }

    /**
     * Handles the user touching on the video element, passing it to PAL.
     * @param {!TouchEvent|!MouseEvent} touchEvent
     */
    function onVideoTouch(touchEvent) {
      nonceManager?.sendAdTouch(touchEvent);
    }

    /** Informs PAL that playback has started. */
    function sendPlaybackStart() {
      nonceManager?.sendPlaybackStart();
    }

    /** Informs PAL that playback has ended. */
    function sendPlaybackEnd() {
      nonceManager?.sendPlaybackEnd();
    }

In your implementation, `sendPlaybackStart` should be called once your video
playback session begins. `sendPlaybackEnd` should be called once your video
playback session comes to an end. `sendAdClick` should be called each time the
viewer clicks an ad. `sendAdTouch` should be called on every touch interaction
with the player.

## (Optional) Send Google Ad Manager signals through third-party ad servers

Configure the third-party ad server's request for Ad Manager.

> [!NOTE]
> **Note:** If you use multiple third-party solutions---for example, a third-party SSAI server calling another third-party ad server, you need to make sure the PAL SDK's encrypted nonce is forwarded to each third party.

Configure your third-party ad server to include the nonce in the server's
request to Ad Manager. Here's an example of an ad tag configured inside of the
third-party ad server:

    'https://pubads.serverside.net/gampad/ads?givn=%%custom_key_for_google_nonce%%&...'

For more details, see the [Google Ad Manager Server-side implementation
guide](https://support.google.com/admanager/answer/10668760).

Ad Manager looks for `givn=` to identify the nonce value. The third-party ad
server needs to support some macro of its own, such as
`%%custom_key_for_google_nonce%%`, and replace it with the nonce query parameter
you provided in the previous step. More information on how to accomplish this
should be available in the third-party ad server's documentation.

That's it! You should now have the nonce parameter propagated from the PAL SDK,
through your intermediary servers, and then to Google Ad Manager. This enables
better monetization through Google Ad Manager.