Skip to content

Autocapture

Kitbase automatically captures key user interactions without any manual instrumentation. From the moment you install the SDK, you get pageviews, sessions, clicks, scroll depth, outbound links, and more -- all out of the box.

Every auto-tracked event is sent on the __analytics channel and can be individually toggled on or off via configuration. No cookies are used; sessions are managed client-side with UUIDs.

Configuration

SDK initialization

Pass analytics options when creating the Kitbase instance. All flags default to true unless noted.

typescript
import { init } from '@kitbase/analytics';

const kitbase = init({
  sdkKey: 'YOUR_SDK_KEY',
  analytics: {
    autoTrackPageViews: true,      // screen_view events
    trackBfcacheRestore: true,     // screen_view on bfcache restore (back/forward in MPAs)
    autoTrackOutboundLinks: true,  // outbound_link events
    autoTrackClicks: true,         // click events
    autoTrackScrollDepth: true,    // scroll_depth events
    autoTrackVisibility: true,     // data-kb-track-visibility events
    autoTrackWebVitals: false,     // web_vitals events (opt-in)
    autoDetectFrustration: true,   // rage_click and dead_click events
  }
});

Script tag configuration

If you load Kitbase via a <script> tag, set the global config object before the SDK loads:

html
<script>
  window.KITBASE_CONFIG = {
    sdkKey: 'YOUR_SDK_KEY',
    analytics: {
      autoTrackPageViews: true,
      autoTrackClicks: false,  // disable click tracking
    }
  };
</script>
<script src="https://kitbase.dev/lite.js"></script>

Any option you omit defaults to true.

Auto-Tracked Events Reference

The table below is a quick-reference summary. Detailed sections for each event follow.

EventConfig FlagChannelFires When
session_start-- (always on)__analyticsNew session begins
session_end-- (always on)__analyticsSession times out (server-generated)
screen_viewautoTrackPageViews, trackBfcacheRestore__analyticsPage navigation or bfcache restore
clickautoTrackClicks__analyticsUser clicks interactive element
outbound_linkautoTrackOutboundLinks__analyticsUser clicks external link
scroll_depthautoTrackScrollDepth__analyticsUser leaves a page
rage_clickautoDetectFrustration__analytics3+ clicks within 1s in same area
dead_clickautoDetectFrustration__analyticsClick with no DOM response within 1s
web_vitalsautoTrackWebVitals__analyticsOnce per page load (opt-in)
revenue-- (explicit call)__analyticstrackRevenue() is called

session_start

Fired when a new session begins. A session starts on the first page load or after 30 minutes of inactivity (configurable).

FieldValue
Channel__analytics
Eventsession_start
ConfigAlways enabled

Tags:

Standard enrichment tags only (see Server-Side Enrichment below).

Session management API:

MethodReturnsDescription
kitbase.getSession()SessionFull session object
kitbase.getSessionId()stringCurrent session UUID
kitbase.reset()voidEnd current session and start a new one

Example payload:

json
{
  "channel": "__analytics",
  "event": "session_start",
  "client_timestamp": 1707840000000,
  "client_session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "tags": {}
}

session_end

Fired server-side when a session times out (no new events received within the session timeout window). This event is not sent by the SDK -- it is generated by the Kitbase backend.

FieldValue
Channel__analytics
Eventsession_end
ConfigAlways enabled

Computed fields:

FieldTypeDescription
durationnumberSession duration in milliseconds (last event timestamp minus session start timestamp)
bouncebooleantrue if the session had only one page view
pathstringLast viewed page path (exit page)

The session_end event inherits the device, geo, UTM, and referrer data from the session. It is used to compute bounce rate, average session duration, and exit pages in the analytics dashboard.

Server-generated

Unlike other auto-tracked events, session_end is created entirely by the backend. The SDK does not send this event. It fires after the session timeout (default 30 minutes) with no further activity.


screen_view

Fired on every page navigation -- initial load, History API calls (pushState, replaceState), and popstate events. Also fired when the browser restores a page from the back-forward cache (bfcache), which is common on MPA sites where back/forward navigation does not re-execute scripts.

FieldValue
Channel__analytics
Eventscreen_view
ConfigautoTrackPageViews (default true); bfcache restore controlled by trackBfcacheRestore (default true)

Tags:

TagTypeDescription
__pathstringwindow.location.pathname
__titlestringdocument.title
__referrerstringdocument.referrer
__utm_sourcestringUTM source parameter (if present)
__utm_mediumstringUTM medium parameter (if present)
__utm_campaignstringUTM campaign parameter (if present)
__utm_termstringUTM term parameter (if present)
__utm_contentstringUTM content parameter (if present)

SPA support:

The SDK automatically patches history.pushState and history.replaceState so that client-side navigation in React Router, Vue Router, Angular Router, Next.js, Nuxt, and any other History API-based router triggers a screen_view without additional configuration.

bfcache restore (MPA sites):

On multi-page sites (e.g., Astro without View Transitions), pressing the browser back or forward button may restore the page from the back-forward cache instead of reloading it. Since scripts do not re-execute in this case, pageviews would otherwise be missed. When trackBfcacheRestore is enabled (the default), the SDK listens for the pageshow event with event.persisted === true and sends a screen_view. Set trackBfcacheRestore: false to disable this behavior.

Manual page view tracking:

typescript
kitbase.trackPageView({
  path: '/custom-path',
  referrer: 'https://example.com',
  title: 'Custom Page Title',
});

Example payload:

json
{
  "channel": "__analytics",
  "event": "screen_view",
  "client_timestamp": 1707840012000,
  "client_session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "tags": {
    "__path": "/pricing",
    "__title": "Pricing - Kitbase",
    "__referrer": "https://google.com",
    "__utm_source": "google",
    "__utm_medium": "cpc"
  }
}

click

Fired when a user clicks an interactive element.

FieldValue
Channel__analytics
Eventclick
ConfigautoTrackClicks (default true)

Tags:

TagTypeDescription
__tagstringHTML tag name (e.g. button, a, ion-button)
__idstringElement id attribute
__classstringElement className
__textstringText content (trimmed, max 100 characters)
__hrefstringhref attribute (if present)
__pathstringwindow.location.pathname

Detected elements:

The SDK listens for clicks on the following interactive elements:

  • a, button, input, select, textarea
  • [role="button"], [role="link"], [role="menuitem"], [role="tab"]
  • Custom elements (any element whose tag name contains -, e.g. ion-button, my-dropdown)

Shadow DOM support:

The SDK uses composedPath() to traverse Shadow DOM boundaries. When a matched element lives inside a Shadow DOM, the custom-element host is reported.

No double-counting

When autoTrackOutboundLinks is also enabled, clicks on external links are handled by the outbound_link event and skipped by click tracking. Similarly, elements with a data-kb-track-click attribute fire only the named event, not the generic click.

Example payload:

json
{
  "channel": "__analytics",
  "event": "click",
  "client_timestamp": 1707840045000,
  "client_session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "tags": {
    "__tag": "button",
    "__id": "signup-btn",
    "__class": "btn btn-primary",
    "__text": "Start Free Trial",
    "__path": "/pricing"
  }
}

Fired when a user clicks or keyboard-activates (Enter/Space) a link pointing to an external domain (different hostname).

FieldValue
Channel__analytics
Eventoutbound_link
ConfigautoTrackOutboundLinks (default true)

Tags:

TagTypeDescription
__urlstringFull destination URL
__textstringLink text content (trimmed)

Example payload:

json
{
  "channel": "__analytics",
  "event": "outbound_link",
  "client_timestamp": 1707840060000,
  "client_session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "tags": {
    "__url": "https://github.com/kitbase-dev",
    "__text": "View on GitHub"
  }
}

scroll_depth

Fired when the user navigates away from a page (or closes the tab). Reports the maximum scroll depth reached during the page visit.

FieldValue
Channel__analytics
Eventscroll_depth
ConfigautoTrackScrollDepth (default true)

Tags:

TagTypeDescription
__depthnumberMaximum scroll depth as a percentage (0--100)
__pathstringwindow.location.pathname

Trigger: Flushed on beforeunload, history.pushState, and popstate. Scroll position is sampled using requestAnimationFrame throttling to avoid scroll jank.

Example payload:

json
{
  "channel": "__analytics",
  "event": "scroll_depth",
  "client_timestamp": 1707840120000,
  "client_session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "tags": {
    "__depth": 72,
    "__path": "/blog/getting-started"
  }
}

rage_click

Fired when the SDK detects 3 or more clicks within 1 second in the same area (30px radius) -- a strong signal of user frustration.

FieldValue
Channel__analytics
Eventrage_click
ConfigautoDetectFrustration (default true)

Tags:

TagTypeDescription
__selectorstringCSS selector of the clicked element
__tagstringHTML tag name (e.g. button, div)
__idstringElement id attribute
__classstringElement className
__textstringText content (trimmed, max 100 characters)
__click_countnumberNumber of rapid clicks detected
__pathstringwindow.location.pathname

Example payload:

json
{
  "channel": "__analytics",
  "event": "rage_click",
  "client_timestamp": 1707840300000,
  "client_session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "tags": {
    "__selector": "button.submit-btn",
    "__tag": "button",
    "__id": "submit-btn",
    "__class": "submit-btn btn-primary",
    "__text": "Submit",
    "__click_count": 5,
    "__path": "/checkout"
  }
}

Frustration analytics

Rage clicks are surfaced in the Frustration Signals dashboard, which shows top pages and elements by frustration score. The frustration score is calculated as rage_clicks * 3 + dead_clicks.


dead_click

Fired when the SDK detects a click on an interactive element that produces no DOM change within 1 second -- suggesting the user expected something to happen but nothing did. Uses a MutationObserver to watch for child list, attribute, and character data changes.

FieldValue
Channel__analytics
Eventdead_click
ConfigautoDetectFrustration (default true)

Tags:

TagTypeDescription
__selectorstringCSS selector of the clicked element
__tagstringHTML tag name (e.g. button, a)
__idstringElement id attribute
__classstringElement className
__textstringText content (trimmed, max 100 characters)
__pathstringwindow.location.pathname

Example payload:

json
{
  "channel": "__analytics",
  "event": "dead_click",
  "client_timestamp": 1707840310000,
  "client_session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "tags": {
    "__selector": "div.card-header",
    "__tag": "div",
    "__id": "",
    "__class": "card-header",
    "__text": "Premium Plan",
    "__path": "/pricing"
  }
}

Frustration analytics

Dead clicks are surfaced alongside rage clicks in the Frustration Signals dashboard. Use them to identify UI elements that look clickable but aren't, so you can improve your design.


revenue

Fired when trackRevenue() is called. Included here for completeness since it uses the internal __analytics channel.

FieldValue
Channel__analytics
Eventrevenue

Tags:

TagTypeDescription
__revenuenumberRevenue amount
__currencystringCurrency code (default 'USD')
+ custom tagsAny additional tags passed via the tags option

Usage:

typescript
kitbase.trackRevenue({
  amount: 49.99,
  currency: 'USD',
  tags: {
    plan: 'pro',
    interval: 'monthly',
  },
});

Example payload:

json
{
  "channel": "__analytics",
  "event": "revenue",
  "client_timestamp": 1707840200000,
  "client_session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "tags": {
    "__revenue": 49.99,
    "__currency": "USD",
    "plan": "pro",
    "interval": "monthly"
  }
}

web_vitals

Fired once per page load when Core Web Vitals metrics have been collected. This event is opt-in and must be explicitly enabled.

FieldValue
Channel__analytics
Eventweb_vitals
ConfigautoTrackWebVitals (default false)

Tags (only collected metrics are included):

TagTypeDescription
__lcpnumberLargest Contentful Paint -- loading performance (ms)
__clsnumberCumulative Layout Shift -- visual stability (score)
__inpnumberInteraction to Next Paint -- interactivity (ms)
__fcpnumberFirst Contentful Paint -- first render (ms)
__ttfbnumberTime to First Byte -- server response time (ms)

Usage:

typescript
const kitbase = init({
  sdkKey: 'YOUR_SDK_KEY',
  analytics: {
    autoTrackWebVitals: true,
  }
});

A 30-second timeout ensures the event is sent even if some metrics never fire (e.g., INP requires user interaction). Only metrics that were successfully collected are included in the tags.

Example payload:

json
{
  "channel": "__analytics",
  "event": "web_vitals",
  "client_timestamp": 1707840500000,
  "client_session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "tags": {
    "__lcp": 1250,
    "__cls": 0.05,
    "__inp": 180,
    "__fcp": 800,
    "__ttfb": 120
  }
}

Data Attribute Events

Data attributes let you fire named events directly from HTML -- no JavaScript required. Annotate any element and the SDK handles the rest. These work with Angular, React, vanilla HTML, or any framework.

Custom channel

Unlike the automatic events above that always use the __analytics channel, data-attribute events use the channel you specify (defaulting to engagement).

data-kb-track-click

Track custom named click events without writing JavaScript.

FieldValue
ChannelUser-specified (default engagement)
EventValue of the data-kb-track-click attribute
ConfigautoTrackClicks (default true)

HTML attributes:

AttributeRequiredDefaultDescription
data-kb-track-clickYes--Event name to fire
data-kb-click-channelNoengagementChannel for the event

Tags:

TagTypeDescription
__pathstringwindow.location.pathname

Example:

html
<!-- Basic usage -->
<button data-kb-track-click="CTA Clicked">Sign Up Now</button>

<!-- With custom channel -->
<button
  data-kb-track-click="Add to Cart"
  data-kb-click-channel="ecommerce"
>
  Add to Cart
</button>

When an element has data-kb-track-click, the generic click auto-tracking is skipped for that element to avoid double-counting. The SDK uses closest() to find the nearest annotated ancestor, so child elements inside an annotated parent are also covered.


data-kb-track-visibility

Track how long elements are visible in the viewport. The event fires when the tracked element leaves the viewport, is removed from the DOM, or the user navigates away.

FieldValue
ChannelUser-specified (default engagement)
EventValue of the data-kb-track-visibility attribute
ConfigautoTrackVisibility (default true)

HTML attributes:

AttributeRequiredDefaultDescription
data-kb-track-visibilityYes--Event name to fire
data-kb-visibility-channelNoengagementChannel for the event
data-kb-visibility-thresholdNo0.5IntersectionObserver threshold (0--1)

Tags:

TagTypeDescription
duration_secondsnumberTotal visible time, rounded to whole seconds
duration_msnumberTotal visible time in milliseconds

Example:

html
<!-- Track a section with default settings -->
<section data-kb-track-visibility="Pricing Section Viewed">
  ...
</section>

<!-- Custom channel and threshold -->
<section
  data-kb-track-visibility="Hero Banner Viewed"
  data-kb-visibility-channel="marketing"
  data-kb-visibility-threshold="0.75"
>
  ...
</section>

The SDK uses IntersectionObserver to detect enter/leave viewport transitions and MutationObserver to pick up dynamically added or removed elements. Visibility data is flushed on beforeunload, history.pushState, popstate, and element removal.


Common Fields on All Auto-Tracked Events

Every auto-tracked event includes the following fields in its payload:

FieldTypeDescription
channelstringEvent channel -- always __analytics for auto-tracked events, user-specified for data-attribute events
eventstringEvent name (e.g. screen_view, click)
client_timestampnumberDate.now() when the event was created
client_session_idstringUUID v4, rotated after the session timeout (default 30 min inactivity)
tagsobjectMerged super properties + event-specific tags
user_idstringPresent only if the user has been identified via kitbase.identify(...)

Server-Side Enrichment

All events -- both auto-tracked and manually tracked -- are enriched server-side before storage. These enrichment tags are available as first-class filter dimensions in the dashboard.

Browser and OS:

TagDescription
__browserBrowser name (Chrome, Firefox, Safari, Edge)
__browser_versionBrowser version string
__osOperating system (Windows, macOS, iOS, Android, Linux)
__os_versionOS version string

Device:

TagDescription
__deviceDevice type: desktop, mobile, or tablet
__brandDevice brand (Apple, Samsung, Google, etc.)
__modelDevice model (iPhone 15, Pixel 8, Galaxy S24, etc.)

Geolocation (from IP):

TagDescription
__countryCountry name
__regionRegion or state
__cityCity name

Privacy

IP addresses are used only for geolocation enrichment and are not stored. See Analytics Guide — Privacy for details.


Bot Filtering

Kitbase automatically filters bot traffic so your analytics stay clean. No configuration is needed.

The following are detected and excluded:

CategoryExamples
Headless browsersPuppeteer, Playwright, PhantomJS
Testing toolsSelenium, WebDriver, Cypress
HTTP clientscurl, wget, Postman, HTTPie
Search crawlersGooglebot, Bingbot, DuckDuckBot, Yandex, Baidu
Social crawlersTwitterbot, Facebookbot, LinkedInBot
Monitoring toolsUptimeRobot, Pingdom, New Relic

Bot detection runs automatically on every incoming event. Detected bot traffic is silently discarded before it reaches your dashboard or analytics queries.


Disabling Specific Auto-Track Features

You can selectively disable any auto-track feature while keeping the rest active. Set the corresponding flag to false in your configuration.

Disable a single feature

typescript
const kitbase = init({
  sdkKey: 'YOUR_SDK_KEY',
  analytics: {
    autoTrackClicks: false, // disable click tracking
    // everything else remains enabled by default
  }
});

Disable multiple features

typescript
const kitbase = init({
  sdkKey: 'YOUR_SDK_KEY',
  analytics: {
    autoTrackClicks: false,
    autoTrackScrollDepth: false,
    autoTrackOutboundLinks: false,
    // only pageviews and visibility remain active
  }
});

Disable all auto-tracking

If you want full manual control, disable every flag:

typescript
const kitbase = init({
  sdkKey: 'YOUR_SDK_KEY',
  analytics: {
    autoTrackPageViews: false,
    trackBfcacheRestore: false,
    autoTrackOutboundLinks: false,
    autoTrackClicks: false,
    autoTrackScrollDepth: false,
    autoTrackVisibility: false,
    autoTrackWebVitals: false,
    autoDetectFrustration: false,
  }
});

You can still track events manually using kitbase.track(...), kitbase.trackPageView(...), and kitbase.trackRevenue(...).

Script tag configuration

html
<script>
  window.KITBASE_CONFIG = {
    sdkKey: 'YOUR_SDK_KEY',
    analytics: {
      autoTrackPageViews: true,
      autoTrackOutboundLinks: false,  // disabled
      autoTrackClicks: false,         // disabled
      autoTrackScrollDepth: true,
      autoTrackVisibility: true,
    }
  };
</script>

Configuration reference

FlagEvent(s) ControlledDefault
autoTrackPageViewsscreen_viewtrue
trackBfcacheRestorescreen_view (bfcache restore)true
autoTrackOutboundLinksoutbound_linktrue
autoTrackClicksclick, data-kb-track-clicktrue
autoTrackScrollDepthscroll_depthtrue
autoTrackVisibilitydata-kb-track-visibilitytrue
autoTrackWebVitalsweb_vitalsfalse
autoDetectFrustrationrage_click, dead_clicktrue

Released under the MIT License.