Installing the tracking script
The three ways to add the Convultra JavaScript SDK to a site, how to use it in a bundled app, the custom domain option, and which one to pick.
On this page · 8 sections
The Convultra JavaScript SDK can be installed three ways. All of them load the same script, about 10KB gzipped, and the only difference is how the page waits for it.
Comparison
| Method A: Stub + async | Method B: Sync script | Method C: Async only | |
|---|---|---|---|
| Best for | Conversion tracking (purchases, leads, signups) | Simple sites that accept a brief block | Traffic analytics only |
| Blocks rendering | No | Yes (about 10KB) | No |
| Race conditions | None, the stub queues calls | None, the SDK is ready after the tag | Possible, the SDK may not be ready when you call it |
| Conversion tracking | Yes | Yes | No (nothing queues early calls) |
| Automatic analytics | Yes | Yes | Yes |
| Recommended | Yes | For simple setups | For analytics only |
Method A: Stub + async script (recommended)
The recommended approach for any site that tracks conversions. It uses the same pattern as gtag.js: a light stub queues calls while the full SDK loads asynchronously.
<!-- Convultra stub: queues calls before SDK loads -->
<script>
window.Convultra=window.Convultra||(function(){
var q=[];var c={q:q,initialized:false,config:{}};
['init','track','trackPurchase','trackLead','trackSignup','trackConversion',
'trackAddToCart','trackViewContent','trackBeginCheckout','enhance',
'setEnhancedUserData','identify','trackContact','trackSchedule',
'trackDownload','trackSubscription','trackAddPaymentInfo',
'trackAddToWishlist','trackSearch'].forEach(function(m){
c[m]=function(){q.push({m:m,a:Array.prototype.slice.call(arguments,0),t:Date.now()});return c;};
});
return c;
})();
</script>
<script async src="https://cdn.convultra.com/ultra.min.js" data-convultra-key="YOUR_API_KEY"></script>
How it works:
- The inline stub creates a
window.Convultraobject with every SDK method. - Each call pushes onto an internal queue with a timestamp.
- The
asyncscript downloads the full SDK without blocking render. - When the SDK loads, it drains the queue and processes every call in order.
You can call Convultra.trackPurchase() or any other method immediately after the stub, before the async script has loaded. The stub captures it and the SDK processes it once ready.
Method B: Sync script (no stub)
A single script tag that blocks rendering until the SDK has loaded. The SDK is available immediately after the tag, so no stub is needed.
<script src="https://cdn.convultra.com/ultra.min.js" data-convultra-key="YOUR_API_KEY"></script>
After this tag, window.Convultra is fully initialized:
<script src="https://cdn.convultra.com/ultra.min.js" data-convultra-key="YOUR_API_KEY"></script>
<script>
// Convultra is guaranteed to be ready here
Convultra.trackPurchase({
orderId: 'order_789',
value: 49.99,
currency: 'USD'
})
</script>
This blocks rendering until the script downloads and executes. For most sites Method A is better because it handles the same cases without blocking.
Method C: Async script only (analytics only)
A single async tag with no stub. The SDK tracks traffic analytics automatically, but you cannot reliably call conversion methods because nothing queues calls made before the SDK loads.
<script async src="https://cdn.convultra.com/ultra.min.js" data-convultra-key="YOUR_API_KEY"></script>
Tracked automatically, with no extra code:
- Pageviews and page navigation
- Click IDs (
gclid,gbraid,wbraid,fbclid,msclkid,ttclid,oppref) - Sessions and unique visitors
- Referrer and landing page
- UTM parameters (
utm_source,utm_medium,utm_campaign,utm_term,utm_content) - Device, browser, OS and location
Do not use this method if you need to track conversions. Calls made before the SDK loads fail silently. Use Method A instead.
Bundled applications (React, Vue, Next.js and similar)
There is no npm package. The SDK is a single script that defines a global Convultra object, so in a bundled application you still load it from the CDN, with Method A in your HTML template or by injecting the same two tags at startup, and call the global from your components:
// Anywhere after the stub: the call is queued until the SDK loads
window.Convultra.trackPurchase({
orderId: 'order_123',
value: 99.99,
currency: 'USD'
})
If you load the script without the data-convultra-key attribute, initialize it yourself once. init() takes the project key as a string:
Convultra.init('YOUR_API_KEY')
Custom domain
To serve the SDK from your own domain, which keeps tracking first-party and out of reach of blocklists that target third-party tracking hosts, add a custom tracking domain under Settings → Tracking → Custom tracking domains. Then swap the CDN URL:
<!-- Before -->
<script async src="https://cdn.convultra.com/ultra.min.js" data-convultra-key="YOUR_API_KEY"></script>
<!-- After -->
<script async src="https://track.yourdomain.com/v1/ultra.js" data-convultra-key="YOUR_API_KEY"></script>
This works with all three methods. The SDK code is identical; only the delivery domain changes. See Custom tracking domains for the full setup.
Source URLs
| Environment | URL |
|---|---|
| Production (minified) | https://cdn.convultra.com/ultra.min.js |
| Development (unminified, with source maps) | https://cdn.convultra.com/ultra.js |
| Custom domain | https://track.yourdomain.com/v1/ultra.js |
Always use ultra.min.js in production. The unminified build includes source maps and verbose logging, which is useful for debugging and not suited to production.
Which key goes in the tag
data-convultra-key takes your project key (proj_...), shown under Settings → Tracking → Install with a Copy button. The ready-made snippets for HTML, React, WordPress, Shopify and the API are on the Tracking health page. The key is public and write-only, so it is safe to ship in a page. Never put a secret sk_ API key in a browser; those are for reading data and belong on a server.