Writing organisation scripts

Write and test Global organisation scripts that run in OmniLab Pages without disrupting the participant experience.

This guide is the developer companion to the admin script configuration article. Use it when you are writing or reviewing the JavaScript that runs in OmniLab Pages.

Where the script runs

Organisation scripts run in the consumer-facing OmniLab Pages runtime, not inside OmniLab Studio. Before active scripts run, OmniLab initialises window.omnilab and can expose both group data and basic contact data to the page.

Values commonly available to organisation scripts
window.omnilab?.contact?.externalId
window.omnilab?.contact?.email
window.omnilab?.group
window.omnilab?.group?.configuration?.variables
window.omnilab?.group?.uniqueKey
window.location.pathname

Contact values are available only when the participant is already known in that flow.

Your code must contain real script tags

OmniLab expects the script code field to contain one or more valid <script>...</script> blocks. Inline scripts and external script loaders are both supported.

Inline script example
<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  event: "omnilab_view",
  organisation_key: window.omnilab?.group?.uniqueKey,
  page: window.location.pathname,
});
</script>
External script example
<script async src="https://www.googletagmanager.com/gtm.js?id=GTM-AB12C3D"></script>

Context and trigger behavior

SettingWhat it means
ALLRun in both iframe and non-iframe OmniLab Pages
IFRAME_ONLYRun only when OmniLab is embedded
NON_IFRAME_ONLYRun only when OmniLab Pages is standalone
VISITLoad during the normal page visit
REGISTRATIONHold the script for the registration stage

If the current trigger is REGISTRATION, OmniLab still keeps the other active scripts available and adds the registration-targeted scripts for that stage. In practice, use a separate REGISTRATION script for conversion events instead of overloading the base page-view script.

Safe use cases

  • Analytics loaders such as GTM, a pixel base tag, or a dataLayer bootstrap
  • Per-organisation behaviour based on window.omnilab.group.configuration.variables
  • Lightweight event pushes on visit or registration
  • Minor DOM enhancements that do not depend on fragile selectors or block interaction
Page-view script using organisation variables
<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  event: "omnilab_view",
  organisation_key: window.omnilab?.group?.uniqueKey,
  country: window.omnilab?.group?.configuration?.variables?.country,
  locale: window.omnilab?.group?.configuration?.variables?.locale || "en_US",
  page: window.location.pathname,
  surface: "OmniLab Pages",
});
</script>
Registration-only conversion event
<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  event: "registration_complete",
  external_id: window.omnilab?.contact?.externalId,
  email: window.omnilab?.contact?.email,
  organisation_key: window.omnilab?.group?.uniqueKey,
});
</script>

What to avoid

  • Replacing or overriding OmniLab business logic
  • Blocking synchronous work that delays page load or prevents participation
  • Fragile DOM rewrites that depend on unstable class names or layout details
  • Collecting extra personal data without a clear legal basis and review
  • Large client-side libraries that are not essential to the participant journey

A broken script can break every embedded experience

Because these scripts execute in OmniLab Pages, one bad script can affect live campaigns. Keep them small, test them in staging, and give admins a rollback plan before production.

Local testing workflow

  1. Build and review the script in a staging environment.
  2. Test both iframe and non-iframe delivery if the script depends on the container.
  3. If the trigger is REGISTRATION, complete a full registration flow and inspect the browser console and network panel.
  4. After admins save the script, publish the affected campaign again before you validate the live experience.

Handoff to admins

When you hand a script to an admin, provide:

  • the script name
  • the intended context (ALL, IFRAME_ONLY, or NON_IFRAME_ONLY)
  • the intended trigger (VISIT or REGISTRATION)
  • whether the script should start active or inactive
  • a rollback instruction and a staging test result

Complete example scripts

Google Tag Manager base loader

Use this when your team wants GTM available before firing additional events.

Google Tag Manager loader
<script>
(function (w, d, s, l, i) {
  w[l] = w[l] || [];
  w[l].push({
    'gtm.start': new Date().getTime(),
    event: 'gtm.js',
  });
  var f = d.getElementsByTagName(s)[0],
    j = d.createElement(s),
    dl = l != 'dataLayer' ? '&l=' + l : '';
  j.async = true;
  j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
  f.parentNode.insertBefore(j, f);
})(window, document, 'script', 'dataLayer', 'GTM-AB12C3D');
</script>

Page-view event with organisation variables

Page-view dataLayer push
<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  event: 'view_page',
  country: window.omnilab?.group?.configuration?.variables?.country,
  region: window.omnilab?.group?.configuration?.variables?.region,
  language:
    window.omnilab?.group?.configuration?.variables?.centerLanguage || 'English',
  locale:
    window.omnilab?.group?.configuration?.variables?.locale || 'en_US',
  page: window.location.pathname,
  page_type: 'Experience',
  organisation_key: window.omnilab?.group?.uniqueKey?.toUpperCase(),
  surface: 'OmniLab Pages',
});
</script>

Registration event with dataLayer.push

Use this when you want to emit a conversion-style event after registration.

Registration dataLayer push
<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
  event: 'registration_complete',
  organisation_key: window.omnilab?.group?.uniqueKey?.toUpperCase(),
  country: window.omnilab?.group?.configuration?.variables?.country,
  locale:
    window.omnilab?.group?.configuration?.variables?.locale || 'en_US',
  page: window.location.pathname,
  registration_status: 'complete',
});
</script>

Meta Pixel registration trigger

Use this pattern when the base Meta Pixel is already present and you only need to fire an event from OmniLab Pages.

Meta Pixel registration event
<script>
if (typeof window.fbq === 'function') {
  window.fbq('track', 'CompleteRegistration', {
    organisation_key: window.omnilab?.group?.uniqueKey,
    country: window.omnilab?.group?.configuration?.variables?.country,
    locale:
      window.omnilab?.group?.configuration?.variables?.locale || 'en_US',
    page: window.location.pathname,
  });
}
</script>

Available organisation variable paths

What you want to readVariable pathExample result
Countrywindow.omnilab?.group?.configuration?.variables?.countryFrance
Local language overridewindow.omnilab?.group?.configuration?.variables?.centerLanguageFrench
Locale codewindow.omnilab?.group?.configuration?.variables?.localefr_FR
Regionwindow.omnilab?.group?.configuration?.variables?.regionEurope
Organisation keywindow.omnilab?.group?.uniqueKeyparis-centre
Current page pathwindow.location.pathname/summer-experience

Add a fallback when you need one, for example centerLanguage || 'English' or locale || 'en_US'.

Keep analytics payloads generic

Prefer organisation, locale, page, and event context unless your measurement design truly requires more. If a destination expects transformed or filtered values, apply that logic inside your script before pushing it.

Was this helpful?

Optional comments help us improve this page for future authors and readers.

On this page