Browser RUM Integration
This guide walks through adding Real User Monitoring (RUM) to a browser application using the Kubesense SDK. It covers installation, initialization, and every instrumentation API available.
1. Prerequisites
Before integrating, obtain the following from your Kubesense workspace:
| Value | Where to find it |
|---|---|
applicationId | Settings → RUM Application Management → your application → View Details |
clientToken | Settings → RUM Application Management → your application → View Details |
2. Installation
Option A — npm / Yarn (recommended)
Full SDK (includes Session Replay):
npm install @kubesense/kubesense-browser-rum
# or
yarn add @kubesense/kubesense-browser-rumSlim SDK (no Session Replay, smaller bundle):
npm install @kubesense/kubesense-browser-rum-slim
# or
yarn add @kubesense/kubesense-browser-rum-slimOption B — CDN (script tag)
Add this script in the <head> of your HTML, before any other scripts:
<script>
(function(h,o,u,n,d){h=h[d]=h[d]||{q:[],onReady:function(c){h.q.push(c)}}
d=o.createElement(u);d.async=1;d.src=n
n=o.getElementsByTagName(u)[0];n.parentNode.insertBefore(d,n)
})(window,document,'script','<CDN_URL>/kubesense-rum.js','KUBESENSE_SDK')
</script>note: Replace <CDN_URL> with the URL provided by your Kubesense account team.
3. Initialization
Call init() once, as early as possible in your application's entry point. All API calls made before init() are queued and replayed automatically.
npm / ES Module
import { kubesenseSdk } from '@kubesense/kubesense-browser-rum'
kubesenseSdk.init({
applicationId: '<YOUR_APPLICATION_ID>',
clientToken: '<YOUR_CLIENT_TOKEN>',
kubesenseRumEndpoint: 'app.kubesense.ai',
service: 'my-web-app',
env: 'production',
version: '1.0.0',
sessionSampleRate: 100,
trackUserInteractions: true,
trackResources: true,
trackLongTasks: true,
firstPartyDomains: [
"api.kubesense.ai", // exact hostname
/\.kubesense\.ai/, // all subdomains via regex
(host) => host.endsWith(".internal"), // custom function
],
})CDN
window.KUBESENSE_SDK.onReady(function() {
window.KUBESENSE_SDK.init({
applicationId: '<YOUR_APPLICATION_ID>',
clientToken: '<YOUR_CLIENT_TOKEN>',
kubesenseRumEndpoint: 'app.kubesense.ai',
service: 'my-web-app',
env: 'production',
version: '1.0.0',
sessionSampleRate: 100,
trackUserInteractions: true,
trackResources: true,
trackLongTasks: true,
firstPartyDomains: [
"api.kubesense.ai",
/\.kubesense\.ai/,
(host) => host.endsWith(".internal"),
],
})
})React (App.tsx / main.tsx)
import { kubesenseSdk } from '@kubesense/kubesense-browser-rum'
kubesenseSdk.init({
applicationId: '<YOUR_APPLICATION_ID>',
clientToken: '<YOUR_CLIENT_TOKEN>',
kubesenseRumEndpoint: 'app.kubesense.ai',
service: 'my-react-app',
env: process.env.NODE_ENV,
version: process.env.REACT_APP_VERSION,
sessionSampleRate: 100,
trackUserInteractions: true,
trackResources: true,
trackLongTasks: true,
firstPartyDomains: [
"api.kubesense.ai",
/\.kubesense\.ai/,
(host) => host.endsWith(".internal"),
],
})
function App() { /* ... */ }
export default App4. Configuration Reference
Required
| Option | Type | Description |
|---|---|---|
applicationId | string | Your RUM application ID |
clientToken | string | Your client authentication token |
Common Options
| Option | Type | Default | Description |
|---|---|---|---|
kubesenseRumEndpoint | string | — | Your Kubesense RUM endpoint hostname |
service | string | — | Service name for this application |
env | string | — | Deployment environment (production, staging, etc.) |
version | string | — | Application version (e.g. 1.2.3) |
sessionSampleRate | number | 100 | Percentage of sessions to collect (0–100) |
Tracking Behaviour
| Option | Type | Default | Description |
|---|---|---|---|
trackUserInteractions | boolean | true | Auto-collect clicks and user actions |
trackResources | boolean | true | Collect XHR / Fetch resource events |
trackLongTasks | boolean | true | Collect long task events (>50ms) |
trackViewsManually | boolean | false | Disable automatic view creation (SPA manual control) |
trackBfcacheViews | boolean | false | Create separate views for back/forward cache restores |
trackEarlyRequests | boolean | false | Capture requests made before SDK initialises |
trackAnonymousUser | boolean | true | Track anonymous user identity and extend cookie expiration |
actionNameAttribute | string | — | HTML attribute used to name actions (e.g. data-action-name) |
excludedActivityUrls | MatchOption[] | — | Request URLs to ignore for page activity calculation |
firstPartyDomains | MatchOption[] | — | Additional domains to treat as first-party in resource classification |
allowedTracingUrls | Array<MatchOption | TracingOption> | — | URLs to inject distributed trace headers into |
allowedGraphQlUrls | Array<MatchOption | GraphQlUrlOption> | — | GraphQL endpoints to track with operation metadata |
trackFeatureFlagsForEvents | FeatureFlagsForEvents[] | [] | Attach feature flag evaluations to these event types |
allowUntrustedEvents | boolean | false | Listen to programmatically dispatched DOM events (useful in automated test environments) |
allowedTrackingOrigins | MatchOption[] | — | Origins where the SDK is allowed to run (browser extension use) |
Session Replay & Privacy
| Option | Type | Default | Description |
|---|---|---|---|
sessionReplaySampleRate | number | 0 | Percentage of sessions to record (0–100) |
startSessionReplayRecordingManually | boolean | false if sessionReplaySampleRate > 0, else true | Start recording only when startSessionReplayRecording() is called |
defaultPrivacyLevel | 'mask' | 'mask-user-input' | 'allow' | 'mask' | Default text masking level for session replay |
enablePrivacyForActionName | boolean | false | Mask action names in session replay |
subdomain | string | — | Custom subdomain for session replay share links |
trackingConsent | 'granted' | 'not-granted' | 'granted' | Initial user tracking consent state |
defaultPrivacyLevel values
| Value | Behaviour |
|---|---|
'mask' | All text content and form inputs are replaced with xxx. Static and dynamic text is hidden. |
'mask-user-input' | Only form inputs (<input>, <textarea>, <select>) are masked. Static text is visible. |
'allow' | Nothing is masked. All content is recorded as-is. |
Override the privacy level on individual HTML elements using the data-ks-privacy attribute:
<!-- Force mask a specific element even when the global level is 'allow' -->
<div data-ks-privacy="mask">Card number: 4111 1111 1111 1111</div>
<!-- Allow a specific element even when the global level is 'mask' -->
<h1 data-ks-privacy="allow">Welcome to the Dashboard</h1>
<!-- Mask only user input within this container -->
<form data-ks-privacy="mask-user-input">
<input type="text" placeholder="Name" />
</form>Distributed Tracing
| Option | Type | Default | Description |
|---|---|---|---|
traceSampleRate | number | 100 | Percentage of requests to trace (0–100) |
traceContextInjection | 'sampled' | 'tracecontext' | 'sampled' | When to inject trace context into requests |
propagateTraceBaggage | boolean | false | Include user/account IDs in the W3C baggage header |
Performance & Transport
| Option | Type | Default | Description |
|---|---|---|---|
profilingSampleRate | number | 0 | Percentage of users to profile (0–100) |
compressIntakeRequests | boolean | false | Compress payloads sent to the intake (requires workerUrl) |
workerUrl | string | — | URL to the SDK Web Worker file (same origin required) |
proxy | string | function | — | Proxy URL or function to route SDK requests through a custom endpoint |
Session Persistence & Cookies
| Option | Type | Default | Description |
|---|---|---|---|
sessionPersistence | 'cookie' | 'local-storage' | 'cookie' | Storage strategy for sessions |
useSecureSessionCookie | boolean | false | Restrict session cookie to HTTPS connections only |
usePartitionedCrossSiteSessionCookie | boolean | false | Use a partitioned cross-site cookie — required when the SDK runs inside an iframe on another domain |
trackSessionAcrossSubdomains | boolean | false | Share the session across all subdomains of the same site |
storeContextsAcrossPages | boolean | false | Persist global context and user context in localStorage across page navigations |
note: sessionPersistence, useSecureSessionCookie, usePartitionedCrossSiteSessionCookie, and trackSessionAcrossSubdomains must be set to identical values if you use both the RUM and Logs SDKs on the same page.
Other Options
| Option | Type | Default | Description |
|---|---|---|---|
silentMultipleInit | boolean | false | Suppress the error when init() is called more than once on the same page |
firstPartyDomains — Detailed
By default, only the current page's hostname is classified as "first-party" in resource and trace attribution. Use firstPartyDomains to declare additional origins you own so they are correctly attributed instead of appearing as third-party.
Accepts strings (exact hostname), regular expressions, or functions:
kubesenseSdk.init({
// ...
firstPartyDomains: [
'api.myapp.com', // exact hostname
/\.myapp\.com$/, // all subdomains of myapp.com
(host) => host.endsWith('.internal'), // function — matches *.internal
],
})With this configuration, requests to api.myapp.com, cdn.myapp.com, or payments.internal are classified as first-party resources, and distributed trace headers are automatically injected if those origins also appear in allowedTracingUrls.
Callbacks & Plugins
| Option | Type | Description |
|---|---|---|
beforeSend | (event, context) => boolean | Inspect, modify, or discard events before sending. Return false to drop (not applicable to view events). |
plugins | RumPlugin[] | SDK plugin extensions |
beforeSend example — drop health-check errors
kubesenseSdk.init({
// ...
beforeSend: (event) => {
if (event.type === 'error' && event.error.message.includes('health-check')) {
return false // drop this event
}
return true
},
})beforeSend example — enrich resource events
kubesenseSdk.init({
// ...
beforeSend: (event) => {
if (event.type === 'resource' && event.resource.url.includes('/api/graphql')) {
event.context.graphql_operation = getGraphQlOperation(event.resource.url)
}
return true
},
})5. View Tracking
A view represents a page or screen the user is on. The SDK creates views automatically on URL changes. For Single-Page Apps with custom routing, you may want manual control.
Automatic (default)
Views are created automatically on every history.pushState or hashchange. No code needed.
Manual View Control (SPA)
Set trackViewsManually: true in init(), then call startView() on each route change.
// React Router example
import { useEffect } from 'react'
import { useLocation } from 'react-router-dom'
import { kubesenseSdk } from '@kubesense/kubesense-browser-rum'
function RouteTracker() {
const location = useLocation()
useEffect(() => {
kubesenseSdk.startView({ name: location.pathname })
}, [location])
return null
}// Vue Router example
router.afterEach((to) => {
kubesenseSdk.startView({ name: to.name ?? to.path })
})View API
// Start a new view with a name
kubesenseSdk.startView('checkout')
// Start with full options (name, service, version)
kubesenseSdk.startView({ name: 'checkout', service: 'payments', version: '2.1.0' })
// Change the name of the current view after it started
kubesenseSdk.setViewName('checkout-confirmation')
// Attach context to the current view only
kubesenseSdk.setViewContext({ cart_id: 'abc123', item_count: 3 })
kubesenseSdk.setViewContextProperty('experiment_variant', 'B')
// Read current view context
const ctx = kubesenseSdk.getViewContext()6. User Context
Attach user identity to all events. Call this after login or session restore.
// Set user (id is required)
kubesenseSdk.setUser({
id: 'usr-1234',
name: 'Jane Smith',
email: 'jane@example.com',
// Any custom properties:
plan: 'enterprise',
role: 'admin',
})
// Update a single property
kubesenseSdk.setUserProperty('plan', 'pro')
// Read current user
const user = kubesenseSdk.getUser()
// Remove a property
kubesenseSdk.removeUserProperty('role')
// Clear on logout
kubesenseSdk.clearUser()note: Calling setUser() with a different id automatically expires the current session to prevent cross-user data contamination on shared devices.
7. Account Context
Attach account/organization information to all events (useful for B2B applications).
kubesenseSdk.setAccount({
id: 'acct-5678',
name: 'Acme Corp',
plan: 'enterprise',
})
// Update a single property
kubesenseSdk.setAccountProperty('plan', 'enterprise-plus')
// Read current account
const account = kubesenseSdk.getAccount()
// Remove a property
kubesenseSdk.removeAccountProperty('plan')
// Clear
kubesenseSdk.clearAccount()8. Error Tracking
Automatic Error Collection
The SDK automatically captures:
- Unhandled JavaScript exceptions (
window.onerror) - Unhandled promise rejections
- Console errors (
console.error) - Network errors (for tracked resource URLs)
No code needed for these.
Manual Error Reporting
Report handled errors you catch yourself:
try {
processPayment(order)
} catch (error) {
kubesenseSdk.addError(error, {
order_id: order.id,
amount: order.total,
})
}// Report a plain string
kubesenseSdk.addError('Payment failed: insufficient funds', {
user_id: currentUser.id,
})React Error Boundary
import { Component } from 'react'
import { kubesenseSdk } from '@kubesense/kubesense-browser-rum'
class ErrorBoundary extends Component {
componentDidCatch(error: Error, info: React.ErrorInfo) {
kubesenseSdk.addError(error, {
component_stack: info.componentStack,
})
}
render() {
return this.props.children
}
}9. Action Tracking
Automatic Action Collection
When trackUserInteractions: true (default), the SDK automatically tracks clicks and names them from:
- The element's
data-action-nameattribute (configure viaactionNameAttribute) - The element's
aria-label,title, oraltattribute - The element's inner text (truncated)
Custom Actions
// Track a programmatic or non-click action
kubesenseSdk.addAction('export_csv', {
row_count: 1500,
format: 'csv',
})
kubesenseSdk.addAction('search', {
query: searchTerm,
results_count: results.length,
})Naming Clicks via HTML Attribute
<!-- Using default attribute (data-action-name) -->
<button data-action-name="Add to cart">+</button>
<!-- Using a custom attribute configured at init -->
<!-- kubesenseSdk.init({ actionNameAttribute: 'data-rum-action' }) -->
<button data-rum-action="checkout">Buy Now</button>10. Resource & Long Task Tracking
Both are enabled by default. No code needed.
kubesenseSdk.init({
trackResources: true, // default: true
trackLongTasks: true, // default: true
})To stop collecting resources or long tasks entirely:
kubesenseSdk.init({
trackResources: false,
trackLongTasks: false,
})11. Custom Timings & Performance Vitals
Custom View Timings
Mark key moments within the current view (e.g. "time to data loaded"):
// After data is fetched and rendered
kubesenseSdk.addTiming('data_ready')
// Pass an explicit timestamp (ms since page load)
kubesenseSdk.addTiming('hero_image_loaded', performance.now())Timings appear in the view event under view.custom_timings.
Duration Vitals
Measure elapsed time for arbitrary operations:
// Option 1: start / stop
const ref = kubesenseSdk.startDurationVital('checkout_flow')
// ... user completes checkout ...
kubesenseSdk.stopDurationVital(ref, {
context: { steps_completed: 4 },
})
// Option 2: start by name and stop by name
kubesenseSdk.startDurationVital('report_generation')
generateReport().then(() => {
kubesenseSdk.stopDurationVital('report_generation')
})
// Option 3: add a completed vital with known start/duration
kubesenseSdk.addDurationVital('pdf_render', {
startTime: renderStartTime,
duration: renderDuration,
context: { page_count: 12 },
})12. Feature Operations
Track multi-step operations (e.g. checkout flows, onboarding) as a series of steps with pass/fail outcomes.
// Start tracking a named operation
kubesenseSdk.startFeatureOperation('onboarding', {
context: { step: 'profile_setup' },
})
// Mark succeeded
kubesenseSdk.succeedFeatureOperation('onboarding', {
context: { steps_completed: 3 },
})
// Mark failed with a reason
kubesenseSdk.failFeatureOperation('onboarding', 'profile_incomplete', {
context: { missing_fields: ['phone'] },
})13. Global Context
Attach custom properties to every event (views, errors, resources, actions).
// Set at startup
kubesenseSdk.setGlobalContext({
deployment_region: 'us-east-1',
feature_set: 'beta',
})
// Add or update a single property at any time
kubesenseSdk.setGlobalContextProperty('ab_test_group', 'variant_B')
// Read current context
const ctx = kubesenseSdk.getGlobalContext()
// Remove one property
kubesenseSdk.removeGlobalContextProperty('feature_set')
// Clear everything
kubesenseSdk.clearGlobalContext()14. Session Replay
Session Replay records the user's screen so you can replay exactly what happened around an error or frustration signal.
Enable Replay
kubesenseSdk.init({
// ...
sessionReplaySampleRate: 20, // record 20% of sessions
})Manual Recording Control
kubesenseSdk.init({
// ...
sessionReplaySampleRate: 100,
startSessionReplayRecordingManually: true, // don't start automatically
})
// Start recording only for important flows (e.g. after login)
function onUserLoggedIn() {
kubesenseSdk.startSessionReplayRecording()
}
// Stop recording when leaving a sensitive screen
function onEnterPaymentPage() {
kubesenseSdk.stopSessionReplayRecording()
}Privacy Masking
kubesenseSdk.init({
defaultPrivacyLevel: 'mask-user-input', // 'mask' | 'mask-user-input' | 'allow'
})| Level | Behaviour |
|---|---|
mask | All text and inputs are masked (default) |
mask-user-input | Only form inputs are masked; static text is visible |
allow | Nothing is masked |
Override per element:
<!-- Force masking an element -->
<div data-ks-privacy="mask">Sensitive data</div>
<!-- Allow a specific element in a masked view -->
<p data-ks-privacy="allow">Public content</p>Get Replay Link
const replayUrl = kubesenseSdk.getSessionReplayLink()
// Share or store this URL to view the recording later15. Distributed Tracing
Correlate frontend RUM events with backend traces by injecting trace headers into outgoing requests.
kubesenseSdk.init({
// ...
allowedTracingUrls: [
'https://api.example.com', // exact origin
/https:\/\/.*\.example\.com/, // regex
(url) => url.startsWith('https://api.'), // function
],
traceSampleRate: 100, // trace 100% of allowed requests
})Custom Propagator Format
kubesenseSdk.init({
allowedTracingUrls: [
{
match: 'https://api.example.com',
propagatorTypes: ['tracecontext', 'kubesense'], // W3C + Kubesense headers
},
],
})Propagate User/Account in Baggage
kubesenseSdk.init({
propagateTraceBaggage: true, // includes user.id and account.id in the baggage header
})16. Privacy & Consent
Tracking Consent
If you require explicit consent before collecting data (e.g. GDPR):
kubesenseSdk.init({
// ...
trackingConsent: 'not-granted', // start with no collection
})
// After user accepts your consent banner:
kubesenseSdk.setTrackingConsent('granted')
// If user withdraws consent:
kubesenseSdk.setTrackingConsent('not-granted')Stop a Session
kubesenseSdk.stopSession()
// No new events collected until next page load or user activity17. Feature Flag Tracking
Track which feature flags were evaluated during a session or action:
// After evaluating a flag
const flagValue = featureFlags.get('new_checkout')
kubesenseSdk.addFeatureFlagEvaluation('new_checkout', flagValue)To attach flag evaluations to specific event types, configure at init:
kubesenseSdk.init({
trackFeatureFlagsForEvents: ['action', 'vital', 'long_task', 'resource'],
})18. GraphQL Tracking
Track GraphQL requests with operation metadata:
kubesenseSdk.init({
allowedGraphQlUrls: [
{
match: 'https://api.example.com/graphql',
trackPayload: false, // don't capture request body
trackResponseErrors: true, // capture GraphQL errors in response
},
],
})19. TypeScript Support
The SDK ships full TypeScript types. Import them directly:
import type {
RumInitConfiguration,
RumEvent,
RumEventDomainContext,
} from '@kubesense/kubesense-browser-rum'
const config: RumInitConfiguration = {
applicationId: '<YOUR_APPLICATION_ID>',
clientToken: '<YOUR_CLIENT_TOKEN>',
service: 'my-app',
env: 'production',
beforeSend: (event: RumEvent, context: RumEventDomainContext): boolean => {
// type-safe access to event fields
return true
},
}20. Core Web Vitals
The SDK automatically collects Core Web Vitals metrics defined by Google. These metrics help you understand real-world user experience.
Automatically Collected Vitals
| Vital | Description | Good | Needs Improvement | Poor |
|---|---|---|---|---|
| LCP | Largest Contentful Paint - time to render largest content | < 2.5s | 2.5s - 4s | > 4s |
| FID | First Input Delay - time to respond to first interaction | < 100ms | 100ms - 300ms | > 300ms |
| INP | Interaction to Next Paint - response to all interactions | < 200ms | 200ms - 500ms | > 500ms |
| CLS | Cumulative Layout Shift - visual stability | < 0.1 | 0.1 - 0.25 | > 0.25 |
| FCP | First Contentful Paint - time to first content | < 1.8s | 1.8s - 3s | > 3s |
| TTFB | Time to First Byte - server response time | < 800ms | 800ms - 1800ms | > 1800ms |
Custom Vitals
Track your own performance metrics:
// Add custom timing
kubesenseSdk.addTiming('data_loaded', performance.now())
// Or use duration vitals for complex measurements
const vitalRef = kubesenseSdk.startDurationVital('checkout_flow')
// ... user completes checkout ...
kubesenseSdk.stopDurationVital(ref, { context: { steps_completed: 5 } })21. Performance & Bundle Size
Bundle Sizes
| Package | Size (gzip) | Features |
|---|---|---|
@kubesense/kubesense-browser-rum | ~45KB | Full RUM + Session Replay + Profiling |
@kubesense/kubesense-browser-rum-slim | ~25KB | RUM only (no replay) |
@kubesense/kubesense-browser-logs | ~15KB | Log collection |
@kubesense/kubesense-browser-rum-react | ~5KB | React integration |
Lazy Loading Session Replay
Session Replay code is loaded on-demand to reduce initial bundle size. The replay recorder module (~20KB) is only loaded when:
sessionReplaySampleRate > 0AND recording startsstartSessionReplayRecording()is called
Optimizing Performance
kubesenseSdk.init({
sessionSampleRate: 100, // Adjust based on needs
sessionReplaySampleRate: 10, // 10% - replay is expensive
traceSampleRate: 20, // 20% - tracing adds overhead
trackResources: false, // Disable if not needed
defaultPrivacyLevel: 'mask-user-input', // Faster than 'mask'
})22. Troubleshooting
Enable Debug Mode
// Before init - enable console debugging
window.KUBESENSE_SDK_DEBUG = 'true'
kubesenseSdk.init({ ... })Check SDK Status
// Get internal context (current session, view, user)
const context = kubesenseSdk.getInternalContext()
console.log(context)
// Get initialization config
const config = kubesenseSdk.getInitConfiguration()
console.log(config)Common Issues
No data appearing in dashboard:
- Verify
applicationIdandclientTokenare correct - Check browser console for errors
- Confirm
kubesenseRumEndpointmatches your Kubesense instance
Session Replay not working:
- Ensure
sessionReplaySampleRate > 0 - Browser supports Session Replay (not IE, not incognito)
- Check for CSP restrictions blocking worker
High memory usage:
- Reduce
sessionReplaySampleRate - Disable
trackResourcesif not needed
23. Route-Based Session Replay
Record only specific pages based on route patterns:
// Initialize with manual start
kubesenseSdk.init({
startSessionReplayRecordingManually: true,
})
// Define routes to record
const routesToRecord = ['/checkout', '/payment', '/cart', '/dashboard']
// Update recording state based on route
function updateSessionReplay() {
const shouldRecord = routesToRecord.some(route =>
window.location.pathname.startsWith(route)
)
if (shouldRecord) {
kubesenseSdk.startSessionReplayRecording()
} else {
kubesenseSdk.stopSessionReplayRecording()
}
}
updateSessionReplay()
window.addEventListener('popstate', updateSessionReplay)React Router
useEffect(() => {
const shouldRecord = routesToRecord.some(route =>
location.pathname.startsWith(route)
)
if (shouldRecord) {
kubesenseSdk.startSessionReplayRecording()
} else {
kubesenseSdk.stopSessionReplayRecording()
}
}, [location.pathname])24. Geolocation (User Location)
Get accurate user location instead of IP-based GeoIP. Requires user permission.
import { getCurrentPosition, canUseGeoLocation } from '@kubesense/kubesense-browser-core'
if (canUseGeoLocation()) {
getCurrentPosition((position) => {
kubesenseSdk.setGlobalContextProperty('geo', {
latitude: position.latitude,
longitude: position.longitude,
accuracy: position.accuracy,
})
})
}Reverse Geocoding (Location Names)
Convert coordinates to location names:
import { getCurrentPosition, reverseGeocodeWithPosition, canUseGeoLocation } from '@kubesense/kubesense-browser-core'
if (canUseGeoLocation()) {
getCurrentPosition((position) => {
reverseGeocodeWithPosition(position, (result) => {
console.log(result.city) // "San Francisco"
console.log(result.state) // "California"
console.log(result.country) // "United States of America"
})
})
}25. Custom Events
Track custom business events beyond built-in RUM collection:
// Custom action
kubesenseSdk.addAction('checkout_completed', { cartValue: 99, currency: 'USD' })
// Custom error
kubesenseSdk.addError(new Error('Payment failed'), { source: 'checkout' })
// View context (attached only to current view)
kubesenseSdk.setViewContext({ order_id: '12345' })Quick Reference
// Initialization
kubesenseSdk.init({ applicationId, clientToken, /* ... */ })
// Views
kubesenseSdk.startView(name)
kubesenseSdk.setViewName(name)
kubesenseSdk.setViewContext(context)
kubesenseSdk.setViewContextProperty(key, value)
// User & Account
kubesenseSdk.setUser({ id, name, email, /* ...custom */ })
kubesenseSdk.clearUser()
kubesenseSdk.setAccount({ id, name, /* ...custom */ })
kubesenseSdk.clearAccount()
// Global Context
kubesenseSdk.setGlobalContext(context)
kubesenseSdk.setGlobalContextProperty(key, value)
kubesenseSdk.clearGlobalContext()
// Errors & Actions
kubesenseSdk.addError(error, context)
kubesenseSdk.addAction(name, context)
// Timings & Vitals
kubesenseSdk.addTiming(name)
kubesenseSdk.startDurationVital(name)
kubesenseSdk.stopDurationVital(nameOrRef)
// Session Replay
kubesenseSdk.startSessionReplayRecording()
kubesenseSdk.stopSessionReplayRecording()
kubesenseSdk.getSessionReplayLink()
// Consent
kubesenseSdk.setTrackingConsent('granted' | 'not-granted')
kubesenseSdk.stopSession()