Docs > Quick Start Guide
Publisher tutorial
This part of the tutorial is aimed at website owners and publishers who want to implement High Impact JS on their site(s).
Step 1: Add High Impact JS to your site
There are three ways to consume the library. They all expose the same API — pick the one that fits how your site is built.
| Method | Best for | Build step |
|---|---|---|
| npm package | Sites with a bundler (Vite, webpack, Rollup) or a framework (React, Vue, etc.) | Yes |
| Self-hosted from your own domain | AdOps/publishers who want full control and no third-party request | No |
| jsDelivr CDN | The fastest, lowest-code way to get started | No |
Option A — npm package
Install the package with your package manager of choice:
$ npm i highimpact.js$ pnpm add highimpact.js$ yarn add highimpact.js$ bun i highimpact.jsThen import it where you need it:
import { Advantage } from "highimpact.js";With the npm package you call the API directly on the imported Advantage instance — you don't need the window.highImpactJs command queue described below.
Option B — Self-hosted from your own domain
If you'd rather not depend on a third-party CDN, serve the bundle from your own domain. Grab dist/bundles/advantage.umd.cjs from the npm package (or build it from source), upload it to your server, and load it with a <script> tag:
<script src="https://www.your-domain.com/scripts/advantage.umd.cjs"></script>Option C — jsDelivr CDN
The quickest, no-build option — perfect for AdOps and low-code integrations. Add this <script> tag to your page:
<script src="https://cdn.jsdelivr.net/npm/highimpact.js/dist/bundles/advantage.umd.cjs"></script>Tip: Pin a specific version for production so a new release can't change behaviour unexpectedly, e.g. highimpact.js@0.11.1.
Using the command queue (script-tag methods)
When you load the library with a <script> tag (Option B or C), use the global command queue to call the API. The command queue (window.highImpactJs.cmd) lets you queue API calls before the library has finished loading; queued commands run automatically once it's ready.
<script>
window.highImpactJs = window.highImpactJs || { cmd: [] };
window.highImpactJs.cmd.push(function () {
// High Impact JS is ready — call the API here
});
</script>Define this window.highImpactJs object before your <script src=...> tag so commands queued early aren't lost.
Step 2: Define your ad slots
Use defineSlot to register each ad placement that should support high-impact formats. The library will automatically find the matching DOM element, wrap it, detect when an ad renders, and activate the format.
<script>
window.highImpactJs = window.highImpactJs || { cmd: [] };
window.highImpactJs.cmd.push(function () {
highImpactJs.defineSlot({
adUnitId: "/1234/topscroll-ad",
template: "topscroll",
sizes: [
[970, 250],
[1920, 1080]
]
});
});
</script>SlotConfig properties
| Property | Type | Required | Description |
|---|---|---|---|
adUnitId | string | Yes | The ad unit ID (e.g., a GAM slot element ID). |
template | string | No | "topscroll", "midscroll", or "double-fullscreen". |
targetId | string | No | Xandr target ID. Use instead of adUnitId for Xandr. |
sizes | number[][] | No | Accepted creative sizes, e.g. [[970, 250]]. Format only activates when the rendered ad matches. |
waitForAdSignal | boolean | No | Wait for the creative to send a post-message signal before activating. Default: false. |
Step 3: Integrate formats with your site
High-impact formats take over parts of the page layout (e.g., a topscroll pushes content down, a midscroll goes full-width). Almost every website needs some adjustments to make this work smoothly — hiding a sticky header, resetting padding, expanding a container to full viewport width, etc.
You configure this with formatIntegrations. For each format you provide a setup function (called when the format activates) and optional close / reset functions (called when the user dismisses the ad or when the format is reset).
import {
Advantage,
AdvantageFormatName,
IAdvantageWrapper
} from "highimpact.js";
const advantage = Advantage.getInstance();
advantage.configure({
formatIntegrations: [
{
format: AdvantageFormatName.TopScroll,
options: {
closeButtonText: "Ad",
closeButtonAnimationDuration: 0
},
setup: (wrapper: IAdvantageWrapper, ad?: HTMLElement) => {
return new Promise<void>((resolve) => {
// Push the page content down to make room for the topscroll
const main = document.querySelector("main") as HTMLElement;
(main.parentElement as HTMLElement).style.paddingTop =
"80svh";
wrapper.style.top = "0";
wrapper.style.position = "absolute";
resolve();
});
},
close: (wrapper: IAdvantageWrapper, ad?: HTMLElement) => {
// Undo the layout changes when the ad is closed
const main = document.querySelector("main") as HTMLElement;
(main.parentElement as HTMLElement).style.paddingTop = "";
wrapper.style.top = "";
},
reset: (wrapper: IAdvantageWrapper, ad?: HTMLElement) => {
// Same cleanup when the format is reset
const main = document.querySelector("main") as HTMLElement;
(main.parentElement as HTMLElement).style.paddingTop = "";
wrapper.style.top = "";
}
},
{
format: AdvantageFormatName.Midscroll,
setup: (wrapper: IAdvantageWrapper, ad?: HTMLElement) => {
return new Promise<void>((resolve) => {
// Remove margins so the ad stretches to full viewport width
const container = ad?.parentElement
?.parentElement as HTMLElement;
if (container) {
container.style.margin = "0";
container.style.borderWidth = "0";
}
// Compensate if the wrapper isn't flush with the left edge
const rect = wrapper.getBoundingClientRect();
if (rect.left > 0) {
wrapper.style.marginLeft = `-${rect.left}px`;
}
resolve();
});
},
reset: (wrapper: IAdvantageWrapper, ad?: HTMLElement) => {
// Restore original styles
const container = ad?.parentElement
?.parentElement as HTMLElement;
if (container) {
container.style.margin = "";
container.style.borderWidth = "";
}
wrapper.style.marginLeft = "";
}
}
]
});FormatIntegration properties
| Property | Type | Required | Description |
|---|---|---|---|
format | AdvantageFormatName | string | Yes | Which format this integration applies to. |
options | object | No | Format-specific options (e.g., closeButtonText, autoCloseDuration, logo). Varies by format. |
setup | (wrapper: IAdvantageWrapper, ad?: HTMLElement) => Promise<void> | Yes | Called when the format is about to activate. Make your layout adjustments here, then call resolve(). |
close | (wrapper: IAdvantageWrapper, ad?: HTMLElement) => void | No | Called when the user dismisses the ad (e.g., clicks the close button). Undo your layout changes here. |
reset | (wrapper: IAdvantageWrapper, ad?: HTMLElement) => void | No | Called when the format is reset (e.g., a new ad loads into the same slot). Undo your layout changes here. |
Tip: If your close and reset handlers do the same thing, extract the cleanup into a shared function to avoid duplication.
Step 4: Lifecycle Events
The library dispatches lifecycle events that bubble up through the DOM. Use them to react to format changes on your page (e.g., pause a video player, adjust analytics, hide sticky elements).
| Event | When | event.detail |
|---|---|---|
advantage:format-start | Format has been activated | { format, wrapper, iframe } |
advantage:format-close | User closed the format (e.g., × button) | { format, wrapper, iframe } |
advantage:format-reset | Format was reset (e.g., new ad loaded) | { format, wrapper, iframe } |
document.addEventListener("advantage:format-start", (e) => {
console.log("Format activated:", e.detail.format);
// e.g. hide a sticky header
});
document.addEventListener("advantage:format-close", (e) => {
console.log("Format closed:", e.detail.format);
// e.g. restore the sticky header
});Success!
Congratulations! Your website is now set up for high-impact ad formats!
Full Example
A complete publisher-side setup:
<script>
window.highImpactJs = window.highImpactJs || { cmd: [] };
window.highImpactJs.cmd.push(function () {
// Global settings
highImpactJs.setConfig({
plugins: ["gam"]
});
// Template settings
highImpactJs.setTemplateConfig("topscroll", {
peekAmount: "80vh"
});
// Define slots
highImpactJs.defineSlot({
adUnitId: "/1234/topscroll-ad",
template: "topscroll",
sizes: [
[970, 250],
[1920, 1080]
],
waitForAdSignal: true
});
highImpactJs.defineSlot({
adUnitId: "/1234/midscroll-ad",
template: "midscroll",
sizes: [
[1080, 1920]
],
});
});
</script>
<script src="https://cdn.jsdelivr.net/npm/highimpact.js/dist/bundles/advantage.umd.cjs"></script>The library will:
- Find the DOM elements matching each ad unit ID
- Wrap them with
<advantage-wrapper>elements configured for the right format - Listen for the GAM
slotRenderEndedevent - Wait for the creative's post-message signal (when
waitForAdSignal: true) - Activate the format once all conditions are met
For the full Slot API reference (all properties, getter functions, post-message signals, etc.), see the Slot API Reference.