Flash of Default Content (FODC) Prevention Adapter
The Flash of Default Content (FODC) Prevention Adapter is a lightweight, on-page snippet
that prevents a flash of default content before the Intelligent Handshake runtime completes rendering.
It works alongside the other two Edge SDK components:
- Runtime (tag.js) - hosted decisioning and rendering engine
- FODC Prevention Adapter - on-page render guard
- Page Plan - configuration describing targets and rendering behavior
Mental model:
- The Runtime Tag decides what to render.
- The FODC Prevention Adapter ensures it renders cleanly.
Getting Started
- Add the FODC Prevention Adapter snippet once per page.
- Keep your existing Intelligent Handshake SDK runtime Tag and Page Plan integration.
- Call
IHFODC.MarkTargetsStealth(theIntelligentHandshakePagePlan); after your Page Plan is defined.
- Add
IHFODC.RevealTargets(); to your existing pagePlan.onRender handler.
- Leave your current
ManipulationMode.Start(...) runtime startup logic unchanged.
Overview
The Adapter is designed to be added as a separate on-page layer on top of the standard Intelligent Handshake SDK integration.
It does not replace the runtime Tag and it does not replace the Page Plan.
It performs three jobs:
- Hide target elements before rendering begins
- Reveal the final rendered elements when rendering completes
- Fail open through a visibility-aware failsafe if rendering is delayed or unavailable
When to Use It
Use the FODC Prevention Adapter when your page renders dynamic content into visible page slots and you want to prevent a flash
from default content to personalized content.
It is especially useful when:
- default content is visible before the runtime completes
- the rendered target may appear below the fold
- a smooth reveal is preferred over visible content flicker
Adapter Snippet
Add the following snippet once per page. This is the complete on-page FODC Prevention Adapter.
<!--
IH FODC Prevention v1.1.0
Purpose: Prevent flash of default content before Intelligent Handshake renders.
Safe to include once per page.
-->
<style>
.ih-stealth { opacity: 0; }
@media (prefers-reduced-motion: no-preference) {
.ih-reveal { transition: opacity .18s ease-out; }
}
</style>
<script>
(function (window, document) {
"use strict";
if (window.IHFODC && window.IHFODC.Initialized) return;
var IHFODC = window.IHFODC || {};
IHFODC.Version = "1.1.0";
IHFODC.Initialized = true;
IHFODC.State = { revealed: false, failsafeTimer: null };
IHFODC.Trace = function () {
if (window.intelligenthandshake &&
window.intelligenthandshake.Trace &&
window.intelligenthandshake.Trace.CheckPoint) {
window.intelligenthandshake.Trace.CheckPoint.apply(
window.intelligenthandshake.Trace, arguments
);
}
};
IHFODC.GetTargets = function (ep) {
var out = [], seen = new Set();
if (!ep || !Array.isArray(ep.selectors)) return out;
ep.selectors.forEach(function (sel) {
if (typeof sel !== "string" || !sel.trim()) return;
try {
document.querySelectorAll(sel).forEach(function (el) {
if (!seen.has(el)) { seen.add(el); out.push(el); }
});
} catch (ex) {
IHFODC.Trace("FODC invalid selector", sel, ex);
}
});
return out;
};
IHFODC.MarkTargetsStealth = function (pagePlan) {
if (!pagePlan || !Array.isArray(pagePlan.elementPlans)) return;
pagePlan.elementPlans.forEach(function (ep) {
IHFODC.GetTargets(ep).forEach(function (el) {
el.classList.add("ih-stealth", "ih-reveal");
});
});
};
IHFODC.RevealTargets = function () {
if (IHFODC.State.revealed) return;
IHFODC.State.revealed = true;
if (IHFODC.State.failsafeTimer) {
clearTimeout(IHFODC.State.failsafeTimer);
IHFODC.State.failsafeTimer = null;
}
document.querySelectorAll(".ih-stealth")
.forEach(function (el) { el.classList.remove("ih-stealth"); });
};
IHFODC.GetMM = function () {
return window.intelligenthandshake && window.intelligenthandshake.ManipulationMode
? window.intelligenthandshake.ManipulationMode
: null;
};
IHFODC.SdkIsActive = function () {
var mm = IHFODC.GetMM();
return !!(mm && mm.isActive);
};
IHFODC.SdkHasRendered = function () {
var mm = IHFODC.GetMM();
return !!(mm && mm.manipulationModeCalled);
};
IHFODC.StartFailsafe = function () {
if (IHFODC.State.revealed) return;
var MAX_WAIT = 10000, RETRY_MS = 500, start = Date.now();
var done = false, visibleSeen = false, retry = null, io = null;
function cleanup() {
if (retry) { clearTimeout(retry); retry = null; }
if (io) { io.disconnect(); io = null; }
}
function reveal(reason) {
if (done || IHFODC.State.revealed) return;
done = true;
IHFODC.State.revealed = true;
document.querySelectorAll(".ih-stealth")
.forEach(function (el) { el.classList.remove("ih-stealth"); });
IHFODC.Trace("FODC reveal", reason);
cleanup();
}
function schedule() {
if (done || IHFODC.State.revealed || retry) return;
retry = setTimeout(function () {
retry = null;
check("retry");
}, RETRY_MS);
}
function check(reason) {
if (done || IHFODC.State.revealed) return;
var elapsed = Date.now() - start;
if (IHFODC.SdkIsActive() && !IHFODC.SdkHasRendered()) {
if (elapsed < MAX_WAIT) {
schedule();
return;
}
reveal("timeout_sdk_stalled");
return;
}
if (visibleSeen) {
reveal("visible");
return;
}
if (elapsed < MAX_WAIT) {
schedule();
return;
}
reveal("timeout");
}
var elements = Array.from(document.querySelectorAll(".ih-stealth"));
if (!elements.length) return;
io = new IntersectionObserver(function (entries) {
for (var i = 0; i < entries.length; i++) {
if (entries[i].isIntersecting) {
visibleSeen = true;
check("visible_observer");
break;
}
}
}, { root: null, threshold: 0.01 });
elements.forEach(function (el) { io.observe(el); });
schedule();
};
if (document.readyState === "complete") {
IHFODC.StartFailsafe();
} else {
window.addEventListener("load", function () {
IHFODC.StartFailsafe();
}, { once: true });
}
window.IHFODC = IHFODC;
})(window, document);
</script>
<!-- IH FODC Prevention Adapter v1.1.0 - End -->
Standard Integration Remains Unchanged
Keep the standard Intelligent Handshake SDK integration unchanged:
- Keep your existing runtime
tag.js install
- Keep your existing Page Plan structure
- Keep your existing
ManipulationMode.Start(...) runtime startup logic
The Adapter is an additional on-page layer, not a replacement.
Page Plan Requirements
The Adapter expects targetable element plans to use selectors.
{
selectors: ["#ih-offer-slot"],
fallbackMode: "Replace",
fallbackElementID: "ih_dynamic_offer_default",
segmentMap: [
{
score: "H",
mode: "Replace",
ElementID: "ih_dynamic_offer_high"
}
]
}
The Adapter uses these selectors to determine which visible page elements should be hidden before rendering.
Required Integration Changes
1. Mark targets as stealth
After your existing Page Plan is defined, add:
IHFODC.MarkTargetsStealth(theIntelligentHandshakePagePlan);
2. Reveal targets on render
In your existing onRender handler, add:
IHFODC.RevealTargets();
If you already have custom logic in onRender, keep it and append the reveal call:
onRender: function (pagePlan, score) {
renderOffer(score.segmentCode);
IHFODC.RevealTargets();
}
Example
This example shows the FODC Prevention Adapter added on top of a standard runtime Tag and Page Plan integration.
<div id="ih_dynamic_offer_default" style="display:none;">
Default content
</div>
<div id="ih_dynamic_offer_high" style="display:none;">
High-value content
</div>
<div id="ih-offer-slot"></div>
<script>
var theIntelligentHandshakePagePlan = {
actionKey: "YOUR_ACTION_KEY",
onRender: function (pagePlan, score) {
IHFODC.RevealTargets();
},
elementPlans: [
{
selectors: ["#ih-offer-slot"],
fallbackMode: "Replace",
fallbackElementID: "ih_dynamic_offer_default",
segmentMap: [
{ score: "H", mode: "Replace", ElementID: "ih_dynamic_offer_high" }
]
}
]
};
IHFODC.MarkTargetsStealth(theIntelligentHandshakePagePlan);
</script>
<script src="https://code.intelligenthandshake.com/YOUR_API_KEY/tag.js"></script>
<script>
(function (p) {
(function c(k) {
if (window.intelligenthandshake &&
window.intelligenthandshake.ManipulationMode &&
window.intelligenthandshake.ManipulationMode.Start) {
intelligenthandshake.ManipulationMode.Start(p);
} else if (k < 100) {
setTimeout(function () { c(k + 1); }, 50);
}
})(0);
})(theIntelligentHandshakePagePlan);
</script>
Samples
GlassBox is a set of controlled reference implementations that demonstrate how the
Intelligent Handshake (IH) SDK behaves in real-world rendering scenarios. Each sample isolates a
specific rendering pattern so you can observe, test, and validate how content transitions from
original → optimized → fallback, including how FODC (Flash of Default Content) is handled.
These samples are designed to help you choose the right integration pattern based on your page
structure, performance requirements, and tolerance for visual transitions.
-
GlassBox SDK Sample – Basic
A minimal implementation of the IH SDK with no FODC mitigation. This sample shows the
baseline behavior where original content renders first and is then replaced by optimized
content. Use this to understand default rendering flow and SDK timing.
-
GlassBox SDK Sample – Above The Fold (Basic)
Focuses on above-the-fold content without FODC prevention. This demonstrates the visual
impact of content replacement in highly visible areas. Use this to evaluate whether
FODC mitigation is required for your primary user experience.
-
GlassBox SDK Sample – Above The Fold (With FODC Prevention)
Demonstrates FODC prevention applied to above-the-fold content. Target elements are held
in a controlled “stealth” state until IH rendering completes or a fallback condition is met.
Use this pattern for critical, first-impression UI where visual stability is required.
-
GlassBox SDK Sample – Below The Fold (With FODC Prevention)
Demonstrates FODC prevention for below-the-fold content using visibility detection.
Content is only revealed when it enters the viewport or when fallback conditions trigger.
Use this to optimize performance and user experience for scroll-based content regions.
As a general guideline:
• Use Basic samples to understand core behavior
• Use Above-the-Fold with FODC Prevention for primary conversion surfaces
• Use Below-the-Fold patterns to balance performance and visual consistency
Behavior
- Target elements are hidden immediately through
.ih-stealth
- The runtime Tag renders content based on the Page Plan and score
onRender calls IHFODC.RevealTargets()
- If rendering is delayed, the failsafe waits while the SDK is active
- If rendering stalls, the failsafe reveals on visibility or timeout
Best Practices
- Include the Adapter once per page
- Keep selectors specific and stable
- Always call
IHFODC.RevealTargets() in onRender
- Do not rename the
IHFODC namespace
- Do not remove the failsafe
Troubleshooting
Content never appears
- Confirm
IHFODC.RevealTargets() is called in onRender
- Confirm the selectors match visible target elements
Flicker still occurs
- Confirm
IHFODC.MarkTargetsStealth(...) runs before runtime rendering begins
- Confirm selectors target the correct elements
Failsafe triggers too early
- Confirm the runtime Tag activates normally
- Confirm the Page Plan is valid and rendering completes
- Confirm target elements exist before stealth marking begins
Summary
The Flash of Default Content Prevention Adapter is a non-invasive render guard for the Edge SDK.
It adds a clean reveal experience without changing the standard runtime integration.
Add it once per page, mark your Page Plan targets as stealth, and reveal those targets from your existing
onRender handler.