If you’re using Twilio Segment to track user interactions on your website or app,
you can set up Algolia as a destination to forward click and conversion events .
Integrating Algolia with Segment has three steps:
Enable the Algolia destination in Segment.
Enable clickAnalytics
with your searches.
Augment your Segment events with Algolia-related data.
Enable the Algolia destination in Segment
To add the Algolia destination to Segment, follow these steps:
Sign in to your Segment web app and select the workspace you want to work in.
Select the source you want to set up and click Add Destination .
Search for the Algolia destination and select it to add it.
Sign in to your Algolia account and select the application you want to configure.
Copy your application ID and search API key from the dashboard and paste it into Segment.
For more information about adding destinations, go to the Segment documentation.
Enable clickAnalytics
To relate click and conversion events to searches,
Algolia needs a query ID .
To get the queryID
parameter for a search,
set the clickAnalytics
parameter to true
:
1
2
3
4
5
6
index . search ( ' YourSearchQuery ' , {
userToken : ' user-1 ' ,
clickAnalytics : true
}). then (({ hits , queryID }) => {
console . log ( hits , queryID );
})
1
2
3
4
instantsearch . widgets . configure ({
clickAnalytics : true ,
userToken : ' user-1 '
});
1
2
3
4
5
6
import { Configure } from ' react-instantsearch ' ;
< Configure
clickAnalytics = { true }
userToken = { ' user-1 ' }
/>
1
2
3
4
<ais-configure
:click-analytics.camel= "true"
user-token.camel= "user-1"
/>
1
2
3
<ais-configure
[searchParameters]= "{ clickAnalytics: true, userToken: 'user-1' }"
></ais-configure>
Identify users
If you use Segment’s analytics.identify()
function to identify users,
use the same identifier for Algolia by passing it as userToken
parameter with your search.
For example, if you want to use Personalization :
1
2
3
4
5
6
index . search ( ' YourSearchQuery ' , {
userToken : ' user-1 ' ,
enablePersonalization : true
}). then (({ hits }) => {
console . log ( hits );
})
1
2
3
4
instantsearch . widgets . configure ({
enablePersonalization : true ,
userToken : ' user-1 '
});
1
2
3
4
< Configure
enablePersonalization = { true }
userToken = { ' user-1 ' }
/>
1
2
3
4
<ais-configure
:enable-personalization.camel= "true"
user-token.camel= "user-1"
/>
1
2
3
<ais-configure
[searchParameters]= "{ enablePersonalization: true, userToken: 'user-1' }"
></ais-configure>
Algolia requires these properties that aren’t part of the regular Segment specifications:
Property
Type
Required?
index
string
Yes
eventType
value: 'view'
, 'click'
, or 'conversion'
Yes
queryID
string
No
objectIDs
string[]
or objectID
: string
No
positions
number[]
or position
: number
No
filters
Array<{ type: string; value: string; }>
or string[]
(${type}:${value}
—for example, brand:apple
)
No
For more information, see Event properties .
You can get these properties with the following code:
1
2
3
4
5
6
7
8
index . search ( ' query ' , {
userToken : ' user-1 ' ,
}). then (({ hits , queryID , hitsPerPage , page }) => {
hits . map (( hit , index ) => {
const position = index + 1 + page * hitsPerPage ;
const objectID = hit . objectID ;
});
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Required: InstantSearch.js >= 4.8.3
search . use (
instantsearch . middlewares . createInsightsMiddleware ({
insightsClient : null ,
onEvent ( event ) {
const { widgetType , eventType , payload , hits } = event ;
if ( widgetType === " ais.hits " && eventType === " view " ) {
analytics . track ( " Product List Viewed " , {
index : payload . index ,
eventType : ' view ' ,
queryID : payload . queryID ,
objectIDs : payload . objectIDs ,
positions : payload . positions ,
// the rest
});
} else if ( /* ... */ ) {
// ...
}
},
})
);
// index
// eventType
// queryID
// objectIDs
// positions
// filters
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
function debounce ( fn , delay ) {
let timerId ;
return function (... args ) {
if ( timerId ) {
clearTimeout ( timerId );
}
timerId = setTimeout (() => {
fn (... args );
timerId = null ;
}, delay );
};
}
const debouncedHitsRender = debounce (({ hits }) => {
if ( hits . length > 0 ) {
analytics . track ( " Product List Viewed " , {
index : ' <index-name> ' ,
eventType : ' view ' ,
queryID : hits [ 0 ]. __queryID ,
objectIDs : hits . map ( hit => hit . objectID ),
positions : hits . map ( hit => hit . __position ),
// the rest
});
}
}, 500 );
const SendViewEvent = connectHits ((... args ) => {
debouncedHitsRender (... args );
return null ;
});
// ...
const Hit = ({ hit }) => (
< article >
< h1 > { hit . name } </ h1 >
< button
onClick = { () =>
analytics . track ( " Product Clicked " , {
index : ' <index-name> ' ,
eventType : ' click ' ,
queryID : hit . __queryID
objectID : hit . objectID ,
position : hit . __position ,
// the rest
})
}
>
Add to favorite
</ button >
</ article >
);
// ...
< Configure clickAnalytics />
< SendViewEvent />
< Hits hitComponent = { Hit } />
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<!-- Required: Vue InstantSearch >= 3.7.0 -->
< template >
<ais-instant-search
:index-name= " <index-name> "
:search-client="searchClient"
:middlewares="middlewares"
>
<!-- widgets -->
</ais-instant-search>
</ template >
< script >
import {
createInsightsMiddleware ,
} from ' instantsearch.js/es/middlewares ' ;
const insightsMiddleware = createInsightsMiddleware ({
insightsClient : aa ,
onEvent ( event ) {
const { widgetType , eventType , payload , hits } = event ;
if ( widgetType === " ais.hits " && eventType === " view " ) {
analytics . track ( " Product List Viewed " , {
index : payload . index ,
eventType : ' view ' ,
queryID : payload . queryID ,
objectIDs : payload . objectIDs ,
positions : payload . positions ,
// the rest
});
} else if ( /* ... */ ) {
// ...
}
}
});
export default {
data () {
return {
// ...
middlewares : [ insightsMiddleware ]
}
},
}
</ script >
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import { Component , OnInit , forwardRef , Inject } from ' @angular/core ' ;
import { BaseWidget , NgAisInstantSearch } from ' angular-instantsearch ' ;
import { connectHits } from ' instantsearch.js/es/connectors ' ;
function debounce ( fn , delay : number ) {
let timerId ;
return function (... args ) {
if ( timerId ) {
clearTimeout ( timerId );
}
timerId = setTimeout (() => {
fn (... args );
timerId = null ;
}, delay );
};
}
const trackView = debounce ( hits => {
if ( hits . length > 0 ) {
analytics . track ( ' Product List Viewed ' , {
index : ' <index-name> ' ,
eventType : ' view ' ,
queryID : hits [ 0 ]. __queryID ,
objectIDs : hits . map ( hit => hit . objectID ),
positions : hits . map ( hit => hit . __position ),
// the rest
});
}
}, 500 );
@ Component ({
selector : ' app-tracker ' ,
template : ``
})
export class TrackerComponent extends BaseWidget implements OnInit {
public state : {
hits : any [];
};
constructor (
@ Inject ( forwardRef (() => NgAisInstantSearch ))
public instantSearchParent
) {
super ( ' Tracker ' );
}
public ngOnInit () {
this . createWidget ( connectHits , {});
super . ngOnInit ();
}
updateState = state => {
if ( ! state . hits || state . hits . length === 0 ) {
return ;
}
trackView ( state . hits );
};
}
// ...
< ais - configure [ searchParameters ] = " { clickAnalytics: true } " />
< ais - hits >
< ng - template let - hits = " hits " let - results = " results " >
< div * ngFor = " let hit of hits " >
< ais - highlight attribute = " name " [ hit ] = " hit " >< /ais-highlight >
< button
( click ) = "
analytics.track('Product Clicked', {
index: '<index-name>',
eventType: 'click',
queryID: hit.__queryID
objectID: hit.objectID,
position: hit.__position,
// the rest
})
"
>
Favorite
< /button >
< /div >
< /ng-template >
< /ais-hits>
The following code is an example of a click event tracked with Segment that includes all the necessary Algolia-related properties:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
analytics.track('Product Clicked', {
product_id: '507f1f77bcf86cd799439011',
sku: 'G-32',
category: 'Games',
name: 'Monopoly: 3rd Edition',
brand: 'Hasbro',
variant: '200 pieces',
price: 18.99,
quantity: 1,
coupon: 'MAYDEALS',
position: 3,
url: 'https://www.example.com/product/path',
image_url: 'https://www.example.com/product/path.jpg',
// Algolia-related properties
+ index: 'my-algolia-index',
+ eventType: 'click',
+ queryID: 'fd0bbaadc287937s7671d00f1d053b88',
+ objectID: '131280270'
});
Debug events with Segment
If you have administrator permissions for your Segment source,
you can send test events.
To do this, select your source and click Validate .
Select Algolia Insights as the destination.
Now, you can send a test event using the Event builder or JSON editor.
A green box with the status “200 OK” means that Segment successfully sent a test event to the Algolia Insights destination.
To check, if the event delivery was successful, go to the Event Delivery tab.
For example, sending an event with a wrong queryID
shows a Delivery Issue .
To check if Algolia receives your events correctly,
go to the Events Debugger in the Algolia dashboard.
For more information, see Validate your events .