Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
search-insights
Advanced tools
Library for reporting click, conversion and view metrics using the Algolia Insights API
The search-insights npm package is a JavaScript library that allows you to send analytics events to Algolia's Insights API. It helps you track user interactions with your search and discovery experiences, such as clicks, conversions, and view events.
Sending Click Events
This feature allows you to send click events to Algolia's Insights API. You can track which products users are clicking on after performing a search.
const searchInsights = require('search-insights');
searchInsights('init', { apiKey: 'yourAPIKey', appId: 'yourAppId' });
searchInsights('clickedObjectIDsAfterSearch', {
eventName: 'Product Clicked',
index: 'yourIndexName',
queryID: 'theQueryID',
objectIDs: ['objectID1', 'objectID2'],
positions: [1, 2]
});
Sending Conversion Events
This feature allows you to send conversion events to Algolia's Insights API. You can track which products users are purchasing after performing a search.
const searchInsights = require('search-insights');
searchInsights('init', { apiKey: 'yourAPIKey', appId: 'yourAppId' });
searchInsights('convertedObjectIDsAfterSearch', {
eventName: 'Product Purchased',
index: 'yourIndexName',
queryID: 'theQueryID',
objectIDs: ['objectID1', 'objectID2']
});
Sending View Events
This feature allows you to send view events to Algolia's Insights API. You can track which products users are viewing.
const searchInsights = require('search-insights');
searchInsights('init', { apiKey: 'yourAPIKey', appId: 'yourAppId' });
searchInsights('viewedObjectIDs', {
eventName: 'Product Viewed',
index: 'yourIndexName',
objectIDs: ['objectID1', 'objectID2']
});
Segment is a customer data platform that helps you collect, clean, and control your customer data. It provides a unified API to track user interactions and send them to various analytics services. Compared to search-insights, Segment offers a broader range of integrations and data management capabilities.
Mixpanel is an advanced analytics platform that helps you track user interactions with your web and mobile applications. It provides detailed insights into user behavior and allows you to create custom reports. Mixpanel is more focused on in-depth analytics and user behavior tracking compared to the more search-focused search-insights.
Google Analytics is a widely-used web analytics service that tracks and reports website traffic. It provides comprehensive insights into user behavior, traffic sources, and conversion rates. While Google Analytics offers a broader range of analytics features, search-insights is specifically tailored for tracking search-related events.
Search Insights lets you report click, conversion and view metrics using the Algolia Insights API.
You're looking at the documentation of search-insights
v2, which is the new major version. (Click here for v1.x documentation.)
v2 introduces a breaking change which is useCookie
being false
by default. If it's false
, search-insights
doesn't generate anonymous userToken. It means no event will be sent until setUserToken
is explicitly called.
Since v2.0.4, search-insights no longer validates event payloads. You can visit https://algolia.com/events/debugger instead.
Are you using Google Tag Manager in your app? We provide a custom template to ease the integration.
The Search Insights library can be either loaded via jsDelivr CDN or directly bundled with your application. We recommend loading the library by adding the snippet below to all pages where you wish to track search analytics.
<script>
var ALGOLIA_INSIGHTS_SRC = "https://cdn.jsdelivr.net/npm/search-insights@2.7.0";
!function(e,a,t,n,s,i,c){e.AlgoliaAnalyticsObject=s,e[s]=e[s]||function(){
(e[s].queue=e[s].queue||[]).push(arguments)},e[s].version=(n.match(/@([^\/]+)\/?/) || [])[1],i=a.createElement(t),c=a.getElementsByTagName(t)[0],
i.async=1,i.src=n,c.parentNode.insertBefore(i,c)
}(window,document,"script",ALGOLIA_INSIGHTS_SRC,"aa");
</script>
Initializing the library is optional, as you can specify the credentials for each event when sending them. This gives you the flexibility to manage your Algolia credentials on a per-event basis, without having to configure them upfront.
// Optional: configure default Algolia credentials for events
aa('init', {
appId: 'APP_ID',
apiKey: 'SEARCH_API_KEY',
});
// Optional: set the analytics user ID
aa('setUserToken', 'USER_ID');
Option | Type | Default | Description |
---|---|---|---|
appId | string | None | The identifier of your Algolia application. |
apiKey | string | None | The search API key of your Algolia application. |
userHasOptedOut | boolean | false | Whether to exclude users from analytics. |
region | 'de' | 'us' | Automatic | The DNS server to target. |
host | string | None | The URL to route requests through before they're forwarded to Algolia. |
useCookie | boolean | false | Whether to use cookie in browser environment. The anonymous user token will not be set if false . When useCookie is false and setUserToken is not called yet, sending events will throw errors because there is no user token to attach to the events. |
cookieDuration | number | 15552000000 (6 months) | The cookie duration in milliseconds. |
userToken | string | undefined (optional) | Initial userToken. When given, anonymous userToken will not be set. |
partial | boolean | false | Whether to preserve previously passed options without redeclaring them. |
To update the client with new options, you can call init
again.
By default, all previously passed options that you don't redefine are reset to their default setting, except for the userToken
. To preserve previously passed options without redeclaring them, use the partial
option.
aa("init", {
appId: "APP_ID",
apiKey: "SEARCH_API_KEY",
region: "de",
});
aa("init", {
appId: "APP_ID",
apiKey: "SEARCH_API_KEY",
partial: true,
}); // `region` is still `"de"`
When using Require.js, the default UMD build might conflict and throw with a "Mismatched anonymous define() modules" message. This is a known Require.js issue.
To work around this problem and ensure you capture all interactions occurring before the library is done loading, change ALGOLIA_INSIGHTS_SRC
to point to the IIFE build, and load it via a <script>
tag.
<script>
var ALGOLIA_INSIGHTS_SRC = "https://cdn.jsdelivr.net/npm/search-insights@2.7.0/dist/search-insights.iife.min.js";
!function(e,a,t,n,s,i,c){e.AlgoliaAnalyticsObject=s,e[s]=e[s]||function(){
(e[s].queue=e[s].queue||[]).push(arguments)},e[s].version=(n.match(/@([^\/]+)\/?/) || [])[1],i=a.createElement(t),c=a.getElementsByTagName(t)[0],
i.async=1,i.src=n,c.parentNode.insertBefore(i,c)
}(window,document,"script",ALGOLIA_INSIGHTS_SRC,"aa");
</script>
(Node.js >= 8.16.0
required)
Insights library can be used on the backend as a Node.js module.
npm install search-insights
# or
yarn add search-insights
Initializing the library is optional, as you can specify the credentials for each event when sending them. This gives you the flexibility to manage your Algolia credentials on a per-event basis, without having to configure them upfront.
const aa = require('search-insights');
// Optional: configure default Algolia credentials for events
aa('init', {
appId: 'APPLICATION_ID',
apiKey: 'SEARCH_API_KEY'
});
userToken
On the Node.js environment, unlike the browser environment, userToken
must be specified when sending any event.
aa('clickedObjectIDs', {
userToken: 'USER_ID',
// ...
});
If you want to customize the way to send events, you can create a custom Insights client.
// via ESM
import { createInsightsClient } from "search-insights";
// OR in commonJS
const { createInsightsClient } = require("search-insights");
// OR via the UMD
const createInsightsClient = window.AlgoliaAnalytics.createInsightsClient;
function requestFn(url, data) {
const serializedData = JSON.stringify(data);
const { protocol, host, path } = require("url").parse(url);
const options = {
protocol,
host,
path,
method: "POST",
headers: {
"Content-Type": "application/json",
"Content-Length": serializedData.length
}
};
const { request: nodeRequest } =
url.indexOf("https://") === 0 ? require("https") : require("http");
const req = nodeRequest(options);
req.on("error", error => {
console.error(error);
});
req.write(serializedData);
req.end();
};
const aa = createInsightsClient(requestFn);
The Search Insights library supports both Search and Personalization Algolia features.
To enable click analytics, the search parameter clickAnalytics
must be set to true
. This tells the Algolia engine to return a queryID
on each search request.
const searchClient = algoliasearch('APPLICATION_ID', 'SEARCH_API_KEY');
const search = instantsearch({
indexName: 'INDEX_NAME',
searchClient,
searchParameters: {
clickAnalytics: true,
},
});
function getQueryID() {
return search.helper.lastResults.queryID;
}
aa('clickedObjectIDsAfterSearch', {
index: 'INDEX_NAME',
eventName: 'Click item',
queryID: getQueryID(),
objectIDs: ['object1'],
positions: [42],
});
Option | Type | Description |
---|---|---|
index | string | The name of the index related to the event |
eventName | string | The name of the event |
objectIDs | string[] | The list of IDs of the result that was clicked |
positions | number[] | The list of the absolute positions of the HTML element that was clicked (1-based and not 0-based) |
queryID | string | The queryID of the search sent from Algolia |
aa('convertedObjectIDsAfterSearch', {
index: 'INDEX_NAME',
eventName: 'Add to basket',
queryID: getQueryID(),
objectIDs: ['object1'],
});
Option | Type | Description |
---|---|---|
index | string | The name of the index related to the event |
eventName | string | The name of the event |
objectIDs | string[] | The list of IDs of the result that was clicked |
queryID | string | The queryID of the search sent from Algolia |
To enable personalization, the search parameter enablePersonalization
must be set to true
.
const searchClient = algoliasearch('APPLICATION_ID', 'SEARCH_API_KEY');
const search = instantsearch({
indexName: 'INDEX_NAME',
searchClient,
searchParameters: {
enablePersonalization: true,
},
});
userToken
In cases where the userToken
is generated, you need a way to access the userToken
so that you can pass it to the searchClient
.
const searchClient = algoliasearch('APPLICATION_ID', 'SEARCH_API_KEY');
aa('getUserToken', null, (err, userToken) => {
// for algoliasearch v3.x
searchClient.setExtraHeader('X-Algolia-UserToken', userToken);
// for algoliasearch v4.x
searchClient.transporter.headers['X-Algolia-UserToken'] = userToken;
});
userToken
changeIf you want to attach a listener for userToken
change, you can call onUserTokenChange
.
aa('onUserTokenChange', (userToken) => {
console.log("userToken has changed: ", userToken);
});
onUserTokenChange
accepts callback
(required) and options
(optional).
aa('onUserTokenChange', callback, options);
Option | Type | Description |
---|---|---|
immediate | boolean | Fire the callback as soon as it's attached |
aa('init', { ..., useCookie: true }); // ← This sets an anonymous user token if cookie is available.
aa('onUserTokenChange', (userToken) => {
console.log(userToken); // prints out the anonymous user token
}, { immediate: true });
aa('init', { ... });
aa('setUserToken', 'my-user-id-1');
aa('onUserTokenChange', (userToken) => {
console.log(userToken); // prints out 'my-user-id-1'
}, { immediate: true })
With immediate: true
, onUserTokenChange
will be immediately fired with the token which is set beforehand.
aa('clickedObjectIDs', {
index: 'INDEX_NAME',
eventName: 'Add to basket',
objectIDs: ['object1'],
});
Option | Type | Description |
---|---|---|
index | string | The name of the index related to the event |
eventName | string | The name of the event |
objectIDs | string[] | The list of IDs of the result that was clicked |
aa('clickedFilters', {
index: 'INDEX_NAME',
eventName: 'Filter on facet',
filters: ['brand:Apple'],
});
Option | Type | Description |
---|---|---|
index | string | The name of the index related to the event |
eventName | string | The name of the event |
filters | string[] | The list of filters that was clicked as '${attr}${op}${value}' |
aa('convertedObjectIDs', {
index: 'INDEX_NAME',
eventName: 'Add to basket',
objectIDs: ['object1'],
});
Option | Type | Description |
---|---|---|
index | string | The name of the index related to the event |
eventName | string | The name of the event |
objectIDs | string[] | The list of IDs of the result that was clicked |
aa('convertedFilters', {
index: 'INDEX_NAME',
eventName: 'Filter on facet',
filters: ['brand:Apple'],
});
Option | Type | Description |
---|---|---|
index | string | The name of the index related to the event |
eventName | string | The name of the event |
filters | string[] | The list of filters that was clicked as '${attr}${op}${value}' |
aa('viewedObjectIDs', {
index: 'INDEX_NAME',
eventName: 'Add to basket',
objectIDs: ['object1'],
});
Option | Type | Description |
---|---|---|
index | string | The name of the index related to the event |
eventName | string | The name of the event |
objectIDs | string[] | The list of IDs of the result that was clicked |
aa('viewedFilters', {
index: 'INDEX_NAME',
eventName: 'Filter on facet',
filters: ['brand:Apple'],
});
Option | Type | Description |
---|---|---|
index | string | The name of the index related to the event |
eventName | string | The name of the event |
filters | string[] | The list of filters that was clicked as '${attr}${op}${value}' |
You can send multiple events in a single HTTP request, by using sendEvents
method.
aa('sendEvents', [
{
eventType,
eventName,
userToken,
...
}
]);
Option | Type | Description |
---|---|---|
eventType | 'view' | 'click' | 'conversion' | The name of the index related to the event. |
eventName | string | The name of the event. |
userToken | string (optional) | search-insights uses anonymous user token or a token set by setUserToken method. You can override it by providing a userToken per event object. |
The Search Insights library sends all events to the Algolia application it has been initialized with, by default. In some cases, you might have data coming from more than one Algolia application which all need events.
You can use a single instance of the Search Insights library while still customizing the Algolia credentials on a per-event basis. All click, view and conversion methods support an additional argument where you can specify credentials that will override those set during initialization (which is optional).
aa('clickedObjectIDsAfterSearch', {
index: 'INDEX_NAME',
eventName: 'Click item',
queryID: getQueryID(),
objectIDs: ['object1'],
positions: [42],
}, {
headers: {
'X-Algolia-Application-Id': 'OTHER_APP_ID',
'X-Algolia-API-Key': 'OTHER_SEARCH_API_KEY'
}
});
This also works with event batching, using sendEvents
:
aa('sendEvents', [
{
eventType,
eventName,
userToken,
...
}
], {
headers: {
'X-Algolia-Application-Id': 'OTHER_APP_ID',
'X-Algolia-API-Key': 'OTHER_SEARCH_API_KEY'
}
});
Option | Type | Description |
---|---|---|
headers | Record<string, string> | A dictionary of headers that will override those set by default. You can check out a list of headers for authentication in the Algolia API reference. |
The following examples assume that the Search Insights library is loaded.
To run the examples and the code, you need to run two separate commands:
yarn dev
runs webpack and the Node.js serveryarn build:dev
runs Rollup in watch modeTo release, go on main
(git checkout main
) and use:
yarn run release
It will create a pull request for the next release. When it's reviewed, approved and merged, then CircleCI will automatically publish it to npm.
Search Insights is MIT licensed.
FAQs
Library for reporting click, conversion and view metrics using the Algolia Insights API
We found that search-insights demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 7 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.