Script tag
Add Voidhash to a site without a JavaScript build, such as Webflow, WordPress, or plain HTML.
For a site without a bundler, the SDK also ships as one file, voidhash.global.js, that a
<script> tag loads from Voidhash's CDN. It contains everything it needs, about 40 kB gzipped, and
does what the npm package does: page views, campaign attribution, events, identity, and consent.
Add the snippet
Put both tags in the <head> of every page:
<script>
window.voidhash = window.voidhash || { q: [] };
[
"track",
"page",
"identify",
"signOut",
"reset",
"setAnalyticsConsent",
"setPersonAttributes",
"on",
].forEach(function (method) {
window.voidhash[method] =
window.voidhash[method] ||
function () {
window.voidhash.q.push([method, arguments]);
};
});
["getDistinctId", "getSessionId", "getFeatureVariant", "isFeatureEnabled"].forEach(
function (method) {
window.voidhash[method] = window.voidhash[method] || function () {};
},
);
</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 keeps the calls,
and the methods that return a value return undefined until then. The second loads the SDK
without holding up the page. When it arrives, it creates the client as window.voidhash, starts
it, records the page view and the campaign the visitor came from, and then makes the kept calls,
in order.
Keep the async attribute. If the file cannot be loaded, for example while the CDN is
unreachable, your page renders and works as before: the kept calls are simply never made, and
getDistinctId() returns undefined, so code that reads it must handle that.
Choose a version
/web/latest/voidhash.global.js is always the newest release; your site picks up a new one within
minutes of it. To decide when your site updates, load a version instead, which we recommend for a
production site: a release can then never change a page you have tested. A version's file never
changes, so add its integrity hash, and the browser refuses to run anything else:
<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 every file names its version, so the newest one is:
curl -s https://cdn.voidhash.com/web/latest/voidhash.global.js | head -n 1
# /*! @voidhash/web 0.0.1-alpha.1-g83f7412 | MIT */and the integrity hash of a version is:
curl -s https://cdn.voidhash.com/web/0.0.1-alpha.1-g83f7412/voidhash.global.js | openssl dgst -sha384 -binary | openssl base64 -AYou can also serve the file yourself: install the package as in the
quickstart and copy dist/voidhash.global.js from it to
your static files.
Options
The tag's data- attributes set the client's options:
| Attribute | Option |
|---|---|
data-publishable-key | publishableKey. Required, unless window.voidhash.options sets it: without a key, the file starts no client. |
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, for a consent tool. |
data-store-before-consent | "false" sets storeBeforeConsent: false. |
data-capture-page-views | "false" turns off automatic page views. |
For any other option, such as analytics.sanitizeUrl to keep private
pages out, set the options in the first tag, as window.voidhash.options, and leave
data-publishable-key out. The file still loads async, and the client starts with these options:
<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 on the tag wins over the same option here. If an option is wrong, the SDK does
not start and reports the error to the browser console; the page is not affected.
Track events and identify visitors
Call the client from anywhere on the page, for example from a button:
<button onclick="voidhash.track('trial_started', { plan: 'pro' })">Start your free trial</button>After a visitor signs up or signs in, identify them with your user ID:
voidhash.identify("user_42", { email: "ada@example.com" });Before the file has loaded, only the methods the snippet lists are available. 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 your site needs consent first, as in the EU, start the client with consent pending and keep
its state off the device until the visitor agrees, then pass the answer from your consent tool:
<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>// In your consent tool's callback. Calls made before the file loads are kept.
voidhash.setAnalyticsConsent(analyticsAllowed ? "granted" : "denied");With a consent tool such as Cookiebot or OneTrust, add data-analytics-consent-source="app" as well,
so the tool's answer always wins over one stored on an earlier visit; see
Use a consent tool.
Privacy and consent explains what each answer changes.
Content Security Policy
Besides the connect-src entries in Content Security Policy,
allow https://cdn.voidhash.com, or the origin you serve the file from, in script-src. The inline
snippet needs a nonce or a hash in script-src, or move it into a file of its own.