SmileLineDocs
Lead capture

Website tracking

Install one snippet so SmileLine finds your website's forms, captures their submissions and attributes every enquiry.

By the end of this page the SmileLine script will be live on your website, the setup checklist will be green, and enquiries will arrive with their marketing attribution attached — without changing any of your existing forms.

What the script does

  • Finds your forms. It scans each page for enquiry forms and lists them under Settings → Website with their field names and labels, ready to confirm. See Website forms.
  • Captures submissions. Once a detected form is confirmed, every submission becomes a lead — your form keeps working exactly as before; SmileLine listens alongside it.
  • Attributes enquiries. UTM parameters, ad click IDs, the landing page and the referrer travel with each submission, so attribution works without any extra wiring.
  • Swaps in tracking numbers. With call tracking set up, the script replaces your published phone number with the visitor's rotating tracking number — every phone-shaped number on the page, the specific numbers a pool lists, or elements you mark with class="sl-phone" — so calls get the same attribution as form submissions.
  • Sends nothing else. Beyond the one number-assignment request call tracking needs, there is no pageview beacon and no analytics stream — see Privacy and consent.

Only owners and managers can see Settings → Website and manage tracking.

Install the snippet

Until the script is installed, the tracking page is the install flow: a status band at the top, then an Install card with three numbered steps.

Go to Settings → Website. If tracking isn't set up yet, the status card reads Tracking not set up, so click Install. (Later, the same card links to Tracking settings.)

Your website address. Save it and SmileLine checks which platform the site runs on, so step 3 shows instructions for WordPress, Wix, Squarespace, Webflow, Shopify or a custom build. If it can't tell, you get generic steps and a Check again link.

Copy the install code. Two tabs, and you only need one of them. Snippet is the default and suits every website; npm SDK is for custom sites and single-page apps, and is covered under Developer SDK. The snippet looks like this, but copy yours from SmileLine, because it carries your practice's site key and regional hostname:

<script async src="https://widget-eu.smileline.io/sl.js" data-site="pk_YOUR_SITE_KEY"></script>

That is an EU example; US practices receive a widget-us.smileline.io address.

Paste it into your platform. Add it to every page of your website, ideally in a site-wide header. If someone else looks after the site, use Email these steps to a developer: SmileLine emails them the snippet with the platform-specific steps. One send per hour.

Once the script has loaded from your website, the numbered steps drop away and the Install card keeps only the snippet and its Copy button.

The script updates itself (it is cached for about five minutes), so you install it once. If your platform requires pinned assets, download sl.js and serve it yourself under Advanced → Self-hosted script, and you then own updates.

Watch the setup checklist

Under the status band, four steps confirm the setup with real events from your website. The page refreshes itself while you install, and only the next outstanding step shows its explanation, so the list stays short. Once all four are green the list disappears and the band alone reports that tracking is live.

StepTurns green when
Snippet installedThe script has phoned home from your website in the last day.
Forms detectedThe script found at least one form to capture.
Test enquiry receivedAny form on your site was submitted, and the submission arrives even before mapping.
Mapping confirmedYou confirmed a detected form's field mapping so its submissions open journeys.

For the last two steps, submit one of your own forms as a test, then confirm its mapping. See Confirm a detected form.

The script is deliberately quiet. It makes exactly three kinds of request:

  1. Loading its configuration when a page opens.
  2. Reporting a newly found form — field names, labels and input types only. Nothing a visitor typed is ever included.
  3. Submitting a form's contents when the visitor presses submit — the only moment enquiry data leaves the browser.

It also honours consent:

  • It reads Google Consent Mode and IAB TCF signals from your cookie banner automatically, and your own code can signal consent explicitly through the SDK.
  • Until storage consent is granted, the visitor's attribution lives in memory only — nothing is written to cookies or local storage. A later grant upgrades it; an explicit denial wipes anything previously stored.
  • When storage is allowed, SmileLine keeps a first-party visitor ID cookie (_sl_vid, 400 days, SameSite=Lax) and an attribution record in local storage (_sl:v1, expiring after 180 days of inactivity).
  • A visit's first touch is recorded once and never replaced; the last touch is replaced only when a new session (after 30 minutes of inactivity) arrives with campaign parameters or an external referrer.

Domain pinning

With domains pinned, detected forms only accept submissions from those hostnames — anything else parks for review instead of becoming a lead. Built forms are exempt: they submit from SmileLine's own hosted-form origin and are protected by their bot check instead. Custom integrations are exempt too, because they post server-to-server.

On the tracking page, open Advanced and use Domain pinning to Pin up to ten hostnames. Pinning practice.com also covers www.practice.com and other subdomains. An empty list means pinning is off.

A submission from an unpinned domain still receives a success response — the sender learns nothing — and the parked submission appears in the review queue so a legitimate enquiry from a forgotten domain is never lost.

Form detection follows the same boundary: the script only registers forms found on pages belonging to your configured website address, its www twin and subdomains, or a pinned domain. Reports from any other host are ignored.

Pause tracking or rotate the key

Both live under Advanced on the tracking page.

  • The Tracking live switch pauses tracking everywhere: installed scripts stop loading their configuration and go inert. While tracking is paused the status band says so and offers Resume tracking.
  • Regenerate key mints a new site key. Snippets carrying the current key stop working immediately, so update the website straight afterwards.
  • Configuration changes reach installed scripts within about a minute.

Developer SDK

Building a custom site or single-page app? The npm package replaces the snippet rather than joining it, so install one or the other, never both. It carries the same tracking core (visitor identity, attribution, consent) and turns Snippet installed green on its own, but it leaves the two things the snippet does by touching your pages to you:

  • It does not find your forms, so nothing appears under Website forms by itself. Build each form's capture hook yourself and post to it with captureLead.
  • It does not swap in call tracking numbers.

Pick it from the npm SDK tab in step 02 of the install card, which prints the snippet below with your own site key and region already filled in:

npm install @smileline/browser
import { init, captureLead, consent } from "@smileline/browser";

init({ siteKey: "pk_YOUR_SITE_KEY" });

init defaults to the EU cell, so US practices pass their regional API base: init({ siteKey: "pk_…", apiBase: "https://api-us.smileline.io" }). The tracking page prints yours, so copying from there is always right.

  • init(options) — call once; later calls are ignored. Safe to import during server-side rendering (it becomes a no-op).
  • captureLead(token, fields) — submits an enquiry to a form's capture endpoint with the visitor's attribution attached. It never throws; it resolves to { ok, status }.
  • consent(state)"granted", "denied", or per-flag, e.g. { adStorage: true }.
  • visitor() — the visitor ID, or null before init completes.

The snippet installs the same API as a global command queue, safe to call before the script loads:

sl("consent", "granted");
sl("captureLead", "YOUR_FORM_TOKEN", { email: "amelia@example.co.uk" });

On this page