Skip to main content
Site → Settings → Global JS. Publish-gated (needs the Global JS permission on this site, which requires Publish).
Settings: Global JS

Global JS panel. One editor, byte counter, publish-gated.

What it is

A single JavaScript block that runs once per page per visitor, before any variant’s code. Useful for:
  • Shared helpers. A waitFor polyfill, a debounce utility, a branded logger. Instead of copying the same function into every variant, put it here.
  • One-time analytics wiring. A GA4 configure call, a Segment identify, something your variants can then use without repeating.
  • Feature flags read from your own system. Cache your feature flag values into a global so your variant JS can read them synchronously.

When it runs

  1. Consent gate has passed (see Consent).
  2. Visitor is not opted out (see Opt-out).
  3. Global JS runs. Once per page. Wrapped in a try / catch.
  4. The rest of the runtime decides variants and applies them.
Because it runs before any variant, code in Global JS can define utilities that variant code then uses.

Once per page per site

window.__abtestlyGlobalJsRan[siteId] is set on first run. A second call, for example on a SPA route change, is a no-op. The block runs once and stays. That is deliberate: shared helpers are almost always things you want to define once. Anything that needs to fire on route change belongs in SPA panel, not here.

Size cap

50 KiB UTF-8. The editor counts bytes and refuses to save over the cap. Almost every real Global JS is well under this, even a large utility library gzip-inlined into base64 has room.

Errors

Errors thrown inside Global JS are caught, logged to the browser console with a prefixed message, and reported to ABTestly via the /err beacon (first-occurrence-per-session, deduped). An error in Global JS does not stop variant JS from running. It does mean whatever your Global JS was supposed to provide is not available to variants; if variants blindly assume it worked, they will throw too. Wrap risky code in try/catch inside Global JS and fall back gracefully.

Example

Variants can then:

What Global JS is not for

  • Variant code. If it belongs to a specific experiment, put it in the variant. Global JS is site-wide, always-on. A “test” living in Global JS is not a test.
  • Anything with heavy DOM manipulation. DOM changes belong in variants where they can be scoped and cleaned up on SPA route change.
  • Third-party script loading. Load third parties from your own <script> tags in <head> or from a tag manager. Adding them through Global JS makes it hard to reason about their load order relative to the rest of the page.

Redacted from the audit log

The full text of Global JS is redacted in the activity log. Only the event of the change and who made it is visible; the actual code is not. This is because Global JS commonly contains site-specific keys or identifiers you would not want in an audit-log export.