SDKs
Web SDK (browser)
Add Traqio to a website: @traqio/web keeps the ad click id from the landing URL to the conversion in first-party storage. React, Vue, Angular or plain HTML.
@traqio/web is the Traqio SDK for websites and web apps. When a visitor arrives from a Traqio tracking link, the landing URL carries the ad click id — the trackID — as traq_click. The SDK reads it, keeps it in first-party storage (localStorage, plus a cookie on your own domain) and hands it back when the visitor converts, so the conversion can be tied to its click deterministically, not by guesswork. It also records web events and visits, with consent and erasure. No fingerprinting, no third-party cookie, no advertising id; about 7 KB gzipped, one package for React, Vue, Angular and plain HTML.
Available on npm
@traqio/web · version 0.1.0How far it is proven: Analyzed and typechecked in CI; the native half compiles in a host app.Requirements#
- Any evergreen browser (the SDK uses
fetchandlocalStorage). - A web key for the site. The app key of a mobile app is refused here, and the reverse is true.
- Links that land on your site: a tracking link whose destination is a page of the site, so the trackID arrives in the URL.
Set up#
Create a web key#
In the console, open Integrations → SDK for the site and create a web key. List every origin that runs the SDK — scheme and host, no path:
https://example.com,https://www.example.com,https://app.example.com. There is no wildcard. A request from any other origin, or with noOriginheader at all (curl, a server), is refused with a 403.Install the package#
npm install @traqio/webOr, without a build step, one tag on every page — it initialises itself and exposes
window.Traqio:<script src="https://cdn.jsdelivr.net/npm/@traqio/web@0.1/build/traqio.min.js" data-sdk-key="YOUR_WEB_KEY" async></script>Initialise on every page#
// app/traqio.tsx — mounted once, in the root layout "use client"; import { useEffect } from "react"; import { Traqio } from "@traqio/web"; export function TraqioInit(): null { useEffect(() => { void Traqio.init({ sdkKey: process.env.NEXT_PUBLIC_TRAQIO_WEB_KEY! }); }, []); return null; }// main.ts (Vue) — or plugins/traqio.client.ts in Nuxt import { createProduct } from "vue"; import { Traqio } from "@traqio/web"; import App from "./App.vue"; void Traqio.init({ sdkKey: import.meta.env.VITE_TRAQIO_WEB_KEY }); createProduct(App).mount("#app");// app.config.ts import { ApplicationConfig, PLATFORM_ID, inject, provideAppInitializer } from "@angular/core"; import { isPlatformBrowser } from "@angular/common"; import { Traqio } from "@traqio/web"; export const appConfig: ApplicationConfig = { providers: [ provideAppInitializer(() => { if (isPlatformBrowser(inject(PLATFORM_ID))) void Traqio.init({ sdkKey: "YOUR_WEB_KEY" }); }), ], };import { Traqio } from "@traqio/web"; Traqio.init({ sdkKey: "YOUR_WEB_KEY" }); // tq_web_… — a WEB key, not the app keyOnce, as early as possible.
initreads the trackID from the current URL before anything else, so a visitor who leaves at once still keeps it. It is safe during server-side rendering: on a server it does nothing.Keep the trackID with the user#
The conversion that counts — a sign-up, a subscription, a purchase — usually happens on your backend, where the user id is known. The SDK writes the cookie
traq_clickon your registrable domain (example.com), so your backend receives it with the sign-up request itself:// Node / Express — the browser sends the cookie with the sign-up request itself app.post("/signup", async (req, res) => { const trackId = req.cookies.traq_click ?? req.body.traq_click ?? null; const user = await users.create({ email: req.body.email, traqClick: trackId }); // … });If your backend is on another domain, send it explicitly —
Traqio.getTrackId()returns it, or null when the visitor did not come from an ad:<form id="signup" action="/signup" method="post"> <input type="hidden" name="traq_click" /> … </form> <script> // Filled at submit time, so it works whenever the SDK finished loading. document.getElementById("signup").addEventListener("submit", (e) => { e.target.elements.traq_click.value = window.Traqio?.getTrackId() ?? ""; }); </script>Your backend then reports the sign-up with the trackID through a server SDK — Node.js, PHP / Laravel or Python — which ties it to the click.
Track events and set the user id#
Traqio.setUserId(user.id); // after sign-in Traqio.track("signup"); Traqio.track("purchase", { value: 49, currency: "EUR", transactionId: payment.id, store: "stripe" });Events are batched, retried, kept across page loads, and sent when the tab is hidden or the page is left. A tracked event is a conversion: track the steps that matter, not every page view.
What it does today, and what it does not#
| Today | |
|---|---|
| Read and keep the trackID (localStorage + first-party cookie) | Yes |
| Share it across subdomains of the same site | Yes, through the cookie |
| Events with value, currency and payment id | Yes — recorded, not attributed to a campaign |
| Visits (retention) | Yes |
| Consent, storage only after consent, erasure | Yes |
| Tie a sign-up to its click | Yes — your backend, through a server SDK |
| Show web conversions in the console's reports | Yes — per campaign, beside installs, once your backend ties the sign-up |
| Send web events to Meta or TikTok | Not yet |
The browser SDK never sends the trackID itself. A key anyone can read in your page must not be able to credit a campaign, so the tie between a conversion and its click is made by your backend, with a secret server key, through a server SDK. Events the browser sends itself are recorded without a campaign, and no web event is forwarded to ad networks yet.
Web events never touch your app's numbers
Consent#
Traqio.init({ sdkKey: "YOUR_WEB_KEY", waitForConsent: true });
// when your consent banner gets an answer
consentBanner.onAnswer((granted) => Traqio.setConsent(granted));With waitForConsent, nothing is written to the device — no localStorage, no cookie — until setConsent(true); the SDK still works for the current page, in memory. setConsent(true) then stores what the page kept, trackID included; setConsent(false) removes everything the SDK stored. The same answer governs whether data about this visitor may be shared with ad networks — see privacy.
API reference#
interface WebInitOptions {
sdkKey: string; // the site's web key (tq_web_…)
endpoint?: string; // default "https://api.traqio.app"
userId?: string; // your user id, once known
consent?: boolean; // ad-sharing consent, if already known
waitForConsent?: boolean; // store nothing until setConsent(true) — default false
trackIdDays?: number; // how long the trackID is kept — default 30
cookies?: boolean; // false = localStorage only — default true
}| Method | What it does |
|---|---|
init(options) | Reads the trackID from the URL, then starts the SDK. Idempotent; a no-op on a server. |
track(name, props?) | Queues an event: value, currency, transactionId, store. |
setUserId(id) | Your user id, after sign-in. |
getTrackId() | The kept trackID, or null when there is none or it expired. |
setConsent(granted) | Ad-sharing consent; with waitForConsent, also whether anything may be stored. |
forgetMe() | Erasure: the server deletes what it holds about this browser and user, the SDK goes quiet and forgets the trackID. |
flush() | Sends the queue now. Already wired to tab hide and page exit. |
Limits#
- Safari keeps storage written by JavaScript for 7 days on sites it classifies as tracking: the trackID can expire sooner there than
trackIdDayssays. - A click in an app's in-app browser followed by a conversion in another browser, without signing in, carries no trackID: that conversion is shown as unattributed, never guessed.
Proof so far
Frequently asked questions#
- What is the trackID?
- The click id of the ad the visitor clicked. A Traqio tracking link adds it to the landing URL as the traq_click parameter; @traqio/web reads it and keeps it in first-party storage (localStorage and a cookie on your own domain), so the conversion can later be tied to that exact click instead of being guessed.
- Is the web key a secret?
- No. It sits in your page, so anyone can read it. It is protected by its list of allowed origins: the Traqio API accepts it only from the origins you declared, checked on the Origin header the browser sets itself. Because it is public, a web key cannot attribute a conversion to a click — that takes a secret server key, used by your backend.
- Does @traqio/web work with server-side rendering?
- Yes. Nothing touches window or document when the module is imported, and init() does nothing on a server. Call it from code that runs in the browser: a client component, a .client plugin, or an initializer guarded by isPlatformBrowser.
- How long is the trackID kept?
- 30 days by default (the trackIdDays option). The server applies your attribution window anyway, so keeping it longer is harmless. Safari caps storage written by JavaScript at 7 days for sites that use it to track, so expect 7 days there.