Skip to main content

Website Snippet

Reach attributes revenue to marketing activities using a business’s first-party data – we provide a lightweight javascript snippet that can be injected onto a customer’s public-facing landing page and tracks when a user lands on a business’s website (after clicking on a marketing link) and then later identifies themselves on that same site.

Who does what

Attribution involves two parties, each with distinct responsibilities. Partners are responsible for implementing createIdentification() on their own app and owned surfaces — logged-in dashboards, post-signup flows, checkout confirmations, and any other page where your platform knows who the user is. Because these are surfaces you control, you wire up the identification calls directly in your application code. Tenants (your businesses) are responsible for a simpler task: adding the Reach tracking snippet to their own public-facing website. That’s it. During onboarding, Reach handles the rest — we inspect the tenant’s site, identify the forms where visitors submit their contact details (quote requests, lead capture forms, contact pages), and configure listeners that automatically fire createIdentification on the tenant’s behalf. Tenants do not need to write any identification code themselves. Together, these two integration surfaces give Reach a complete picture: the snippet on the tenant’s site captures anonymous visits and ad click attribution, Reach’s configured listeners capture identifications from public forms, and your platform’s createIdentification calls capture identifications from logged-in experiences. All of it feeds into a single attribution chain. The rest of this article covers the partner’s implementation — how to load the snippet, the best practices around it, and how to call createIdentification from your application.

Basic Installation

Please ensure you load this javascript snippet on every page in your app. Add the script to the <head> section of your HTML and for optimal performance, place it as early as possible. Embedding this snippet requires two parameters:
  • PARTNER_HASH – a short, public-facing identifier assigned to your vertical SaaS platform by Reach. This will always be the same value – you can hard-code it into your application.
  • TENANT_EXTERNAL_ID – the unique, case-sensitive business ID you use to identify businesses in your platform. This must be the same ID you are setting on tenants that you create in the Reach system. Ideally, this is a value you already have available on any web pages that you host for your clients. Note: you will onboard the business to Reach when they opt-in to using Reach’s services in the Management UI.
<head>
  <script src="https://public.embedreach.com/scripts/:PARTNER_HASH/:TENANT_EXTERNAL_ID/analytics.js"></script>
</head>
Please get in touch with our team if you have any questions about the best way to load the script if you’re using your particular web development framework.

Load it early

Place the script tag in <head>, not at the bottom of <body> and not with defer. The snippet tracks page visits as soon as it loads — if it loads late, short sessions and fast bounces won’t be recorded. Loading early also ensures window.reach is initialized before any createIdentification call fires.

Embed it directly — don’t use GTM

Load the script tag directly on the page. Do not route it through Google Tag Manager or a similar tag management system. GTM is frequently blocked by ad blockers and privacy-focused browsers, which silently drops tracking coverage with no error surfaced to you.

Don’t cache the script aggressively

Some of what analytics.js returns is server-driven configuration (per-tenant tracking settings, etc.). If you serve the script through a CDN or middleware that caches it with a long TTL, tenants won’t pick up configuration updates without a deploy. Short cache windows (a few minutes) are fine; multi-hour or multi-day caches are not.

Create Identifications

The snippet exposes window.reach.createIdentification(data), which ties the current visitor’s anonymous session to a real identity. Call it whenever a visitor reveals who they are — this is what enables Reach to attribute a visit (and the ad click that drove it) back to a real customer. At least one of email or phone is required for a meaningful identification. source_id is a good place to pass your platform’s internal user ID so Reach can deduplicate records across calls.
createIdentification deduplicates calls within a session — calling it multiple times with the same data is safe and won’t produce duplicate records.

When to call it

Anonymous / form-based flows — call createIdentification when the visitor submits a form that captures their contact details (quote request, contact us, lead capture, checkout, etc.):
// Make sure this code is placed within a script tag AFTER the reach script is loaded
window.reach.createIdentification({
  email: 'test@example.com',
  phone: '+12223334444',
  f_name: 'test',
  l_name: 'example',
  // choose a meaningful name for each unique action that could trigger an identification
  source_id: 'appointment-scheduling-system',
});
Logged-in experiences — call createIdentification as soon as the visitor’s identity is known. There are three moments to cover:
  1. After a successful login
async function handleLogin(credentials) {
  const user = await login(credentials);
  window.reach.createIdentification({
    email: user.email,
    phone: user.phone,
    source_id: user.id,
  });
}
  1. After account creation:
async function handleSignup(formData) {
  const user = await createAccount(formData);
  window.reach.createIdentification({
    email: user.email,
    phone: user.phone,
    source_id: user.id,
  });
}
  1. On page load when the visitor is already authenticated (e.g. they return to a logged-in dashboard):
if (currentUser) {
  window.reach.createIdentification({
    email: currentUser.email,
    source_id: currentUser.id,
  });
}

Content Security Policy (CSP) Considerations

If you have implemented a strict Content Security Policy (CSP) you may need to update it for the Reach app to be successful. The attribution snippet script is loaded from https://public.embedreach.com and makes requests to https://api.embedreach.com. Assuming no other scripts on your website, an example strict CSP would look like this:
Content-Security-Policy:
script-src 'self' https://public.embedreach.com;
connect-src 'self' https://api.embedreach.com;
This CSP applies to the website attribution snippet only. If you are embedding
the Reach UI via the SDK, use the CSP described in the Security Headers (CSP & COOP) guide.

Onboarding Businesses to Reach

Businesses will be automatically onboarded when they opt-in to using Reach’s services in the Management UI. The externalId used here should be the same as the externalId passed in as onBusinessCreate() in the Management UI documentation. If your platform does not manage website creation and management on behalf of your clients, they will be shown instructions during Reach’s onboarding flow for how to inject the snippet on the most common website creators.

Cross-Domain Attribution

Sometimes, what looks like one website is actually on multiple domains – some common versions of this:
  • Client owns their website / landing page, but they redirect to another page hosted by the vertical SaaS platform (e.g. “online ordering”) where a user will put in their contact information.
  • Client owns their website / landing page, but they embed an iframe hosted by the vertical SaaS platform (e.g. “request an estimate” or “schedule a call” form) where a user will put in their contact information.
The Reach attribution snippet will automatically handle cross-domain attribution for these use-cases as long as it is embedded on both sites. During the implementation process with Reach, please let the team know the domain your platform uses for these “identification” pages to ensure this works correctly.

Error Handling

The script is designed to fail gracefully – no additional error handling is required at this time. Please reach out to our team if you have any concerns.