Menu
Feedback
Guides
API Reference

Guides

Tracking search analytics events in mobile apps

Learn how to use Activity Flow listeners and hooks to track Intelligent Search analytics events in Flutter and React Native apps.

In this guide, you will learn how to add tracking to search screens in Flutter and React Native apps so that Activity Flow can capture Intelligent Search analytics events: impressions and clicks on search results and autocomplete suggestions.

The Activity Flow click, view, and impression listeners accept a metadata map with free-form parameters. The elementSource key identifies the origin of the event and is sent at the top level of the payload, while the remaining keys in the map become extra parameters inside attributes.

Before you begin

This guide assumes the Activity Flow SDK is already installed in your app. If you haven't set it up yet, see Installing Activity Flow in Flutter apps or Installing Activity Flow in React Native apps.

Understanding the tracking parameters

elementSource must be one of the following values:

ValueScreen
search-resultSearch results gallery, including the no-results search screen
search-autocompleteAutocomplete product suggestions

Extra parameters:

ParameterRequiredDescription
searchIdYes, in every eventThe search identifier, returned by the Intelligent Search response itself.
productIdYes, on clickThe ID of the clicked product.
productPositionYes, on clickThe product's position in the list, 1-based, absolute across pages.
productSpecificationNoThe product's specification value, when the API returns it.

searchId is generated by Intelligent Search and returned in the search response (product_search on the results gallery, product_suggestions on autocomplete). Never create, derive, or reuse this value.

Follow the steps below to track impressions and clicks on the search results gallery, including the no-results screen.

  1. Add the impression and click listeners for your platform. If searchId didn't come back in the response or is empty, don't add the listeners or send the event: it's better to lose the event than to record one that can't be attributed to a search.

    Flutter


    _11
    resultList.addImpressionListener({
    _11
    'elementSource': 'search-result',
    _11
    'searchId': searchId,
    _11
    });
    _11
    _11
    productCard.addClickListener({
    _11
    'elementSource': 'search-result',
    _11
    'searchId': searchId,
    _11
    'productId': product.productId,
    _11
    'productPosition': (positionOffset + index + 1).toString(),
    _11
    });

    React Native


    _11
    useImpressionObserver({
    _11
    elementSource: 'search-result',
    _11
    searchId,
    _11
    });
    _11
    _11
    const { afHandlePress } = useClickObserver({
    _11
    elementSource: 'search-result',
    _11
    searchId,
    _11
    productId: product.productId,
    _11
    productPosition: String(positionOffset + index + 1),
    _11
    });

  2. Apply the same impression listener to the no-results screen's container, since a search without results still counts as exactly one impression.

    On Flutter, addImpressionListener re-fires when the metadata map changes, so each new searchId automatically generates a new impression.

Tracking autocomplete

Autocomplete follows the same pattern as the results gallery, but with its own elementSource value and searchId.

  1. Use the same listeners with elementSource: 'search-result' replaced by 'search-autocomplete', and the searchId from the suggestions response instead of the results response.

    Autocomplete and the results gallery are distinct searches. Don't propagate the suggestions' searchId to the results screen when the shopper submits the search: that screen has its own searchId.

  2. On React Native, gate the tracking at render time, since it doesn't validate an empty elementSource at runtime: only mount the tracked component when there's a searchId.

Checklist

  • Impression sent on every search, including searches that return no products.
  • searchId always coming from the API and present on both the impression and the click.
  • productPosition is 1-based and correct after pagination or infinite scroll.
  • No event sent on a search that redirects or has no searchId.
Contributors
1
Photo of the contributor julia-rabello
+ 1 contributors
Was this helpful?
Yes
No
Suggest Edits (GitHub)
See also
VTEX Activity Flow
Guides
Installing Activity Flow in mobile apps
Guides
Tracking search analytics events in headless web stores
Guides
Contributors
1
Photo of the contributor julia-rabello
+ 1 contributors
On this page
Was this helpful?
Suggest edits (GitHub)
On this page