Rewarded Ads

How to implement rewarded ads for web using Fuse

Overview

Rewarded ads are a user-initiated ad format where users voluntarily opt-in to watch an ad in exchange for a reward. This format is commonly used for:

  • Unlocking premium content (articles, videos, features)
  • Granting in-game currency or items
  • Providing extra lives or power-ups
  • Offering access to premium features
  • Unlocking WiFi access at airports or public spaces

Rewarded ads provide a positive user experience because users choose when to engage with ads and receive tangible value in return.

How it Works

The rewarded ad format uses Google Publisher Tag’s REWARDED out-of-page format. Fuse provides a simple API to:

  1. Register the ready, granted, and closed callbacks
  2. Register and load a rewarded ad
  3. Receive the ready callback when the ad is ready
  4. Make the ad visible to the user (user-initiated)
  5. Receive the granted callback when the reward is granted (after required viewing duration)
  6. Receive the closed callback when the ad is closed

Important: Always register onRewardedReady, onRewardedGranted, and onRewardedClosed before calling registerRewarded. The ready callback can fire as soon as the ad loads — if the callback is not registered yet, you will miss the event and never know the ad is ready to display.

Important: The reward is only granted if the user watches the ad for the required duration:

  • Display ads: Typically 5 seconds of viewable time
  • Video ads: Completion or skip threshold (for TrueView ads)

Configuration

Admin Panel Setup

In the Fuse admin panel, create a zone with the rewarded attribute set to true. This tells Fuse to configure the zone as a rewarded ad slot.

{
  "attributes": {
    "rewarded": true
  }
}

You can optionally configure custom reward values in Google Ad Manager:

  • Reward Type: The type of reward (e.g., “coins”, “lives”, “articles”)
  • Reward Amount: The quantity of the reward (e.g., 20, 5, 3)

API Reference

Register onRewardedReady, onRewardedGranted, and onRewardedClosed before calling registerRewarded. The APIs below are listed in the order they should be called.

fusetag.onRewardedReady(callback)

Sets a callback function to be called when the rewarded ad is ready to display. Register this before calling registerRewarded — the ready callback can fire as soon as the ad loads, and a callback registered after that point will not be invoked.

Parameters:

  • callback (function): A callback function that receives the zone code as a parameter

Example:

fusetag.que.push(function() {
  fusetag.onRewardedReady(function(zoneCode) {
    console.log('Rewarded ad is ready:', zoneCode);
    // Enable your "Watch Ad" button or similar UI
  });
});

fusetag.onRewardedGranted(callback)

Sets a callback function to be called when the user earns the reward. This fires after the user has watched the ad for the required duration. Register this before calling registerRewarded.

Parameters:

  • callback (function): A callback function that receives:
    • zoneCode (string): The zone code
    • payload (object | null): Reward information with properties:
      • type (string): The reward type (e.g., “coins”, “lives”, “article”)
      • amount (number): The reward amount

Example:

fusetag.que.push(function() {
  fusetag.onRewardedGranted(function(zoneCode, payload) {
    console.log('Reward granted!', zoneCode, payload);

    if (payload) {
      const rewardType = payload.type;    // e.g., "coins"
      const rewardAmount = payload.amount; // e.g., 20

      // Grant the reward to the user
      grantReward(rewardType, rewardAmount);
    }
  });
});

fusetag.onRewardedClosed(callback)

Sets a callback function to be called when the user closes the rewarded ad. Register this before calling registerRewarded.

Parameters:

  • callback (function): A callback function that receives the zone code as a parameter

Example:

fusetag.que.push(function() {
  fusetag.onRewardedClosed(function(zoneCode) {
    console.log('Rewarded ad was closed:', zoneCode);
    // Update UI, re-register ad for next time if needed
  });
});

fusetag.registerRewarded(zoneCode)

Registers and loads a rewarded ad for the specified zone code. Call this after registering the ready, granted, and closed callbacks.

Parameters:

  • zoneCode (string): The zone code configured in the Fuse admin panel

Example:

fusetag.que.push(function() {
  fusetag.registerRewarded('my_rewarded_zone');
});

fusetag.displayRewarded()

Makes the rewarded ad visible to the user. This should only be called after the ad is ready and in response to a user action (e.g., clicking a “Watch Ad” button).

Parameters:

  • None

Example:

fusetag.que.push(function() {
  fusetag.displayRewarded();
});

Implementation Example

Here’s a complete example of implementing rewarded ads for a paywall scenario:

<!DOCTYPE html>
<html>
<head>
  <title>Premium Content</title>
  <script async src="https://cdn.fuseplatform.net/publift/tags/2/YOUR_ACCOUNT/fuse.js"></script>
</head>
<body>
  <div id="content-container">
    <h1>Premium Articles</h1>
    <p>Articles remaining: <span id="articles-remaining">3</span></p>

    <button id="read-article" onclick="readArticle()">Read Article</button>
    <button id="watch-ad" onclick="watchAd()" style="display: none;">
      Watch Ad to Unlock More Articles
    </button>
  </div>

  <script>
    const fusetag = window.fusetag || (window.fusetag = { que: [] });
    let articlesRemaining = 3;
    let adReady = false;

    fusetag.que.push(function() {
      // Set up callbacks
      fusetag.onRewardedReady(function(zoneCode) {
        console.log('Rewarded ad is ready:', zoneCode);
        adReady = true;
      });

      fusetag.onRewardedGranted(function(zoneCode, payload) {
        console.log('Reward granted!', zoneCode, payload);

        // Grant the reward
        if (payload) {
          articlesRemaining += payload.amount;
          updateDisplay();
          alert(`You earned ${payload.amount} ${payload.type}(s)!`);
        }
      });

      fusetag.onRewardedClosed(function(zoneCode) {
        console.log('Rewarded ad closed:', zoneCode);

        // Re-register for next time
        adReady = false;
        fusetag.que.push(function() {
          fusetag.registerRewarded('test_rewarded');
        });
      });

      // Register the rewarded ad
      fusetag.registerRewarded('test_rewarded');
    });

    function readArticle() {
      if (articlesRemaining <= 0) {
        document.getElementById('read-article').disabled = true;
        document.getElementById('watch-ad').style.display = 'inline-block';
        alert('No articles remaining! Watch an ad to unlock more.');
        return;
      }

      articlesRemaining--;
      updateDisplay();

      // Show article content...
    }

    function watchAd() {
      if (!adReady) {
        alert('Ad is still loading...');
        return;
      }

      fusetag.que.push(function() {
        fusetag.displayRewarded();
      });
    }

    function updateDisplay() {
      document.getElementById('articles-remaining').textContent = articlesRemaining;

      if (articlesRemaining > 0) {
        document.getElementById('read-article').disabled = false;
        document.getElementById('watch-ad').style.display = 'none';
      }
    }
  </script>
</body>
</html>

Live Example

Best Practices

  1. User Choice: Always make rewarded ads opt-in. Users should explicitly choose to watch an ad for a reward.

  2. Clear Value Proposition: Clearly communicate what reward the user will receive before they watch the ad.

  3. Timing: Offer rewarded ads at logical points where users might want the reward (e.g., when they run out of articles, coins, or lives).

  4. Reward Delivery: Grant the reward immediately after the onRewardedGranted callback fires. Don’t delay or require additional actions.

  5. Re-registration: After a rewarded ad is closed, re-register the ad if you want to allow users to watch another ad later.

  6. Error Handling: Always check if the ad is ready before calling displayRewarded(). Handle cases where ads don’t load.

  7. User Experience:

    • Don’t force users to watch ads
    • Provide alternative ways to earn rewards (e.g., purchases)
    • Respect user choices if they close the ad before completion
  8. Mobile Optimization: Ensure your site has proper viewport settings:

    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    

Requirements and Restrictions

  • User Opt-in: Users must voluntarily choose to watch the ad
  • Mobile Optimized Pages Required: Rewarded ads work on mobile optimized pages
  • Sound: Some rewarded ads may play with sound on. Users are prompted to continue or cancel
  • Confirmation Prompts: If users try to close the ad early, they’re prompted to confirm forfeiture
  • Minimum View Time: Display ads require 5 seconds of viewable time for reward grant
  • Completion: Video ads must complete, or reach skip threshold for TrueView ads
  • Ad Persistence: Rewarded ads persist after completion and must be closed by the user

Event Flow

  1. Callback setup: Register onRewardedReady, onRewardedGranted, and onRewardedClosed. This must happen before step 2 — see Important.
  2. Registration: Call registerRewarded(zoneCode) to load the ad
  3. Ready: onRewardedReady callback fires when ad is available
  4. User Action: User clicks “Watch Ad” or similar button
  5. Display: Call displayRewarded() to show the ad
  6. Viewing: User watches the ad
  7. Reward Grant: onRewardedGranted callback fires after required view time with reward details
  8. Closure: User closes the ad, onRewardedClosed callback fires

Troubleshooting

Ad doesn’t display:

  • Verify the zone is configured with rewarded: true in the admin panel
  • Check that registerRewarded was called before attempting to display
  • Ensure the zone code matches the configuration
  • Verify ad is ready before calling displayRewarded()
  • Check browser console for errors

Reward not granted:

  • User may have closed the ad before the required viewing time
  • Check that onRewardedGranted callback is registered before calling registerRewarded
  • Verify the ad had sufficient viewability (must be in view)
  • For display ads, ensure at least 5 seconds of viewable time

Callback not firing:

  • Ensure all callbacks (onRewardedReady, onRewardedGranted, onRewardedClosed) are registered before calling registerRewarded. If you register the callback after, the ready event may have already fired and your callback will never be invoked.
  • Verify all code is wrapped in fusetag.que.push()
  • Check for JavaScript errors that might prevent callback execution

Multiple rewards granted:

  • Ensure you’re not calling displayRewarded() multiple times
  • Check that you’re properly tracking reward state
  • Consider disabling the “Watch Ad” button after clicking

Server-Side Verification

Note: Server-side verification (SSV) is an app-only feature and is not available for web. For web implementations:

  • Implement client-side reward validation
  • Use fraud detection mechanisms
  • Monitor for suspicious patterns
  • Consider implementing rate limiting
  • Track reward grants server-side for auditing

Reporting and Analytics

You can track rewarded ad performance using Google Ad Manager reports:

  • Platform dimension: Shows breakdown by platform
  • Interaction type dimension: Identifies rewarded requests vs other types
  • Creative technology dimension: Shows video vs display breakdown

Policy Compliance

Publishers using rewarded inventory must comply with Google Ad Manager policies for ad units that offer rewards.

See Also