> ## Documentation Index
> Fetch the complete documentation index at: https://developer.voyado.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tracking product views

> How to send product views to Engage with productview(), how sessions work, and what abandoned browse requires.

Tracking product views feeds three features in Engage: abandoned browse, products of interest, and product recommendations.

You can send product views either with the [tracking script](/docs/tracking/tracking-script) or with the tracking API.

## What product views are used for

<AccordionGroup>
  <Accordion title="Abandoned browse">
    1. Your site submits product views, which belong to a session.
    2. A session with no activity for 30 minutes is treated as abandoned. If it contains **no cart event** and the product views are connected to a contact, it is sent to Engage. All other sessions are filtered out. A session can only be sent to Engage once.
    3. The product views are enriched with data from the product feed.
    4. Engage triggers the automation matching the trigger configuration. Email activities in that automation can include dynamic product data from the feed.

    <Card title="Read more about abandoned browse" href="https://help.engage.voyado.com/hc/en-gb/articles/17212835023516-Working-with-abandoned-browse" icon="https://mintcdn.com/voyado/Ns4bBcK3LNctK_Un/icons/help-center-link.png?fit=max&auto=format&n=Ns4bBcK3LNctK_Un&q=85&s=3e7ca2ce0b8cfb9fbd27a4bdf53b2ce1" horizontal width="128" height="128" data-path="icons/help-center-link.png" />
  </Accordion>

  <Accordion title="Products of interest">
    From the recency, frequency and pattern of product views over the last 90 days, Engage calculates up to **25 products** each contact is most likely interested in, based purely on their onsite behavior.

    The list is refreshed by a scheduled job and enriched from the article register — note that products of interest are connected to the **article register**, not the product feed. It can then be used in segmentation and as part of a scheduled selection in an automation.

    <Card title="Read more about products of interest" href="https://help.engage.voyado.com/hc/en-gb/articles/17236539524380-Products-of-interest" icon="https://mintcdn.com/voyado/Ns4bBcK3LNctK_Un/icons/help-center-link.png?fit=max&auto=format&n=Ns4bBcK3LNctK_Un&q=85&s=3e7ca2ce0b8cfb9fbd27a4bdf53b2ce1" horizontal width="128" height="128" data-path="icons/help-center-link.png" />
  </Accordion>

  <Accordion title="Product recommendations">
    If a contact has products of interest, that data feeds the calculation of their personal recommendations. Engage combines their onsite behavior with their full purchase and return history to produce a personalized set of recommendations for use in emails.
  </Accordion>
</AccordionGroup>

## What an abandoned browse automation requires

* The `locale` must match a product feed in Engage. Events without a matching feed are filtered out.
* At least one SKU must match a product in that feed (usually via `g:id`). Products that don't match are left out of the email; if **no** SKUs match, the automation doesn't trigger at all.
* The session must contain no cart events. See [sessions and sessionId](#sessions-and-sessionid) below.

## Sessions and sessionId

Every session has a unique `sessionId`. Engage uses it to make sure abandoned cart and abandoned browse never both trigger for the same session:

* If `cart` and `productView` events share a `sessionId`, only the **abandoned cart** automation triggers.
* **Abandoned browse** triggers only when no cart event was recorded for that `sessionId`.

The tracking script adds `sessionId` automatically. When you use the tracking API, you must add it to every payload yourself.

<Warning>
  The `sessionId` is not strictly mandatory for cart events, but it is required if you use abandoned browse and abandoned cart together. Not using it can result in both automations firing for the same session.
</Warning>

## Using the tracking script

Call `productview()` every time a product is shown to the visitor, whether or not they have been identified. It sends an HTTP POST to the Collect endpoint.

```javascript theme={null}
va("productview", {
   "categoryName": "Women / Armour / Greaves",
   "itemId": "123XYZ",
   "contactId": "afa7625d-2e97-4667-b4c1-ad3b01194bbb",
   "locale": "sv-SE"
});
```

<ResponseField name="categoryName" type="string" required>
  The product's category, for example `Men / Sweaters / Cardigan`.
</ResponseField>

<ResponseField name="itemId" type="string" required>
  The product identifier, matched against SKU in Engage.
</ResponseField>

<ResponseField name="locale" type="string" required>
  The locale of the site, as an IETF language tag such as `sv-SE`. Must match a product feed locale in Engage, otherwise abandoned browse cannot trigger.
</ResponseField>

<ResponseField name="contactId" type="string">
  The Engage contact ID. If omitted, the `_vaI` cookie is used as a fallback.
</ResponseField>

## Using the tracking API

You can submit product views directly via the API instead of implementing the tracking script. Be aware that a lot of what the script handles out of the box then becomes your responsibility:

* **Identification.** The API requires a `contactId`, so only identified product views can be registered. You must identify visitors arriving from Engage email links yourself, by reading the `vtid` query parameter and passing it as `contactId`.
* **Sessions.** You must include a `sessionId` in every payload. Abandoned browse will not work without it.

<Card title="Read more about the Engage REST API" href="/docs/api/the-engage-api" icon="https://mintcdn.com/voyado/Ns4bBcK3LNctK_Un/icons/developer-link.png?fit=max&auto=format&n=Ns4bBcK3LNctK_Un&q=85&s=fbd08f956358ab12f664a7158e1a1399" horizontal width="128" height="128" data-path="icons/developer-link.png" />

## Rules to follow

* **Send product views for anonymous visitors too.** A view recorded anonymously is linked to the contact once they are identified. Never restrict `productview()` to logged-in visitors.

* **A "product view" is any time a product is shown**, not just a product page visit. A quick-look popup counts.

* **`itemId` must match a SKU in Engage**, so the view can be enriched with product and transaction data.

* **One event per unique SKU.** A page may fire `productview()` several times if it represents several SKUs, but never twice for the same SKU.

## Common scenarios

<AccordionGroup>
  <Accordion title="Visitor arrives from a newsletter link, then views a product">
    The link from the Engage email carries `vtid`, so the script identifies the visitor before the product view is sent.

    Populate the event like this:

    * `categoryName` — the current product category, e.g. `Computer accessories > Printers > Toners`
    * `itemId` — the current product SKU, e.g. `549852`
    * `locale` — the site's current language/market, e.g. `sv-SE`
    * `contactId` — the visitor's Engage contact ID (`vtid` is used as a fallback)
  </Accordion>

  <Accordion title="Unidentified visitor views a product">
    Send the event exactly as above, with one difference:

    * Do **not** populate `contactId`

    The view is recorded against the browser's client ID and connected to a contact later, if and when the visitor is identified.
  </Accordion>

  <Accordion title="Visitor lands on a product page with multiple variants">
    A product display page covering several sizes, colours or variants needs a decision about what counts as a view.

    * **Preferred:** send one `productview()` when a specific variant is selected, rather than one per size.
    * If you want to record the view regardless of variant, send a single representative SKU from the page.
    * As a last resort, send all variants — but be aware this risks abandoned browse emails filled with many variants of the same product.
  </Accordion>
</AccordionGroup>

<Card title="Verify your product view tracking" href="/docs/tracking/verifying-web-tracking#verify-product-views" icon="https://mintcdn.com/voyado/Ns4bBcK3LNctK_Un/icons/developer-link.png?fit=max&auto=format&n=Ns4bBcK3LNctK_Un&q=85&s=fbd08f956358ab12f664a7158e1a1399" horizontal width="128" height="128" data-path="icons/developer-link.png" />
