How Loading Works

The sequence from page load to applied variants — install script, edge fetch, and anti-flicker

Guide~4 min read

Copy this guide and your current settings as a prompt for your AI agent.

Preview agent promptSee the guide, code and settings included when you copy.

The Coframe SDK reaches your visitors through a three-part sequence: an install script in your page’s <head> sets up the queue and hides the page, the SDK script is fetched from the edge (arriving with project data already baked in), and the page is revealed once variants are applied or a timeout elapses.

Watch: 54s — the install script, the single edge round trip, and the reveal — step by step
On this page
  1. 01The install script
  2. 02Fetching from the edge
  3. 03Anti-flicker during load
  4. 04Related

01The install script

The install script is a small, synchronous IIFE placed in the <head> of each page. It runs before the browser paints content and does the following in order:

  1. Disable guard — if ?cf_disable (or ?cf_disabled) appears anywhere in the query string, the script logs a warning and exits immediately. Nothing loads.

  2. Duplicate guard — if an element with the id coframe-sdk-js already exists in the DOM, the script exits. This prevents the SDK from being installed twice on the same page.

  3. Config object — builds a configuration object containing at minimum projectId, currentUrl (the current page URL), startTime (the current timestamp, used for performance tracking), and timeoutMs: 1000.

  4. Queue setup — initialises window.CFQ and pushes the config: (window.CFQ = window.CFQ || []).push({ config }). The SDK reads this command from the queue when it loads.

  5. Anti-flicker — hides the page body and arms a fallback reveal timer (see Anti-flicker during load below).

  6. SDK script injection — creates an async <script> pointing to https://edge.cofra.me/cf.js with the config serialized into the config query parameter. An onerror handler calls show() so the page is never permanently hidden if the request fails.

The config query parameter is a JSON-encoded, URL-encoded configuration object. The edge requires it to contain both projectId and currentUrl — the install script populates both automatically.

For the full install snippet and placement guidance, see JavaScript installation.

02Fetching from the edge

When the browser fetches https://edge.cofra.me/cf.js?config=..., the edge worker parses the config parameter, loads project data (experiments, variants, personalization rules) for the identified project, selects the appropriate SDK bundle based on the browser’s User-Agent, and returns a single JavaScript response containing both:

  1. A window.CFQ.push({ projectData: ... }) call with the project data — the filtered experiment configuration and personalization headers — baked directly into the script.
  2. The full compiled SDK bundle, appended immediately after.

Because the project data and the SDK bundle arrive together in one HTTP response, the SDK does not need a separate network round-trip to fetch its configuration after it loads. The projectData push is already waiting in the queue before the first line of SDK code executes.

For details on how the edge handles SDK delivery and versioning, see Delivery and versioning.

03Anti-flicker during load

When Coframe applies a variant to a page element, there is a window between the browser’s first paint and when the SDK finishes applying changes. Without protection, visitors can briefly see the original content before it is replaced — a flash of original content.

The install script addresses this synchronously, before the browser’s first paint, using a CSS variable to hide the body:

JS
const style = document.createElement('style');
style.id = 'coframe-antiflicker';
style.textContent =
  ':root { --cf-show: 0;}' +
  'body { opacity: var(--cf-show) !important; transition: opacity 0.2s ease; }'

function hide() { document.head.appendChild(style); }
function show() {
  document.documentElement.style.setProperty('--cf-show', '1');
  style.parentNode && style.parentNode.removeChild(style);
}
hide(); setTimeout(show, config.timeoutMs);

The body is hidden by setting --cf-show: 0. A fallback timer calls show() after config.timeoutMs — the generated install script ships timeoutMs: 1000, so the page is always revealed within 1000 ms even if the SDK has not finished applying changes. When the SDK finishes applying variants it calls show() earlier, and the onerror handler on the injected <script> also calls show() directly if the edge request fails. The page is never permanently stuck in a hidden state.

Because anti-flicker must guarantee the body is hidden before the browser’s first paint, the install script cannot be loaded asynchronously. Loading it through an async tag manager (such as Google Tag Manager) means the browser may paint original content before the snippet runs, defeating the protection.

For the full hide/reveal explanation and timeout configuration, see Anti-flicker. To adjust timeoutMs and other runtime settings, see Config reference.

04Related

Related reading

Content and video lessons from Coframe documentation. Code examples are not executed on this page.

BACK TOHow Coframe Works

Documentation

Open Coframe App

Search documentation

Search all guides and references↑ ↓ Navigate · Esc Close