Docs
Auto-Capture
One ~5 kB script tag (2 kB gzip) captures UI interactions automatically — page views, clicks, and form submissions — grouped into sessions, with no further code changes. Perfect for session context around your manually tracked events.
Setup
Add the script to your HTML and initialize it with your public key. Public keys are safe to ship in a page: they can only submit auto-capture events through POST /v1/events/batch and can never read activity, so an exposed key never leaks other users' data.
<script src="https://softechlog.com/stl_capture.js"></script>
<script>
Softechlog.init("stl_pk_xxxxxxxxxxxx", {
// apiUrl: "https://api.softechlog.com", // override for staging
// trackPageviews: true, // auto page views incl. SPA route changes
// captureUrlQuery: false, // keep ?query and #hash out of stored URLs
// debug: false, // log to the console
});
</script>| Option | Default | Description |
|---|---|---|
apiUrl | https://api.softechlog.com | Override the API base URL (staging, proxies) |
trackPageviews | true | Record ui.page_viewed on load and on pushState / replaceState / popstate route changes |
captureUrlQuery | false | By default query strings and fragments are stripped from stored URLs (?token=…, #access_token=…). Set true to keep them. |
debug | false | Log activity to the browser console |
Identify the current user
Call once on login or page load when the user is known. Events buffered before the call are attributed retroactively, and the identity persists for the tab session. Until then, events are stored without an actor:
// After login (or on page load when the user is known):
Softechlog.identify({
id: currentUser.id, // required
name: currentUser.name, // optional
email: currentUser.email, // optional
avatar_url: currentUser.avatar, // optional
});
// On logout: flush, forget the user, start a new session
Softechlog.reset();What gets auto-captured
| Trigger | Action name | Metadata |
|---|---|---|
| Page view (incl. SPA route change) | ui.page_viewed | url, title, referrer |
| Button click | ui.button_clicked | text, selector, page_url |
| Link click | ui.link_clicked | text, href, selector, page_url |
| Form submit | ui.form_submitted | form_id, form_name, page_url |
All auto-captured events are stored with capture_mode: "auto", so you can always separate them from server-tracked events when filtering.
Privacy controls
- Form field values are never read — only structural metadata like form names and page URLs.
- URLs are stored without query string or fragment unless you opt in with
captureUrlQuery: true. data-stl-ignoreon an element (or any ancestor) skips it entirely;data-stl-maskkeeps the event but redacts its text.- Element text is truncated to 200 characters.
<button data-stl-ignore>Not tracked at all</button> <div data-stl-mask><button>Tracked, text redacted</button></div>
Sessions
The script generates a session id (a UUID) and attaches it to every event, so the API groups them into browsing sessions automatically. Each session records its starting page, start/end time, and event count — browse them in the dashboard under Sessions and replay a session's timeline, or fetch it yourself with GET /v1/events?session_id=…. Softechlog.reset() starts a fresh session on logout.
Delivery
- Events are batched every 2 seconds (≤ 100 events / ≤ 48 KB per request), sent immediately when the tab is hidden, and via
sendBeaconon unload. - Requests use
text/plainwith the public key in the JSON body, so no CORS preflight is needed from any origin. - Retries with exponential backoff on network errors and
5xx; honoursRetry-Afteron429; pauses for 5 minutes on402(monthly plan limit reached). The queue is capped at 500 events (oldest dropped). - Rate limit: 200 batch calls per minute per public key — batching keeps normal traffic far below this.
Manual tracking from the browser
For meaningful actions outside the auto-capture scope, you can also track custom events with the same script:
Softechlog.track('checkout.started', { plan: 'growth' }); // action must be resource.verb
Softechlog.page(); // manual page view (e.g. custom routers)
Softechlog.flush(); // send the queue now
Softechlog.sessionId; // current session id (UUID)