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 and load a rewarded ad
  2. Receive a callback when the ad is ready
  3. Make the ad visible to the user (user-initiated)
  4. Receive a callback when the reward is granted (after required viewing duration)
  5. Receive a callback when the ad is closed

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

fusetag.registerRewarded(zoneCode)

Registers and loads a rewarded ad for the specified zone code. Call this before you need to display the ad.

Parameters:

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

Example:

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

fusetag.onRewardedReady(callback)

Sets a callback function to be called when the rewarded ad is ready to display.

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.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();
});

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.

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.

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
  });
});

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. Registration: Call registerRewarded(zoneCode) to load the ad
  2. Ready: onRewardedReady callback fires when ad is available
  3. User Action: User clicks “Watch Ad” or similar button
  4. Display: Call displayRewarded() to show the ad
  5. Viewing: User watches the ad
  6. Reward Grant: onRewardedGranted callback fires after required view time with reward details
  7. 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 callbacks are registered before calling registerRewarded
  • 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