From 419a4fac6f82b9e23779360eac0d169fc661b00d Mon Sep 17 00:00:00 2001
From: Darshil Rathod <69842641+RathodDarshil@users.noreply.github.com>
Date: Thu, 3 Sep 2026 15:52:48 +0530
Subject: [PATCH] docs: add beta Web Attribution guide (LIN-2731)
---
docs.json | 1 +
introduction.mdx | 12 +-
sdk/web.mdx | 349 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 361 insertions(+), 1 deletion(-)
create mode 100644 sdk/web.mdx
diff --git a/docs.json b/docs.json
index 972e489..ecb3509 100644
--- a/docs.json
+++ b/docs.json
@@ -30,6 +30,7 @@
"sdk/ios",
"sdk/android",
"sdk/expo",
+ "sdk/web",
"sdk/unity",
"sdk/shopify"
]
diff --git a/introduction.mdx b/introduction.mdx
index e40b2a1..8745a16 100644
--- a/introduction.mdx
+++ b/introduction.mdx
@@ -36,7 +36,7 @@ Linkrunner is a Mobile Measurement Partner (MMP) that helps founders, growth mar
## SDKs
-Pick your platform — every SDK ships with attribution, deferred deep linking, event tracking, and revenue capture out of the box.
+Pick your platform. Mobile SDKs cover app attribution, while the Web SDK measures website traffic and events.
@@ -71,6 +71,16 @@ Pick your platform — every SDK ships with attribution, deferred deep linking,
+
+
+
+ Beta website attribution for traffic, campaigns, users, and events
+
+
+ Storefront and checkout attribution
+
+
+
## Ad Network Integrations
diff --git a/sdk/web.mdx b/sdk/web.mdx
new file mode 100644
index 0000000..bf04abb
--- /dev/null
+++ b/sdk/web.mdx
@@ -0,0 +1,349 @@
+---
+title: "Web SDK"
+description: "Set up Linkrunner's beta Web Attribution SDK for page views, users, events, and traffic-source attribution"
+icon: "globe"
+---
+
+The Linkrunner Web SDK tracks page views, known users, custom events, and the traffic sources that brought visitors to your website.
+
+
+ Web Attribution is currently in beta. To request access, email
+ [support@linkrunner.io](mailto:support@linkrunner.io) with your project name and website domain.
+ We will enable Web Attribution and send you a Web SDK token.
+
+
+The SDK automatically captures:
+
+- Page views, including single-page app navigation
+- First-touch and last-touch UTM attribution
+- Ad click IDs such as `gclid`, `fbclid`, and `ttclid`
+- Paid, organic, social, AI search, referral, and direct traffic
+- Browser, device, geography, and performance data
+
+## 1. Add the SDK
+
+We recommend loading the browser SDK from the Linkrunner CDN. This lets Linkrunner ship fixes and updates without requiring you to change or redeploy your integration.
+
+The direct script tag and the Next.js helper both load `https://cdn.linkrunner.io/web/v1/lr.js` by default. The [npm package](https://www.npmjs.com/package/@linkrunner/web) provides the typed Next.js component and event methods, while the browser SDK still stays current through the CDN.
+
+
+
+Add this script before the closing `` tag. Replace `YOUR_WEB_SDK_TOKEN` with the token provided by Linkrunner.
+
+```html
+
+```
+
+
+
+Install the package:
+
+```bash
+npm install @linkrunner/web
+```
+
+Add `LinkrunnerScript` to your root layout so it loads once and stays active across navigation:
+
+```tsx
+// app/layout.tsx
+import { LinkrunnerScript } from '@linkrunner/web/next'
+
+export default function RootLayout({ children }) {
+ return (
+
+
+ {children}
+
+
+
+ )
+}
+```
+
+`LinkrunnerScript` loads the browser SDK from the Linkrunner CDN by default.
+
+
+
+Install the package:
+
+```bash
+npm install @linkrunner/web
+```
+
+Add `LinkrunnerScript` to `_app.tsx`, not `_document.tsx` or an individual page:
+
+```tsx
+// pages/_app.tsx
+import { LinkrunnerScript } from '@linkrunner/web/next'
+
+export default function App({ Component, pageProps }) {
+ return (
+ <>
+
+
+ >
+ )
+}
+```
+
+`LinkrunnerScript` loads the browser SDK from the Linkrunner CDN by default.
+
+
+
+The SDK tracks the first page view when it loads. Single-page app navigation is tracked by default.
+
+## 2. Identify users and track events
+
+Call `identify` after a user signs in or when you otherwise know their identity. Use a stable internal user ID rather than an email address or phone number.
+
+```js
+import { lr } from '@linkrunner/web'
+
+lr.identify(String(user.id))
+```
+
+With the script tag, use the global object:
+
+```js
+window.lr.identify(String(user.id))
+```
+
+The SDK saves this ID in `localStorage` and includes it as `user_id` on later events.
+
+Track a custom event with `track`:
+
+```js
+lr.track('purchase', {
+ amount: 49.99,
+ currency: 'USD',
+})
+```
+
+To show a signed-up user's details in the Web Events dashboard, identify the user and then send a `signup` event:
+
+```js
+lr.identify(String(user.id))
+
+lr.track('signup', {
+ name: user.name,
+ email: user.email,
+ phone: user.phone,
+})
+```
+
+Only send personal data when you have permission to do so. Calling `identify` does not add the user ID to events that were already captured.
+
+
+ Calls made before the SDK finishes loading are queued and replayed after initialization.
+
+
+## 3. Verify the integration
+
+Set `data-debug="true"` while testing:
+
+```html
+
+```
+
+Then open your browser's developer tools:
+
+1. In **Console**, confirm that messages start with `[Linkrunner]` and include `Initialized`.
+2. In **Network**, confirm that page views and events send a `POST` request to `/web/ingest`.
+3. Trigger a test event and confirm the console reports `Sent via fetch`.
+
+Debug logging turns on automatically on `localhost`, `127.0.0.1`, and `[::1]`. Remove `data-debug="true"` after testing.
+
+## Configuration
+
+### Script tag attributes
+
+| Attribute | Required | Description | Default |
+| --- | --- | --- | --- |
+| `data-token` | Yes | Your Web SDK token | None |
+| `data-domain` | No | Your first-party collection hostname, such as `lr.example.com` | None |
+| `data-endpoint` | No | A full URL or same-origin path for a proxy you operate | None |
+| `data-spa` | No | Set to `"false"` to disable automatic SPA page views | `true` |
+| `data-debug` | No | Set to `"true"` or `"false"` to control console logging | On for local development |
+
+You can also set the same options before the script loads:
+
+```html
+
+
+```
+
+Without `data-domain` or `data-endpoint`, events go to `https://api.linkrunner.io/web/ingest`.
+
+## First-party collection
+
+Some ad blockers stop requests to analytics domains. First-party collection sends events through your own domain instead.
+
+### Proxy through your website
+
+This is the most reliable option because both the SDK and event endpoint use paths on your website. For Next.js, add two rewrites:
+
+```js
+// next.config.js
+module.exports = {
+ async rewrites() {
+ return [
+ {
+ source: '/lr/lr.js',
+ destination: 'https://cdn.linkrunner.io/web/v1/lr.js',
+ },
+ {
+ source: '/lr/ingest',
+ destination: 'https://api.linkrunner.io/web/ingest',
+ },
+ ]
+ },
+}
+```
+
+Point `LinkrunnerScript` at those routes:
+
+```tsx
+
+```
+
+For a plain script tag:
+
+```html
+
+```
+
+
+ Your proxy must preserve the visitor's IP address. Forward `X-Forwarded-For` with the visitor's address first, or set `X-Linkrunner-Visitor-IP` explicitly. If the proxy drops it, geographic data will identify your proxy instead of the visitor.
+
+
+### Point a subdomain at Linkrunner
+
+Use this option when you cannot add proxy routes to your website.
+
+
+
+In the Linkrunner dashboard, open **Settings → Manage Domains** and add the collection subdomain you want to use, such as `lr.example.com`.
+
+
+
+Add a CNAME record with your DNS provider:
+
+```text
+lr.example.com. CNAME api.linkrunner.io.
+```
+
+Linkrunner issues the TLS certificate on the first request for a registered subdomain.
+
+
+
+Add `data-domain` to the script tag:
+
+```html
+
+```
+
+For Next.js, use the `domain` prop:
+
+```tsx
+
+```
+
+
+
+Run this request before relying on the subdomain:
+
+```bash
+curl -i -X OPTIONS \
+ -H 'Origin: https://example.com' \
+ -H 'Access-Control-Request-Method: POST' \
+ https://lr.example.com/web/ingest
+```
+
+Expect a `204` response with an `access-control-allow-origin` header. Then confirm in your browser's **Network** tab that event requests go to `https://lr.example.com/web/ingest`.
+
+
+
+
+ Set `data-domain` to a hostname, not a URL. The SDK accepts a scheme or trailing slash, but it always normalizes the value to `https://HOST/web/ingest`. Use `data-endpoint` only when you control the full proxy path.
+
+
+
+ If each event creates one request to your subdomain and another to `api.linkrunner.io`, the first-party endpoint is failing and the SDK is using its fallback. Check the CNAME, domain registration, and any firewall or authentication rules in front of the subdomain.
+
+
+## Attribution storage
+
+| Data | Storage | Lifetime |
+| --- | --- | --- |
+| First-touch UTMs and click IDs | `localStorage` | Until browser storage is cleared |
+| Last-touch click IDs | `localStorage` | 90 days |
+| Last-touch UTMs | `sessionStorage` and `localStorage` | 24 hours from the campaign click |
+| Visitor ID and user ID | `localStorage` | Until browser storage is cleared |
+| Session ID and page count | `sessionStorage` | Current tab session |
+
+The 24-hour `localStorage` copy preserves last-touch UTMs when a payment gateway or 3D Secure flow returns the visitor in a new tab.
+
+## Troubleshooting
+
+
+
+Confirm that you are using the Web SDK token provided by Linkrunner. Mobile SDK project tokens do not work with the Web SDK. If you need a token, contact [support@linkrunner.io](mailto:support@linkrunner.io).
+
+
+
+Load the SDK once. In Next.js, put `LinkrunnerScript` in the root layout or `_app.tsx`, not on individual pages. The SDK already tracks SPA navigation by default.
+
+
+
+Use [first-party collection](#first-party-collection). A same-origin proxy is the strongest option. A CNAME may still be detected by browsers that inspect DNS records.
+
+
+
+Do not trust client-side events for payments, entitlements, or other sensitive state changes. Send those events from your backend with the [Event Capture API](/api-reference/event-capture) or [Revenue Tracking API](/api-reference/revenue-tracking).
+
+
+
+## More resources
+
+
+
+ View the package, current version, and full SDK reference.
+
+
+ Read the source code and release history.
+
+
+ Install Web Attribution on a Shopify storefront and checkout.
+
+
+
+**Need help or beta access?** Contact [support@linkrunner.io](mailto:support@linkrunner.io)