by Overwolf
  • Nitro
  • Publishers
    PUBLISHERS
    How it Works Documentation Newsletter
  • Advertisers
    ADVERTISERS
    Advertisers Offering Top Sites
  • Resources
    RESOURCES
    Ad Unit Demos Blog & News Press Releases FAQ Case Studies
  • NitroDex
Log in

Ad Publishers

  • Helpful Integration Tools and Common Issues
  • Google MCM – What is it?
  • Installing the ad script on your page
  • Setting up your ads.txt file
  • Creating an ad placement
  • Special Ad Formats
  • Detecting ad-blocking users
  • Creating a Playlist and Adding Content

Data and Privacy

  • Passing Hashed Emails
  • Creating a link for the user to manage their consents
  • US Privacy law compliance steps
  • Support for Google Analytics and Consent Mode
  • Adding custom consents or disclosures

Dashboard and Best Practices

  • Ad Layout Best Practices
  • Nitro Glossary
  • NitroPay
  • Docs
  • Electron Apps and NitroPay

Electron Apps and NitroPay

These instructions are provided as-is. Refer to the Electron docs for development help beyond this article. This sample app is also available at github.com/ggsoftwarellc/nitropay-electron-example

Before implementation please ensure that all createAd calls within the app have the following configuration option enabled and set to include ‘google’ as a value. Click here

Once you have the app live we require a period of review. To submit for review and for more information regarding working with Overwolf on your app, please contact us via Intercom! (that’s the green bubble in the bottom right hand corner)

ad-sample.html #

Ads must be created and embedded from a domain name that is approved for ad serving on NitroPay. The following file is an example of a standalone page that embeds 2x 300×250 ads. Please ensure you edit the script to point to your site ID, and you keep data-cmp-mode=”5″ on the script embed.

<!DOCTYPE html>
<html style="width: 100%">
    <head>
        <script data-cfasync="false">
            window.nitroAds = window.nitroAds || {
                createAd: function () {
                    return new Promise((e) => {
                        window.nitroAds.queue.push(['createAd', arguments, e]);
                    });
                },
                addUserToken: function () {
                    window.nitroAds.queue.push(['addUserToken', arguments]);
                },
                queue: [],
            };
        </script>
        <script data-cfasync="false" data-cmp-mode="5" async src="https://s.nitropay.com/ads-####.js"></script>
        <script data-cfasync="false" async src="https://consent.nitrocnct.com/loader.js"></script>
    </head>

    <body style="width: 100%; margin: 0">
        <div style="width: 300px">
            <div id="banner-1" style="display: block"></div>

            <script type="text/javascript">
                window.nitroAds.createAd('banner-1', {
                    sizes: [[300, 250]],
                    demo: true,
                    report: {
                        enabled: true,
                        position: 'bottom-right',
                        wording: 'Report Ad',
                    },
                    skipBidders: [],
                });
            </script>

            <br /><br />

            <div id="banner-2" style="display: block"></div>
            <script type="text/javascript">
                window.nitroAds.createAd('banner-2', {
                    sizes: [[300, 250]],
                    demo: true,
                    report: {
                        enabled: true,
                        position: 'bottom-right',
                        wording: 'Report Ad',
                    },
                    skipBidders: [],
                });
            </script>
        </div>
    </body>
</html>

cmp.html #

The following file must be remotely hosted on a domain that is approved for ad serving on NitroPay. It must be on the same domain as all of the ad embeds (such as ad-sample.html above).

<!DOCTYPE html>
<html style="width: 100%">
    <head>
        <script type="text/javascript">
            window.__npcmp_display_mode = 'app';
        </script>
        <script data-cfasync="false" async src="https://consent.nitrocnct.com/loader.js"></script>
    </head>

    <body style="width: 100%; margin: 0">
        <script>
            const urlParams = new URLSearchParams(window.location.search);
            const resurface = urlParams.get('resurface');

            function callback(tcData) {
                if (tcData?.eventStatus == 'useractioncomplete') {
                    window.close();
                }
            }

            function test() {
                if (window.__cmp) {
                    if (resurface) {
                        window.__cmp('showModal');
                    } else {
                        window.__cmp('showConsentTool');
                    }

                    window.__tcfapi('addEventListener', 2, callback);
                    return;
                } else if (typeof window['__npcmp_gdpr'] !== 'undefined' && !window['__npcmp_gdpr']) {
                    window.close();
                    return;
                }
                setTimeout(test, 100);
            }

            if (!resurface) {
                window.__tcfapi_queue = [['addEventListener', 2, callback]];
            }

            test();
        </script>
    </body>
</html>

main.js #

This example code creates a 1600×900 electron window, launches a the CMP and creates an ad. Update the relevant URLs.

const { app, BrowserWindow, BrowserView } = require('electron');
const path = require('node:path');

app.whenReady().then(() => {
    // Sample base window
    const parent = new BrowserWindow({
        width: 1600,
        height: 900
    });
    parent.loadFile('index.html');


    // URL to the ad embed
    const adURL = 'https://yoursite.com/app/ad-sample.html';

    // URL to your cmp.html
    const cmpURL = 'https://yoursite.com/app/cmp.html';

    // Your front page
    const referrer = 'https://yoursite.com/';

    // ## Create an ad window ##
    const ad = new BrowserView({
        webPreferences: {
            partition: 'persist:adpartition',
        },
    });

    // Remove app name and electron from user-agent
    const re = new RegExp(`(${app.getName()}|Electron)/[\\d\\.]+ `, 'g');
    ad.webContents.setUserAgent(ad.webContents.getUserAgent().replace(re, ''));

    // Position ad to the right side (example)
    // Width is set larger than viewable area to avoid being treated as mobile device by ads
    let bounds = parent.getBounds();
    ad.setBounds({ x: bounds.width - 325, y: 10, width: 1280, height: 600 });
    parent.on('resize', function () {
        bounds = parent.getBounds();
        ad.setBounds({ x: bounds.width - 325, y: 10, width: 1280, height: 600 });
    });

    parent.setBrowserView(ad);

    // ## Load the CMP ##
    
    const createCMP = () => {
        return new BrowserWindow({
            width: 1120,
            height: 600,
            center: true,
            closable: false,
            skipTaskbar: true,
            modal: true,
            titleBarStyle: 'hidden',
            transparent: true,
            hasShadow: false,
            frame: false,
            moveable: false,
            fullscreen: false,
            webPreferences: {
                partition: 'persist:adpartition',
            },
            parent,
        })
    }

    const cmp = createCMP();

    // Safe to show ads once the CMP window is closed
    cmp.on('closed', () => {
        ad.webContents.loadURL(adURL, {
            httpReferrer: referrer,
        });
    });
    
    cmp.loadURL(cmpURL);
});

These examples should produce the following CMP view when compiled in Electron. Clicking “Accept” on the CMP will then load the sample ads.

GDPR and resurfacing the CMP UI #

Our example leverages the geo data exposed by NitroPay to determine if the user is in a country where a CMP needs to be shown. It is the publisher’s responsibility to create a way to resurface the CMP UI so that a user can change their consent.

An example of how this could be done is by using Electron’s event emitters. Within your app’s local files you could create a button like:

<button id="resurface">Update my consent preferences</button>

<script type="text/javascript">
    const btn = document.getElementById('resurface');
    btn.addEventListener('click', async function() {
        await window.cmp.resurface();
    });
</script>

Create the supporting function in your preload script

const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('cmp', {
  resurface: () => ipcRenderer.invoke('resurface')
})

Ensure the main window is using that preload script

const parent = new BrowserWindow({
    width: 1600,
    height: 900,
    webPreferences: {
        preload: path.join(__dirname, 'preload.js'),
    }
});

Create the listener that actually resurfaces the UI in your main.js. Logic for CMP resurfacing exists in the cmp.html example above.

// Handles resurfacing the CMP
ipcMain.handle('resurface', () => {
    const cmp = createCMP();
    cmp.loadURL(cmpURL + '?resurface=1');
});

The consent button will be visible to all users unless your app supplies a check for whether the user is in a GDPR country before rendering it. If a user in a non-GDPR country sees and clicks the button, nothing will appear to happen.

What are your Feelings
Share This Article :
  • Facebook
  • Twitter
  • LinkedIn
  • Pinterest
Updated on December 4, 2025
Table of Contents
  • ad-sample.html
  • cmp.html
  • main.js
  • GDPR and resurfacing the CMP UI
We use cookies to improve your experience and increase the relevancy of content when using Nitro. Our cookies are used for analytics, optimization, and advertising operations. Learn more.Got it
  • Publishers

    • How it works
    • Documentation
    • Newsletter
  • Advertisers

    • Advertisers Offering
    • Top Sites
  • Resources

    • Ad Unit Demos
    • Blog & News
    • Press Releases
    • FAQ
    • Case Studies
  • Companions

    • Overwolf
    • CurseForge
    • Tebex
  • Nitrodex

© Overwolf. All rights reserved.
  • Terms of Service
  • Privacy Policy