Back to all integrations
API

Custom Code and Script Embeds

Adding tracking, third-party widgets and custom behavior to AppBO funnels and sites without breaking the page.

On this page
What it connectsHow to connect itWhat data movesWorked exampleLimits and gotchas
Need this wired up?

Bring your stack to a call and we will connect it, test every field in both directions, and hand it over documented.

Book a call
01

What it connects

A script embed connects a page built in AppBO to code that runs in the visitor's browser. On one side is the funnel step, site page, form or survey as the builder renders it. On the other is whatever the script talks to: an analytics collector, a tag manager, a chat widget, a scheduling embed, a review widget, a consent manager, or a few lines of your own JavaScript that adjust behavior the builder does not expose.

You reach for this when the thing you need lives in the page rather than in the data. Attribution is the common case. A pixel has to fire in the browser, on the real page, at the right moment, or the campaign has no measurable outcome. Third-party widgets are the second case: a vendor gives you a snippet and the page is the only place it can go. The third is genuine behavioral tweaks: conditionally hiding a field, pre-filling from a query string, adjusting a label, adding a validation rule.

It is also the riskiest integration in this library, because it runs with the full privileges of the page. A badly behaved third-party script can block rendering, break a form submission, leak personal data to a vendor nobody approved, or quietly stop working after a platform update. The discipline that makes it safe is boring and non-negotiable: know what each script does, load it in the right place, scope your selectors, and verify in the browser rather than trusting that it saved without error.

02

How to connect it

  1. Establish what the script actually does before it goes anywhere near a page. Read it, or at minimum know the vendor, what it collects, what domains it calls and whether it sets cookies. A snippet pasted from a ticket is an unreviewed dependency.
  2. Check the privacy consequences first, not last. If the script sends visitor data to a third party, confirm it is covered by your privacy notice and your consent mechanism, particularly on any page handling health, financial or otherwise sensitive information, where the right answer is often not to embed it at all.
  3. Decide the scope. The platform offers page-level or step-level custom code and a broader site or account-level tracking code area; use the narrowest scope that achieves the goal. A tracking script that only matters on one funnel step does not belong account-wide.
  4. Choose head or body deliberately. Consent managers and tag managers generally need to be in the head and early. Everything else is safer at the end of the body, where it cannot delay rendering.
  5. Load third-party scripts asynchronously. Add async or defer unless the vendor explicitly requires synchronous execution, and know that a synchronous third-party script makes your page as slow as their worst day.
  6. Prefer one tag manager over many individual snippets if you have more than a handful. One reviewed container with a change log beats eight snippets added by six people over two years.
  7. Wrap your own code so it waits for the DOM, and so it cannot run before the elements it touches exist. Builder-rendered markup is not available at parse time.
  8. Scope every selector as tightly as you can, and treat builder-generated class names as unstable. Prefer an identifier or attribute you set yourself on the element through the builder over a generated class that will change on the next republish.
  9. Namespace everything you declare. Use a single object or an immediately-invoked function rather than loose global variables and function names, so you cannot collide with the platform's own scripts or another embed.
  10. Guard against double execution. A script added at both page and account level, or a page that re-renders a section, can run your code twice. Set a flag and return early if it is already set.
  11. Never put a secret in an embed. Anything in page JavaScript is public: no API keys with write access, no tokens, no private endpoints. If the browser needs privileged data, it must call a server you control that holds the credential.
  12. Save, then republish the funnel or site. Custom code commonly does not appear on the live page until a republish, which is the single most frequent reason an embed looks like it did not save.
  13. Verify in the browser on the live page, not in the editor preview. Open developer tools: confirm the script is present in the document, confirm no console errors, confirm the network request to the vendor fires, and confirm the expected event appears in the vendor's own real-time view.
  14. Test the critical path with the script live: submit the form, book the appointment, complete the payment. A tracking script that breaks a submit handler costs more than it measures.
  15. Record what you added, where, why and who owns it. Then re-verify after any platform update or template change, because embeds fail silently.
03

What data moves

Platform page to the third party

  • Whatever the script is designed to collect: page URL and referrer, user agent, screen and viewport, click and scroll behavior, time on page.
  • Identifiers the script sets or reads: its own cookies, local storage entries, advertising identifiers, click identifiers from campaign URL parameters.
  • Conversion events you fire deliberately, with whatever parameters you attach.
  • Form field values, but only if the script is written to read them, which is exactly the behavior to audit before embedding anything on a form.

Third party to the page

  • Rendered widget markup: chat panels, booking embeds, review carousels, consent banners.
  • Configuration and experiment assignments fetched at runtime.
  • Further scripts, since many vendor snippets are loaders that pull additional code, which is why reviewing only the snippet you pasted is insufficient.

Within the page

  • Your own code reading and writing DOM elements, pre-filling fields from query string parameters, and attaching event handlers.

What does not move

  • Server-side platform data. An embed has no privileged access to the account's contacts, conversations or pipelines; it sees only what the page rendered.
  • Authenticated API access. Nothing in page JavaScript can safely hold a credential, so there is no secure read of account data from an embed.
  • Server-side events. A browser script cannot report a conversion that happened in a back office or after a refund; that needs a server-side call.
  • Anything from a visitor with JavaScript blocked, an ad blocker active, or consent declined.
04

Worked example

Scenario: a lead-generation funnel must report a conversion to an ad platform when the form is submitted, pre-fill the campaign source into a hidden field, and load a consent banner before any tracking fires.

  1. You review the three snippets involved: the consent manager, the ad platform's base tag, and the ad platform's event call. You confirm what each collects and that the privacy notice covers it.
  2. In the funnel's custom code area you place the consent manager in the head, synchronously, because it must run before anything else can set a cookie.
  3. You place the ad platform's base tag in the head too, but configured so it only initializes after the consent manager signals that marketing consent was granted. Without that gate the tag fires regardless of the banner, which makes the banner decorative.
  4. In the body-end custom code you add your own snippet, wrapped in an immediately-invoked function with a guard flag so it cannot run twice if the section re-renders.
  5. Your snippet waits for DOM ready, reads the campaign parameters from the URL query string, and writes them into a hidden form field you created in the builder, targeted by a custom attribute you set on that field, not by a generated class name.
  6. Your snippet attaches a submit listener to the form, scoped to that one form by its own identifier rather than to every form on the page.
  7. On submit, the listener checks the consent state; if marketing consent is present it calls the ad platform's event function with the conversion event name, then allows the submission to proceed without interfering with it.
  8. You save and republish the funnel, because unpublished custom code does not exist on the live page.
  9. You open the live URL with developer tools. The consent banner appears, no tracking request fires before you accept, and after accepting the base tag loads. The hidden field is populated from the query string.
  10. You submit the form with a test record. The console is clean, the ad platform's real-time view shows the conversion, and the contact arrives in AppBO with the campaign source on the custom field.
  11. You repeat with consent declined and confirm the form still submits and the contact still arrives, with no tracking request. The submission path must never depend on the tracking path.
  12. Three months later a template change republishes the funnel. Your post-change checklist includes reloading the live page and confirming the embed still fires, which catches the regression before the next campaign spends anything.
05

Limits and gotchas

Performance limits

Every third-party script is a dependency on someone else's uptime and latency. A synchronous script in the head blocks rendering until it responds, so a slow vendor becomes your slow page. Load asynchronously, keep the number of embeds small, and measure the page before and after adding one. On mobile connections the difference between three scripts and ten is the difference between a landing page that converts and one that is abandoned.

Retries and idempotency

Browser events are fire-and-forget: if the request fails, is blocked, or the visitor navigates away mid-flight, the event is simply lost, and there is no retry to configure. Conversely, code that runs twice fires the event twice and inflates your numbers. Guard with a flag, fire conversion events once per meaningful action, and for anything that must be accurate (revenue, billing-relevant conversions) report it server-side from a webhook instead of trusting the browser.

Selector and mapping traps

Builder-generated class names and DOM structure are not a public interface and can change on republish or after a platform update. Code bound to them is code that will break without warning. Set your own identifier or data attribute on the element through the builder and target that. Expect the DOM to be built after parse, so never query elements at the top of a head script, and expect dynamically rendered sections to appear after your listener was attached.

Duplicate execution

The classic cause is the same snippet present at account level and at page level, or a tag manager container that also contains the tag you pasted directly. Audit for duplicates whenever conversion counts look too good.

Sandbox versus live

The builder preview is not the live page: different URL, sometimes different markup, and tracking that behaves differently. Always verify on the published URL. Use the vendor's own debug or preview mode rather than guessing, and keep test traffic out of production reporting by filtering it in the vendor rather than by remembering not to click.

Consent, privacy and credentials

Tracking scripts on pages that collect sensitive information are a genuine compliance risk, not a theoretical one. Gate every non-essential script behind consent, keep the consent manager first in the load order, and reconsider whether a third-party script belongs on a page handling health or financial data at all. Never embed a credential: anything in page JavaScript is readable by every visitor.

What commonly breaks

  • Custom code saved but the funnel never republished.
  • A platform or template update changing markup out from under a brittle selector.
  • An ad blocker or privacy browser silently dropping the vendor request, so measurement looks broken when it is working as designed.
  • A script error early in the page preventing later scripts, including form handling, from running.
  • Global variable collisions between two embeds, or between an embed and the platform's own code.
  • A vendor loader quietly pulling in new code that changes behavior without any change on your side.
  • Tracking gated on consent in one place and not another, producing numbers nobody can reconcile.

Connect it with us.

We wire the integration, map the fields, test both directions and hand it over with the SOPs your team needs to run it.

Book a call