Ahoy.js
Ahoy.js is a client-side JavaScript analytics library designed for simple and powerful visit and event tracking. It currently stands at version 0.4.5 and is actively maintained, though a specific release cadence isn't defined. The library's core function is to capture user interactions, such as unique visits, page views, clicks, submits, and custom events, sending this raw data via `POST` requests to a configurable backend endpoint. A key differentiator is its backend-agnostic design, allowing developers to integrate it with any server-side technology, including a dedicated Ruby gem for Rails applications. It automatically manages visit and visitor tokens (expiring after 4 hours and 2 years, respectively) and provides comprehensive data points like referrer, landing page, and event properties, which can be further enriched on the server with IP, user agent, and authentication details. The library also offers robust configuration options for URL endpoints, cookie management, cross-domain tracking, and debug logging.
Common errors
-
POST https://yourdomain.com/ahoy/visits net::ERR_CONNECTION_REFUSED
cause The configured `visitsUrl` or `eventsUrl` does not point to an accessible or running backend service, or a network issue is preventing connection.fixVerify that your backend server is running and accessible at the specified URL paths (`/ahoy/visits` and `/ahoy/events` by default). Check for firewall rules, DNS resolution, and correct `urlPrefix` configuration. -
Failed to load resource: the server responded with a status of 404 (Not Found)
cause Your backend application does not have the necessary routes defined to handle `POST` requests to the `/ahoy/visits` or `/ahoy/events` endpoints.fixEnsure your server-side framework (e.g., Rails, Express.js, etc.) has routes configured to accept `POST` requests at the URLs specified in `ahoy.configure()` and that these routes lead to appropriate controllers or handlers. -
Analytics data is recorded, but user-specific information (like `user_id`) is missing in the backend.
cause The server-side application is not correctly capturing the authenticated user from the request, or `withCredentials` is not enabled for cross-origin requests, preventing session cookies from being sent.fixOn the server, confirm that the authenticated user's ID is being extracted from the request (e.g., from a session, JWT, or other authentication mechanism). If operating across different domains/subdomains, ensure `ahoy.configure({ withCredentials: true });` is set on the client, and your server is configured for CORS with credentials.
Warnings
- deprecated The `ahoy.trackChanges()` method is deprecated and should no longer be used for tracking input field changes.
- gotcha Ahoy.js is a client-side library and requires a backend server to receive, process, and store analytics data. It is not a standalone analytics solution.
- gotcha When tracking user activity across multiple subdomains (e.g., `www.example.com` and `blog.example.com`), the `cookieDomain` configuration must be explicitly set to the top-level domain.
- gotcha If your Ahoy.js client is hosted on a different domain or subdomain than your analytics backend, and you rely on cookies for user authentication, `withCredentials` must be set to `true`.
- gotcha Ahoy.js sends event `time` from the client. The server *must* validate this timestamp to prevent clients from sending manipulated or fraudulent historical/future events.
Install
-
npm install ahoy.js -
yarn add ahoy.js -
pnpm add ahoy.js
Imports
- ahoy
const ahoy = require('ahoy.js');import ahoy from 'ahoy.js';
- ahoy
<script src="path/to/ahoy.js"></script> <script> ahoy.track('Page Load'); </script>
Quickstart
ahoy.configure({
cookieDomain: "example.com", // Use for tracking across subdomains (e.g., app.example.com, blog.example.com)
withCredentials: true, // Essential for sending cookies across different domains/subdomains for authentication
visitsUrl: "/api/analytics/visits", // Customize endpoint for visit tracking
eventsUrl: "/api/analytics/events" // Customize endpoint for event tracking
});
// Enable debug logging in the browser console
ahoy.debug();
// Track a custom event with properties
ahoy.track("Product Viewed", {
productId: "SKU123",
category: "Electronics",
price: 499.99
});
// Track a page view, automatically capturing URL and title
ahoy.trackView();
// Track clicks on specific CSS selectors
ahoy.trackClicks(".add-to-cart-button, #checkout-link");
// Track form submissions on specific CSS selectors
ahoy.trackSubmits("#newsletter-signup-form");
// To force a new visit for testing (requires page reload)
// ahoy.reset();
// window.location.reload();