How Ads Work
Before writing any code, it helps to know four things about how Overlayed serves ads:- Ad inventory is arranged with the Overlayed team first. Ad units, their base selectors (like
htlad-medrec), and where they may be positioned are agreed on before you integrate. Reach out early - the ads have to be set up on Overlayed’s side before your code can request them. - Setup spans all three Electron layers. The main process registers each ad-enabled window
(
overlay.ads.registerWindow), the preload script imports@overlayed/app/preload, and the render process uses the@overlayed/adspackage to initialize, mount the ads script, and request fills. - Ads render into plain
<div>elements in your DOM. You place the containers in your layout and explicitly request fills for them withrefreshAdsViaDivMappings- nothing renders until you ask. - Calls queue until the ads script loads.
init,setPageTargeting, andrefreshAdsViaDivMappingsare safe to call before the script has finished loading; commands are queued and drained once the ad provider is ready.
Wiring Up Ads
Coordinate with the Overlayed team
Install the ads package
@overlayed/ads to your app. It’s a separate package from @overlayed/app and runs in your render
process.Register ad-enabled windows (main process)
overlay.ads.registerWindow after creating it:Import the preload script
init() fails with
“could not find overlayed instance”.Initialize and mount the ads script (render process)
init() sets the app_id page targeting for you and is safe to call more than once. The onError handler is
intentionally a required parameter - script load failure is the failure mode you most want visibility into.Add an ad container and request a fill
<div> with an id that uniquely identifies the slot and a class matching one of your
approved base selectors:class attribute has no leading dot (htlad-medrec), while baseDivId is a selector and
does (.htlad-medrec). That’s it - once the script loads and the fill request resolves, the ad renders inside
your container.Refreshing on Navigation
refreshAdsViaDivMappings is not fire-and-forget for the lifetime of the app - call it on initial mount and again
whenever the page context changes, such as a route navigation in a single-page app. Pass targeting so the ad request
reflects the new context:
setPageTargeting applies to every subsequent request; per-mapping targeting is merged on
top for individual slots. See Configuration for the full breakdown.
Supporting Ad-Free Users
There is no runtime method to toggle ads on and off. To hide ads for a user - a paid subscriber, for example - gate the integration at its two entry points in the render process:FAQ
How do I know the ads script actually loaded?
How do I know the ads script actually loaded?
[Overlayed] Ads script loaded successfully. to the console. On failure, your
onError callback fires and a console error is logged with the script URL. Treat onError as a real
observability hook, not a formality - if the script never loads, every ad slot stays empty.Can I call refreshAdsViaDivMappings before the script finishes loading?
Can I call refreshAdsViaDivMappings before the script finishes loading?
init, setPageTargeting, and refreshAdsViaDivMappings all push commands onto a queue that the ad
provider drains once it’s ready. You don’t need to sequence your calls against the script’s onload.Can I show multiple ads on one page?
Can I show multiple ads on one page?
refreshAdsViaDivMappings takes an array - pass one mapping per container, each with a unique divId.
Which units and how many placements you can run is part of what you agree on with the Overlayed team.Do ads work in both in-game and out-of-game windows?
Do ads work in both in-game and out-of-game windows?
BrowserWindow or RenderWindow can show ads, as long as you called
overlay.ads.registerWindow for it in the main process and its page runs the render-side setup.Does the package expose ad lifecycle events like impressions or clicks?
Does the package expose ad lifecycle events like impressions or clicks?
@overlayed/ads API surface is init, refreshAdsViaDivMappings, setPageTargeting,
getAdsScriptElement, and getAdsScriptUrl - there are no per-ad callbacks for impressions, clicks, or
no-fills. The only failure signal you can hook is the script-load onError.init() logs "could not find overlayed instance" - what's wrong?
init() logs "could not find overlayed instance" - what's wrong?
import "@overlayed/app/preload"; and that the window was created through
overlay.windows.createWindow or overlay.windows.createInGameWindow.Can I put a user ID in targeting to improve ad relevance?
Can I put a user ID in targeting to improve ad relevance?
page_id.What decides which ad sizes and units I can use?
What decides which ad sizes and units I can use?
Where does the ads script URL come from?
Where does the ads script URL come from?
getAdsScriptElement handles this for you; if you need the raw URL - for a CSP allowlist, for example - call
getAdsScriptUrl().
