Install the call tracking snippet on your website
Add the Steer Phones tracking snippet to your site, tag each phone number, and test the installation.
Install the snippet on every page where you want a phone number replaced. The pool continues to decide which visits receive a tracking number; untagged numbers stay as written.
Before you start
- Make sure the phone system has an active tracking pool.
- Get access to edit the site’s header code, or ask someone who has that access to install it.
- List every place the phone number appears: the header, footer, mobile menu, sticky call buttons, contact page, and location pages. Each copy needs its own tag.
Copy the snippet
In Dynamic Numbers, select Get code snippet, then Copy to clipboard. The snippet’s
example comment shows the phone system ID to use on the number elements. It is a UUID, such as
3f2b8c1e-7a4d-4e19-9b62-0c5d8e1f2a37.
The snippet also contains the fallback number that was set when you copied it. The site uses that number if an allocation request fails. If the pool’s fallback number changes and you want that request-failure fallback updated too, copy the snippet again and republish it. When a bot is recognized or the pool is exhausted, the API response uses the pool’s current fallback number.
Add the snippet to every page’s <head>
Put the snippet in the site-wide <head> so it runs on every page where tagged numbers appear. Its
anti-flash style hides tagged elements until the number is swapped and adds the dni-loaded class.
If the script does not mark an element as loaded, a three-second reveal fallback shows the page’s
original number.
The snippet adds the external DNI client asynchronously, so downloading that file does not block
page rendering. Its loader guard adds only one client script. Before the client loads, queued
initializations for the same phone system are reduced to the last options. After the client is
loaded, each SteerDNI.init() call replaces that phone system’s options and requests an allocation
again. Keep one copy of each initialization to avoid unnecessary requests.
Tag each phone number
Add data-steer-dni with the ID from that phone system’s snippet to the element that holds the
number. The script replaces the whole visible text of ordinary elements, so don’t put the tag on a
sentence, heading, or larger block that contains other text.
| Tagged element | What changes |
|---|---|
A link with a tel: target |
The dial target changes, and phone-number-looking link text changes. |
An element with a data-phone value |
The attribute and visible text change. |
| Any other element | Its visible text is replaced with the tracking number. |
Tag each separate instance, including desktop and mobile headers, sticky buttons, and contact or
location pages. For a click-to-call button, tag the link that has the tel: target as well as its
visible number. If a widget reads a number from data-phone, tag that element so both its text and
attribute are updated.
The script only sees the page’s own HTML. A number inside an image, iframe, or embedded third-party
widget cannot be swapped. On a published page, right-click the number, choose Inspect, and
confirm that data-steer-dni is on the element selected in the browser’s developer tools.
Platform instructions
After publishing a site-builder change, use the browser’s developer tools: right-click the number,
choose Inspect, and confirm that data-steer-dni is on the selected element.
WordPress
On WordPress.com, the header-code guide recommends the WPCode Insert Headers and Footers plugin. In the site’s dashboard, open Code Snippets > Header & Footer and paste the snippet in the Header box. This feature is available on Personal, Premium, Business, and Commerce plans. WordPress.com’s Theme File Editor is another option for a developer; it is available on plugin-enabled sites with those plans and is intended for people comfortable editing theme code.
Add data-steer-dni to the phone-number element in the page or theme markup. If your editor does
not let you set a custom attribute, ask a developer to add it to the rendered element.
Wix
In the site’s dashboard, open Settings > Custom Code, add the snippet, select All pages, and set Place Code in to Head. Wix requires the site to be published and have a connected domain; connecting a custom domain requires an upgraded Premium plan.
Tag a native page element that displays the number. Wix HTML embeds display their code in an
iframe, which the DNI script cannot inspect. The selectors option described in the
script reference can target page-owned
elements, but it cannot reach into an iframe. Move the number outside the embed before using DNI.
Squarespace
Use Code Injection to add the snippet to the site’s header. Code Injection is available on Core, Plus, Advanced, and some legacy plans. Code Blocks can render HTML as page content; JavaScript and iframe content in Code Blocks is limited to Core, Plus, Advanced, and some legacy plans. Use Code Injection for the site-wide header snippet rather than a page Code Block.
Add data-steer-dni to the number element in the page markup. If the editor does not expose a
custom-attribute field, ask a developer to add it or use a stable page-element selector as
described in the script reference.
Shopify
In the Shopify admin, open Online Store > Themes > Edit code, then open theme.liquid
in the Layout folder. Add the snippet inside the document head, before </head>, and
save. Shopify’s help center notes that a trial theme must be purchased before you can edit its
code.
In the theme file that renders the phone number, add data-steer-dni to the number’s text or
click-to-call link. Include every template or theme section that renders a duplicate, such as the
mobile header.
Webflow
In Site settings > Custom code, paste the snippet into Head code, save, and publish. Webflow lists an active Site plan or a Core, Growth, Agency, or Freelancer Workspace plan as requirements for custom code.
To tag a number, select its text or link element in Designer, open Element settings >
Custom attributes, and add data-steer-dni with the phone system ID as its value. Set a
click-to-call destination through the link settings.
Duda
In the side panel, open More > Settings and paste the snippet into Header HTML. Republish the site for the change to take effect. Duda notes that only certain code is accepted in Header HTML and unsupported code may be removed.
Add data-steer-dni to the number element’s rendered markup. If the editor does not let you add
custom attributes, ask a developer to update the page element.
Google Tag Manager
Create a Custom HTML tag, paste the snippet into its HTML field, and set its trigger to Initialization - All Pages. Google documents this trigger as running before other triggers except Consent Initialization. The tag still runs after the Tag Manager container loads, so a brief flash of the original number is possible.
Google Tag Manager hosts the snippet; add data-steer-dni to each phone-number element in your
site’s page or theme markup. The tag manager does not replace the need to mark each number.
Menu names change over time. For current steps, check the platform’s official custom-code help center or ask its support team.
Sites that change pages without reloading
The DNI client swaps numbers on page load. A single-page application that changes routes without
loading a new document needs to call SteerDNI.refresh() after each client-side route change so
newly rendered number elements are checked. The initial page load already allocates a number, so
skip the initial mount in a framework effect.
For a Next.js App Router client component, keep the component mounted across routes. Use React’s
useEffect and useRef hooks and usePathname from Next.js navigation. Add this component to
the layout that stays mounted across routes; the pathname ref prevents a refresh on its first
render:
'use client';
function DniRouteRefresh() {
const pathname = usePathname();
const previousPathname = useRef(pathname);
useEffect(() => {
if (previousPathname.current === pathname) return;
previousPathname.current = pathname;
window.SteerDNI?.refresh?.();
}, [pathname]);
return null;
}
usePathname doesn’t change when only the query string changes. If a query-only navigation
renders different tagged numbers, also call refresh() when the query changes.
For plain JavaScript, call refresh() after a route change or whenever new tagged numbers appear:
if (window.SteerDNI && window.SteerDNI.refresh) {
window.SteerDNI.refresh('your-phone-system-id');
}
Omit the phone system ID to refresh every pool on the page.
Sites with a Content Security Policy
If your Content Security Policy blocks the DNI origin, allow the origin shown before /v1/dni.js
in both script-src and connect-src. The generated snippet also contains inline JavaScript and
CSS; a policy that blocks inline code must allow those blocks using its nonce or hash mechanism.
Check the browser console for policy violations after publishing.
Track several locations on one page
Each location with its own phone system can be tracked on the same website, including on one page. Copy the snippet from each phone system, add one initialization per location, and tag each location’s number with that system’s own ID. Each location then receives a number from its own pool and attributes calls to its own phone system. The loader adds the DNI client only once.
Test your installation
- Open the site in a private or incognito window. A matching visit with an available pool number
should show a tracking number on each tagged element, and the element should have the
dni-loadedclass. Right-click the number, choose Inspect, and confirm the attribute and class on the live element. - In the browser console, run
SteerDNI.getSession('<id>'), replacing<id>with the phone system ID. A lent session includesphoneNumber,formattedNumber,expiresAt, andsessionToken. An untracked visit returnsnull; a bot or exhausted pool can instead return a fallback response withsessionToken: nullandpoolExhausted: true. - If the pool tracks only matching visits, test with
?utm_source=test&utm_medium=cpcwhen the pool’s paid-traffic preset is enabled. A plain URL is expected to keep your own number if it does not match the pool’s rules. - For a matching visit with an available tracking number, check Recent Sessions & Attributes. Call the number shown on the site and confirm that the visit appears as converted.
For a fresh allocation, close the private window and open a new one, or clear the site’s local
storage keys steer_visitor_id and steer_dni_session:<phone-system-id>. Recognized crawlers and
headless browsers receive the pool fallback, so an automated site checker may not show a tracking
number.
If someone else manages your website
Forward this checklist to your developer or agency:
- Paste the generated snippet unchanged into the site-wide
<head>. - Add
data-steer-dni="<id>"to every instance of the number, including click-to-call links. - Call
SteerDNI.refresh()after client-side route changes. - Allow the tracking origin in CSP
script-srcandconnect-src. - Do not bundle or inline
dni.js.
Troubleshooting
- The page keeps showing its own number: Confirm that the snippet is on the page and that the
visit matches the pool’s tracking rules. On the published page, right-click the number, choose
Inspect, and confirm
data-steer-dniis on the element with the pool’s phone system ID. - Your normal number flashes before the tracking number: Put the snippet in the site-wide header. A tag manager can insert it after the page starts rendering, so a brief flash is possible.
- The editor removed the tag: Right-click the number on the published page, choose Inspect,
and confirm
data-steer-dniis still on the selected element. If it is missing, add the attribute in the element’s markup or ask a developer to do so. - The number swaps on desktop but not mobile: The mobile layout has a separate copy of the number. Tag that element too and confirm it has the correct phone system ID in Inspect.
- One location shows another location’s tracking number: Check the number’s
data-steer-dnivalue in Inspect. Each number must use the ID from its own phone system’s snippet. - Numbers swap on the first page but not after moving to another page: The site changes routes
without a full page load. Call
SteerDNI.refresh()after the route change. - The browser console reports a Content Security Policy violation: Allow the tracking origin
in
script-srcandconnect-src, and allow the snippet’s inline code using the policy’s nonce or hash mechanism. - The console reports
SteerDNI: trusted API URL is unavailable: The client could not determine its API origin. Make sure it is loaded from a URL ending in/v1/dni.js, or setapiUrlto the API origin only. See theapiUrloption. - The console reports
SteerDNI: could not read the executing script URL: A browser policy kept the client from reading the URL it was loaded from, so it cannot derive the API origin from that address. Requests still work whenapiUrlis set; otherwise setapiUrlto the API origin only, or the client also reportsSteerDNI: trusted API URL is unavailable. - Every page view receives a different number: Browser storage may be blocked. The client can still swap a number, but without local storage it cannot keep the visitor ID or session between full page loads.
- A request returns 429 or fails: The visitor sees the snippet’s configured fallback if allocation cannot complete; if no fallback was configured, the original number is revealed. Allocation is limited to 30 requests per minute per IP address, so repeated tests from one office connection can share that limit.