JavaScript (Web)
Official JavaScript SDK for Rybbit Analytics
Installation
npm install @rybbit/jsyarn add @rybbit/jsPeer Dependencies
The SDK has an optional peer dependency for session replay functionality:
npm install rrwebyarn add rrwebThe rrweb package is only required if you enable session replay in your Rybbit dashboard. The SDK will work without it for all other tracking features.
Initialization
rybbit.init() must be called once before any other tracking methods (pageview, event, etc.) can be used. Attempting to call other methods before init will result in errors or no tracking.
Syntax
async rybbit.init(config: RybbitConfig): Promise<void>;Example
import rybbit from "@rybbit/js";
await rybbit.init({
analyticsHost: "https://app.rybbit.io/api",
siteId: "1",
});Configuration Options
Required Options
| Option | Type | Description |
|---|---|---|
analyticsHost | string | URL of your Rybbit analytics instance (e.g., https://rybbit.yourdomain.com/api). |
siteId | string | The Site ID for your website obtained from your Rybbit instance. |
Local Configuration Options
These options are configured in your code and control SDK behavior locally:
| Option | Type | Default | Description |
|---|---|---|---|
debounceDuration | number | 500 | Debounce time in milliseconds for tracking pageviews after route changes. Set to 0 to disable debouncing (track immediately). |
skipPatterns | string[] | [] | Array of path patterns. Pageviews whose path matches any pattern will not be tracked. See Path Matching. |
maskPatterns | string[] | [] | Array of path patterns. For matching pageview paths, the original path will be replaced by the pattern itself in tracked data. See Path Matching. |
debug | boolean | false | Enable detailed logging to the browser console. |
replayPrivacyConfig | object | - | Privacy settings for session replay. See Session Replay. |
Remote Configuration
These settings are controlled through your Rybbit dashboard and cannot be set in the init config:
| Dashboard Setting | Description | Default |
|---|---|---|
| Track Initial Pageview | Track pageview on initial page load | true |
| Track SPA Navigation | Track pageviews on Single Page Application route changes | true |
| Track URL Parameters | Include URL query strings in tracked data | true |
| Track Outbound Links | Automatically track clicks on external links | true |
| Track Web Vitals | Track Core Web Vitals performance metrics | false |
| Capture Errors | Enable automatic error tracking | false |
| Session Replay | Enable session replay recording | false |
| Track Button Clicks | Automatically track button click interactions | false |
| Track Copy | Automatically track copy events | false |
| Track Form Interactions | Automatically track form submissions and input changes | false |
If fetching settings fails or times out, the SDK uses sensible defaults.
Tracking Pageviews
Pageviews are tracked automatically based on your dashboard settings. This includes the initial page load and subsequent route changes in Single Page Applications (SPAs).
Syntax
rybbit.pageview(path?: string);Parameters
path(string, Optional):- Replaces the detected URL path (
window.location.pathname) and query string (window.location.search) for this specific pageview event. - Should start with a
/(e.g.,/virtual/my-custom-page). - If
pathincludes its own query string (e.g.,/virtual/step?id=123), that query string will be used for the event. Ifpathhas no query string, thequerystringproperty will be empty. skipPatternsandmaskPatternswill be applied topath.
- Replaces the detected URL path (
When to Use Manually
- Automatic tracking disabled: If you disabled automatic pageview tracking in your dashboard.
- Virtual Pageviews: In SPAs where a significant view change occurs without a URL change.
- Specific Timing: If you need to ensure a pageview is tracked only after certain conditions are met.
Example
// Standard manual pageview (usually not needed if auto-tracking is on)
rybbit.pageview();
// Example: Track a step within a multi-step modal
function openUserDetailsModal(userId, step) {
// ... logic to open and display the modal step ...
rybbit.pageview(`/users/${userId}/modal/${step}`);
}
openUserDetailsModal("user-abc", "contact-info");
// Example: Track a virtual pageview with its own query parameters
function showFilteredProductList(category, sortBy) {
let virtualPathWithQuery = `/products/category/${category}?sort=${sortBy}&view=grid`;
rybbit.pageview(virtualPathWithQuery);
}
showFilteredProductList("electronics", "price_desc");Tracking Custom Events
Use custom events to track specific user interactions. Examples include button clicks, form submissions, or adding an item to a cart.
Programmatic Tracking
You can trigger events from your JavaScript code.
Syntax
rybbit.event(name: string, properties?: TrackProperties);Parameters
name(string, Required): The name of the event you want to track.properties(object, Optional): An object containing additional key-value pairs related to the event. Values can be astring,number,boolean, or an array of these types.
Example
// Track a simple button click
document.getElementById("cta-button")?.addEventListener("click", () => {
rybbit.event("cta_click");
});
// Track adding an item to a shopping cart with properties
function addToCart(item) {
// ... add item ...
rybbit.event("add_to_cart", {
itemId: item.id,
itemName: item.name,
price: item.price,
quantity: 1
});
}Declarative Tracking with Data Attributes
The SDK automatically listens for clicks on elements with the data-rybbit-event attribute.
data-rybbit-event="<event-name>": This attribute makes the element trackable. The value is used as the event name.data-rybbit-prop-<property-name>="<value>": You can add multiple properties to the event by using this attribute format. The SDK collects all attributes starting withdata-rybbit-prop-and includes them as key-value pairs in the event data.
Example
<button data-rybbit-event="cta_click">Click Me</button>
<button
data-rybbit-event="add_to_cart"
data-rybbit-prop-item_id="product-123"
data-rybbit-prop-item_name="Classic T-Shirt"
data-rybbit-prop-price="29.99"
>
Add to Cart
</button>Tracking Outbound Links
Outbound links (links to external domains) are tracked automatically by default based on your dashboard settings. The SDK attaches a global click listener to capture clicks on <a> tags with external href attributes.
Syntax
rybbit.trackOutbound(url: string, text?: string, target?: string);Parameters
url(string, Required): The destination URL of the outbound link.text(string, Optional): The text content of the link. Defaults to"".target(string, Optional): Thetargetattribute of the link (e.g.,_blank). Defaults to_self.
When to Use Manually
- Automatic tracking disabled: If you disabled outbound link tracking in your dashboard.
- Non-anchor elements: If you trigger navigation to an external site using JavaScript from an element that isn't an
<a>tag.
Example
// Manually track an outbound click triggered by a button
document.getElementById("external-service-button")?.addEventListener("click", () => {
let url = "https://external-service.com";
rybbit.trackOutbound(url, "Visit External Service", "_blank");
// Optionally navigate after tracking
window.open(url, "_blank");
});Error Tracking
The SDK can automatically capture JavaScript errors and unhandled promise rejections. This feature must be enabled in your Rybbit dashboard.
Automatic Error Capture
When enabled in your dashboard, the SDK will automatically track:
- Uncaught exceptions (
window.errorevents) - Unhandled promise rejections (
window.unhandledrejectionevents)
Manual Error Capture
You can manually capture errors with additional context:
Syntax
rybbit.error(error: Error | ErrorEvent, context?: TrackProperties);Parameters
error(Error | ErrorEvent, Required): The error object to capture.context(object, Optional): Additional context to include with the error.
Example
try {
// Some risky operation
processPayment(orderData);
} catch (error) {
rybbit.error(error, {
component: "checkout",
orderId: "order-123",
userId: currentUser.id
});
// Handle error in your UI
showErrorMessage("Payment failed");
}
// Capture error from async operation
async function fetchUserData(userId) {
try {
const response = await fetch(`/api/users/${userId}`);
return await response.json();
} catch (error) {
rybbit.error(error, {
endpoint: "/api/users",
userId: userId
});
throw error;
}
}Manual error capture only works when error tracking is enabled in your dashboard settings. If it's disabled, calling error() will log a warning.
Session Replay
Session replay records user interactions on your website, allowing you to watch how users navigate and interact with your site. This feature requires the rrweb peer dependency.
Installation
npm install rrwebEnabling Session Replay
Session replay must be enabled in your Rybbit dashboard under. Once enabled, recording starts automatically when the SDK initializes.
Manual Controls
You can manually start, stop, and check the status of session replay:
// Start recording (only works if enabled in dashboard)
rybbit.startSessionReplay();
// Stop recording
rybbit.stopSessionReplay();
// Check if currently recording
const isRecording = rybbit.isSessionReplayActive();
if (isRecording) {
console.log("Session is being recorded");
}Privacy Configuration
Session replay includes privacy-focused defaults and configuration options:
await rybbit.init({
analyticsHost: "https://app.rybbit.io/api",
siteId: "1",
replayPrivacyConfig: {
maskAllInputs: true, // Mask all input values (default: true)
maskTextSelectors: [
".sensitive-data", // Mask text in elements with this class
"#credit-card" // Mask specific element IDs
]
}
});Privacy Config Options
| Option | Type | Description |
|---|---|---|
maskAllInputs | boolean | Mask all input values (default: true) |
maskTextSelectors | string[] | CSS selectors for elements whose text should be masked |
blockClass | string | CSS class name to block elements from recording (default: rr-block) |
blockSelector | string | CSS selector to block elements from recording |
ignoreClass | string | CSS class name to ignore elements from recording (default: rr-ignore) |
ignoreSelector | string | CSS selector to ignore elements from recording |
maskTextClass | string | CSS class name to mask text content (default: rr-mask) |
collectFonts | boolean | Whether to collect font information (default: true) |
slimDOMOptions | object | boolean | Options to reduce DOM snapshot size |
User Identification
You can associate tracking events with a specific user ID and optional traits. The ID is persisted in localStorage and will be attached to all subsequent tracking events for that user.
identify
Assigns a user ID with optional traits.
rybbit.identify(userId: string, traits?: Record<string, unknown>);Parameters:
userId(string, Required): The user ID to associate with tracking events.traits(object, Optional): An object containing user attributes/properties.
Example:
// After a user logs in
rybbit.identify("user-xzy-123");
// With traits
rybbit.identify("user-xzy-123", {
email: "user@example.com",
plan: "premium",
signupDate: "2024-01-15"
});setTraits
Updates traits for the currently identified user without changing the user ID.
rybbit.setTraits(traits: Record<string, unknown>);Example:
// Update user traits after they upgrade
rybbit.setTraits({
plan: "enterprise",
upgradeDate: "2024-03-01"
});clearUserId
Clears the stored user ID.
rybbit.clearUserId();Example:
// When a user logs out
rybbit.clearUserId();getUserId
Retrieves the currently stored user ID.
rybbit.getUserId(): string | null;Example:
let currentUserId = rybbit.getUserId();
console.log("Current Rybbit User ID:", currentUserId);Page Change Callbacks
Register callbacks that execute when the page or route changes. This is useful for integrating with third-party tools or triggering custom logic on navigation.
Syntax
rybbit.onPageChange(callback: (newPath: string, previousPath: string) => void): () => void;Parameters
callback(function, Required): Function to execute on page change. Receives:newPath: The new pathnamepreviousPath: The previous pathname
Returns
Returns an unsubscribe function to remove the callback.
Example
// Register a callback
const unsubscribe = rybbit.onPageChange((newPath, previousPath) => {
console.log(`Navigated from ${previousPath} to ${newPath}`);
// Example: Track scroll position reset
window.scrollTo(0, 0);
});
// Later, to remove the callback
unsubscribe();
// Example: Multiple callbacks can be registered
rybbit.onPageChange((newPath) => {
// Update page title
document.title = `${newPath} - My Site`;
});
rybbit.onPageChange((newPath, previousPath) => {
// Log navigation for debugging
if (process.env.NODE_ENV === 'development') {
console.log('Navigation:', { from: previousPath, to: newPath });
}
});Callbacks are only triggered when the pathname actually changes. Multiple calls to the same path won't trigger callbacks repeatedly.
Opting Out
Users can opt out of all tracking by setting a flag in localStorage or on the window object. When opted out, all tracking calls are silently ignored.
// Opt out via localStorage (persists across sessions)
localStorage.setItem("disable-rybbit", "true");
// Opt out via window flag (current session only)
window.__RYBBIT_OPTOUT__ = true;To re-enable tracking, remove the localStorage item and reload the page:
localStorage.removeItem("disable-rybbit");Cleanup
In Single Page Applications or other dynamic environments, you may need to manually clean up the listeners that the SDK sets up.
Syntax
rybbit.cleanup();What Gets Cleaned Up
- SPA route change listeners (
popstate,hashchange) - Outbound link click listeners
- Data attribute click listeners
- Error tracking listeners
- Session replay recording
- Page change callbacks
- Resets initialization state
Example
// In React
useEffect(() => {
rybbit.init({
analyticsHost: "https://app.rybbit.io/api",
siteId: "1",
});
return () => {
rybbit.cleanup();
};
}, []);Path Matching
These options allow you to control which page paths are tracked and how they appear in your analytics data using wildcard patterns.
Wildcards
*: Matches any sequence of characters except the forward slash (/). Useful for matching single path segments.**: Matches any sequence of characters including the forward slash (/). Useful for matching multiple path segments.
Regex Patterns
For more advanced matching, you can use raw regular expressions by prefixing the pattern with re::
skipPatterns: [
"re:^/users/\\d+/profile$", // Match numeric user IDs only
"re:^/api/v[0-9]+/" // Match any API version prefix
]skipPatterns
If a page's path matches any pattern in skipPatterns, the pageview for that path will not be sent.
Examples:
"/admin/*": Skips/admin/login,/admin/users, but not/admin/settings/profile."/admin/**": Skips/admin/login,/admin/users, and/admin/settings/profile."/users/*/profile": Skips/users/123/profile,/users/abc/profile, but not/users/123/settings.
// Example skipPatterns in init
await rybbit.init({
// ... other options
skipPatterns: [
"/admin/**", // Skip all admin sections
"/debug", // Skip exact /debug path
"/users/*/settings" // Skip settings page for any user
]
});maskPatterns
If a page's path matches a pattern in maskPatterns, the pageview will be sent, but the pathname will be replaced by the pattern string itself. This is useful for grouping similar pages or hiding sensitive IDs.
If a path matches both a skipPatterns and a maskPatterns pattern, skipping takes priority.
Examples:
- Pattern:
"/users/*/profile"/users/123/profileis tracked aspathname: "/users/*/profile".
- Pattern:
"/products/**"/products/electronics/tv-123is tracked aspathname: "/products/**".
// Example maskPatterns in init
await rybbit.init({
// ... other options
maskPatterns: [
"/users/*/profile", // Group all user profile views
"/orders/*" // Mask specific order IDs
]
});