This repo is a small demo React app showing a search-as-type implementation with all appropriate Querymon tracking implemented. If you are working in a Javascript environment, either frontend or backend, you can use the vanilla Querymon JS module in NPM. The module should work in any environment or framework due to its simplicity. The library has a single dependency, uuid
, is extremely simple and is designed to be a very light wrapper around the Querymon API.
The Javascript SDK should work in any environment, and can be added quickly from NPM.
npm install querymon
yarn add querymon
Initializing the SDK is simple, but needs to be done in a location that will persist the instance of Querymon throughout the lifecycle of search, returning results and clicking. It should NOT re-instantiate mid cycle.
Below is a sample of initializing the SDK in App.js of a simple React app.
// Once added via NPM
import { Querymon } from 'querymon';
/* @param {object} configuration
* REQUIRED @param {string} configuration.searchInterfaceKey - The Search Interface Key
* OPTIONAL @param {integer} configuration.debounceTime - The debounce time in ms for the search, defaults to 1000ms
* OPTIONAL @param {string} configuration.userId - The userId to log for all events. If not provided, a random uuid will be generated
*/
const querymon = new Querymon({
searchInterfaceKey: 'Your API key from https://app.querymon.com/search',
userId: 'the persistent user ID to tie conversions, and do other reporting like cohorts'
});
export default function MyApp() {
// Your application code
Note that for convenience, you can pass the userId
here a single time, and it will automatically be appended to all future requests. If inconvenient, you can always pass the userId
along with each request below.
The most basic logging can happen with a simple call to logSearch
with the user query as show below.
// Register query with Querymon. Async fire and forget
querymon.logSearch('search query here');
If you need further customization, such as analytics tagging and segmentation, to pass the user ID or override the timestamp that the query occurred, you can pass these parameters via the options object.
/* Method to log search query
* REQUIRED @param {string} query - The search query
* OPTIONAL @param {object} options - An object of optional parameters
* OPTIONAL @param {list of strings} options.metadata - An array of up to 4 strings to categorize the search query
* OPTIONAL @param {string} options.userId - The userId to log for all events to override the userId provided in the constructor
* OPTIONAL @param {int} options.queryTime - The time the query began (ms since 1970), defaults to the time of method invocation
*/
querymon.logSearch('search query here', {
metadata: ['variant A', 'split C'],
userId: 'user 1234',
queryTime: 1695674081849
});
When the results are returned from the query, you can pass them to the result logging method call as shown below. Be careful to mind the format of the result objects.
// Register results with Querymon. Fire and forget.
querymon.logResults('search query here', yourResults.map((item, index) => {
return {
entityId: item.id,
name: item.name,
description: item.description,
url: item.url,
index: index
};
}));
You also have the ability to specify the userId
and pass a specific timestamp if being logged later. Full example below:
/* Method to log results that were returned
* REQUIRED @param {string} query - The search query
* REQUIRED @param {list} results - The list of the results returned from the search engine
* Example format: [{index: row number integer, entityId: 'identifier for the result', name: 'name of result string', description: 'short description of the result', url: 'url for result'}]
* OPTIONAL @param {object} options - An object of optional parameters
* OPTIONAL @param {string} options.userId - The userId to log for all events to override the userId provided in the constructor
* OPTIONAL @param {int} options.resultReturnTime - The time the results were returned (ms since 1970), defaults to the time of method invocation
*/
querymon.logResults('search query here', yourResults.map((item, index) => {
return {
entityId: item.id,
name: item.name,
description: item.description,
url: item.url,
index: index
};
}), {
userId: 'user 1234',
resultReturnTime: 1695674081849
});
After you return the results to the user, if the user selects one of the results, you can log the click on the results with the following method.
The simplest version just logs the result row and name for matching.
// Register interaction with Querymon
querymon.logClick('search query here', result.index, result.name);
Again, you also have the ability to pass further parameters to specify the userId
or interaction time if logging later than the actual event.
/* Method to log clicks on results
* REQUIRED @param {string} query - The search query
* REQUIRED @param {int} resultRow - The row for the result that was clicked
* REQUIRED @param {string} resultName - The name of the result that was clicked
* OPTIONAL @param {object} options - An object of optional parameters
* OPTIONAL @param {string} options.userId - The userId to log for all events to override the userId provided in the constructor
* OPTIONAL @param {int} options.interactionTime - The time the result was clicked (ms since 1970), defaults to the time of method invocation
*/
querymon.logClick('search query here', result.index, result.name, {
userId: 'user 1234',
interactionTime: 1695674081849
});
Presumably this will happen later, on a different page from the search experience. Because of that, there is no need to pass the search query. Please do ensure to use the same searchInterfaceKey
as used before to map the conversion data back to you search interface.
// Register conversion event with Querymon
querymon.logConversion('purchase');
Again, you also have the ability to pass further parameters to specify the userId
or event time if logging the event later. We also recommend that you pass the eventValue
in cents to track revenue attribution.
/* Method to log a conversion event tied to the specific search interface
* REQUIRED @param {string} eventName - The name of the conversion event
* OPTIONAL @param {object} options - An object of optional parameters
* OPTIONAL @param {string} options.eventValue - The value of the conversion event, in cents. No decimals.
* OPTIONAL @param {string} options.userId - The userId to log for all events to override the userId provided in the constructor
* OPTIONAL @param {int} options.eventTime - The time the conversion event occurred (ms since 1970), defaults to the time of method invocation
*/
querymon.logConversion('purchase', {
eventValue: 999,
userId: 'user 1234',
eventTime: 1695674081849
});