Script tag
Add Voidhash to a site without a JavaScript build, such as Webflow, WordPress or plain HTML.
The script-tag build, voidhash.global.js, is the web SDK as one file that a <script> tag loads
from Voidhash's CDN. It includes everything it needs, about 44 kB gzipped, and records the same
page views, campaigns, events, identity and consent as the npm package.
Add the snippet
Put both tags in the <head> of every page:
<script>
window.voidhash = window.voidhash || { q: [] };
[
"track",
"page",
"identify",
"signOut",
"reset",
"setAnalyticsConsent",
"setAdDataSharing",
"setPersonAttributes",
"on",
].forEach(function (method) {
window.voidhash[method] =
window.voidhash[method] ||
function () {
window.voidhash.q.push([method, arguments]);
};
});
["getDistinctId", "getSessionId", "getFeatureVariant"].forEach(function (method) {
window.voidhash[method] = window.voidhash[method] || function () {};
});
window.voidhash.isFeatureEnabled =
window.voidhash.isFeatureEnabled ||
function (key) {
var flags = (window.voidhash.options || {}).featureFlags || {};
return (flags.defaults || {})[key] === true;
};
window.voidhash.playStoreUrl =
window.voidhash.playStoreUrl ||
function (packageName) {
return "https://play.google.com/store/apps/details?id=" + encodeURIComponent(packageName);
};
</script>
<script
async
src="https://cdn.voidhash.com/web/latest/voidhash.global.js"
data-publishable-key="vh_pk_..."
></script>The first tag lets the page call window.voidhash before the file has loaded. It queues calls to
the listed methods, isFeatureEnabled() returns the flag's default,
and the other methods that return a value return undefined. The second tag loads the SDK without
holding up the page. When the file arrives, it creates the client as window.voidhash, records the
page view and campaign, then makes the queued calls in order.
Keep the async attribute. If the file cannot load, your page works as before: queued calls are
never made, flags read as their defaults and getDistinctId() returns undefined.
Choose a version
/web/latest/voidhash.global.js serves the newest build; pages pick up a new one within about five
minutes. For a production site, load a fixed version instead, so a new build never changes a page
you tested. A version's file never changes, so add its integrity hash:
<script
async
src="https://cdn.voidhash.com/web/0.0.1-alpha.1-g83f7412/voidhash.global.js"
integrity="sha384-..."
crossorigin="anonymous"
data-publishable-key="vh_pk_..."
></script>The first line of each file names its version, and openssl computes the hash:
curl -s https://cdn.voidhash.com/web/latest/voidhash.global.js | head -n 1
# /*! @voidhash/web 0.0.1-alpha.1-g83f7412 | MIT */
curl -s https://cdn.voidhash.com/web/0.0.1-alpha.1-g83f7412/voidhash.global.js \
| openssl dgst -sha384 -binary | openssl base64 -ATo serve the file yourself, install the package as in the
quickstart and copy dist/voidhash.global.js to your
static files.
Options
The tag's data- attributes set client options:
| Attribute | Option |
|---|---|
data-publishable-key | publishableKey. Without a key here or in window.voidhash.options, no client starts. |
data-base-url | baseUrl, for a first-party proxy or a tracking domain. |
data-analytics-consent | analyticsConsent: granted, denied or pending. |
data-analytics-consent-source | analyticsConsentSource: sdk or app. |
data-store-before-consent | "false" sets storeBeforeConsent: false. |
data-cross-subdomain-identity | Present (any value but "false") turns on crossSubdomainIdentity. |
data-capture-page-views | "false" turns off automatic page views. |
data-capture-page-leaves | "false" turns off automatic page leaves. |
data-capture-outbound-clicks | "false" turns off automatic outbound clicks. |
For options an attribute cannot carry, such as functions, set window.voidhash.options in the
first tag and leave data-publishable-key out:
<script>
window.voidhash = window.voidhash || { q: [] };
window.voidhash.options = {
publishableKey: "vh_pk_...",
analytics: {
sanitizeUrl: function (url) {
return url.pathname.indexOf("/account/") === 0 ? null : url;
},
},
featureFlags: { defaults: { "new-checkout": true } },
};
// ... the rest of the snippet above ...
</script>
<script async src="https://cdn.voidhash.com/web/latest/voidhash.global.js"></script>A data- attribute wins over the same option. If an option is invalid, the SDK does not start and
reports the error in the browser console; the page is unaffected.
Track events and identify visitors
Call the client from anywhere on the page:
<button onclick="voidhash.track('trial_started', { plan: 'pro' })">Start your free trial</button>voidhash.identify("user_123", { email: "ada@example.com" });Methods that return a value, such as getDistinctId() for Stripe purchases,
work once the client has started:
voidhash.on("initialized", function (event) {
document.querySelector("#checkout").dataset.visitor = event.distinctId;
});Ask for consent
Where consent comes first, start with consent pending and nothing stored, then pass the answer
from your consent banner. Calls made before the file loads are queued.
<script
async
src="https://cdn.voidhash.com/web/latest/voidhash.global.js"
data-publishable-key="vh_pk_..."
data-analytics-consent="pending"
data-store-before-consent="false"
></script>voidhash.setAnalyticsConsent(analyticsAllowed ? "granted" : "denied");With a consent tool such as Cookiebot or OneTrust, also add data-analytics-consent-source="app".
See Privacy and consent.
Content Security Policy
Besides the connect-src entries, allow
https://cdn.voidhash.com, or the origin you serve the file from, in script-src. The inline
snippet needs a nonce or hash in script-src, or move it into a file of its own.
Next steps
Something wrong or missing on this page? Tell us by email or on Discord.