Web quickstart
Add Voidhash analytics, attribution and identity to a website, React app or Next.js app.
Add the web SDK to an existing website so it records page views, campaign attribution and product events, and links signed-in visitors to your users. It takes about ten minutes.
The web SDK does not present paywalls or make purchases. Web purchases go through Stripe, and the SDK only supplies the buyer's ID: see Sell on the web and Connect Stripe (Help center).
Before you start
- A Voidhash project and its publishable key from Settings → API keys. Use the
vh_pk_test_...key on staging sites and thevh_pk_...key in production; see API keys. - A site built with a bundler. Sites without one, such as Webflow or WordPress, use the script tag instead.
Set up
Install the SDK
Install the SDK from the Voidhash package registry. effect 4 is a peer dependency; an app that
already uses effect 4 keeps its version.
npm install @voidhash/web@https://pkg.voidha.sh/@voidhash/web/branch:main effect@^4.0.3npm install @voidhash/web installs an older preview that doesn't match these docs. To pin a build
for production, see Install.
Configure the client
Each setup records page views, including client-side route changes, and campaign attribution as soon as the client initializes. Routers built on the History API need no extra code.
Create the client in a module your page's entry script imports:
import { createVoidhashClient } from "@voidhash/web";
export const voidhash = createVoidhashClient({
publishableKey: "vh_pk_...",
});
void voidhash.initialize();Put the test key in an environment file. Vite exposes only variables that start with VITE_:
VITE_VOIDHASH_KEY=vh_pk_test_...Wrap your app in the provider. It creates the client and initializes it on mount.
import { VoidhashProvider } from "@voidhash/web/react";
import { createRoot } from "react-dom/client";
import { App } from "./App";
createRoot(document.getElementById("root")!).render(
<VoidhashProvider config={{ publishableKey: import.meta.env.VITE_VOIDHASH_KEY }}>
<App />
</VoidhashProvider>,
);In the App Router, render the provider from a client component of your own, so you can pass
function options such as onDiagnostic. Put the test key in an environment file; Next.js exposes
only variables that start with NEXT_PUBLIC_ to the browser:
NEXT_PUBLIC_VOIDHASH_KEY=vh_pk_test_..."use client";
import { VoidhashProvider } from "@voidhash/web/react";
export function Providers({ children }: { children: React.ReactNode }) {
return (
<VoidhashProvider config={{ publishableKey: process.env.NEXT_PUBLIC_VOIDHASH_KEY! }}>
{children}
</VoidhashProvider>
);
}import { Providers } from "./providers";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}The provider is safe to server-render; the client initializes after hydration. Do not call
initialize() at the top level of a module, because client components also run on the server.
In the Pages Router, render the provider in pages/_app.tsx.
Then track a product event, for example when a visitor starts a checkout:
await voidhash.track("checkout_started", { plan: "yearly" });In React, take track from useAnalytics(). track() queues the event and never waits for the
network. See Track events.
Identify signed-in visitors
When a visitor signs up or signs in, call identify() with your own stable user ID. Their earlier
anonymous activity, including the campaign that brought them, joins that user.
await voidhash.identify("user_123", { email: "ada@example.com" });Use the same user ID in your mobile app, and call signOut() when the user signs out. See
Identify users.
Check your data
Open your site, browse a few pages, then open Activity → Analytics events in Studio. Page views appear within a few seconds. Events sent with a test key appear only when Studio shows the Test environment. If nothing arrives, see Troubleshooting.
If your site needs consent before analytics, as in the EU, start with analyticsConsent: "pending"
and storeBeforeConsent: false, then pass the visitor's answer to setAnalyticsConsent(). See
Ask for consent first.
Next steps
- See a complete sample site: page views, campaign attribution, consent, sign-up and checkout.
- Record page views and campaign attribution
- Attribute Stripe revenue to visitors
- Send requests through your own domain
Something wrong or missing on this page? Tell us by email or on Discord.