---
title: Goals
slug: XSkE-goals
description: How goals work in Personizely: the 7 goal types, page matching, counting limits, values, built-in Purchase, Add to cart and Checkout start goals, primary goals.
docTags: 
createdAt: 2026-10-16T19:44:41.566Z
---

A goal is an action you want visitors to take, such as buying, adding to cart, clicking a button or reading a page. Personizely counts each time a visitor reaches a goal (a **goal hit**) and credits it to the campaigns and widgets they saw before. That is how every A/B test, personalization and widget report measures conversion rate and revenue. There are 7 goal types: Page view, Click, Form submit, Time, Scroll, Event and Manual.

## How it works

1. **You create goals once per website** under **Settings → Goals**, or from the goal picker while editing a campaign or widget. A goal can be reused by any number of campaigns and widgets.
2. **Each campaign and widget tracks a list of goals.** A campaign needs at least one goal. One goal is the **primary goal** (marked with a star). It drives the winner verdict, the test progress and the totals on the Campaigns and Widgets lists.
3. **Goal hits are recorded as visitors browse.** Click, Form submit, Time and Scroll goals are detected by the snippet on the page. Page view and Event goals are matched when the visit or event is recorded. Purchases on Shopify and Wix are recorded server-side from the platform's order data.
4. **Each goal hit is credited** to every campaign and widget the visitor saw within your attribution window that tracks that goal. See [Revenue attribution](docId\:jpQKiTTVFyptseo8UEQOD).

## Goal types

| Type            | Reached when                                                                            | Type-specific settings                                                                              |
| --------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| **Page view**   | The visitor loads a page that matches **Page**                                          | **Page** (required)                                                                                 |
| **Click**       | The visitor clicks an element matching the **CSS Selector**, or anything inside it      | **CSS Selector**, e.g. `#cta`                                                                       |
| **Form submit** | A form matching the **CSS Selector** is submitted                                       | **CSS Selector** of the `<form>` (or an element containing it)                                      |
| **Time**        | The visitor's total time on matching pages in the current session reaches the threshold | **Time spent in seconds**, default **40**                                                           |
| **Scroll**      | The visitor scrolls past the given percentage of a matching page                        | **Scroll percent**, default **50**                                                                  |
| **Event**       | A named event is recorded for the visitor: a built-in commerce event or a custom one    | **Event**: Purchase, Add to cart, Checkout start (where supported) or **Custom** with an event name |
| **Manual**      | Your code calls `ply.trackGoal()` with the goal's name or ID                            | **Default value**                                                                                   |

### Built-in commerce events

| Event          | Shopify                                                                                                | Wix                         | Other sites                                                                                                       |
| -------------- | ------------------------------------------------------------------------------------------------------ | --------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| Purchase       | Server-side from Shopify orders. See [Shopify order tracking and profit](docId\:hS2Gsx3K3YcJ2NRssNAmX) | Server-side from Wix orders | With the [Google Analytics 4 and GTM](docId\:NwHWpmwoIntBLz7-PTe3q), from GA4 `purchase` events in the data layer |
| Add to cart    | From Personizely's Shopify web pixel                                                                   | No                          | From GA4 `add_to_cart` events (Google Analytics integration)                                                      |
| Checkout start | From Personizely's Shopify web pixel                                                                   | No                          | From GA4 `begin_checkout` events (Google Analytics integration)                                                   |

When you connect a platform that supports them, Personizely creates these as **system goals**, named **Purchase**, **Add to cart** and **Checkout start**. The system Purchase goal counts every order. To count only some orders, create your own Event goal on Purchase with a product or tag filter (see below).

Shopify stores with GoKwik, ShipRocket or Shopflo checkouts get additional purchase and checkout-start events. See [Custom checkouts: GoKwik, ShipRocket, Shopflo](docId\:X4-4KmLJTdX84oVkwOtfJ).

### Custom events

Choose **Event → Custom** and type an event name, such as `signup_complete`. The goal is reached whenever an event with that exact name is recorded for the visitor, for example from your own code:

```javascript
ply.trackEvent('signup_complete')        // no value
ply.trackEvent('quote_requested', 250)   // with a value, in your store currency
```

Event names must start with a lowercase letter and use only lowercase letters, digits and underscores, with at least 3 characters. `signup_complete` is valid. `Signup-Complete` throws an error. See the [JavaScript API (window.ply)](docId\:d64TegyOiwNA2GFG1eXPm).

### Manual goals

A Manual goal is reached only when your code calls it by name or ID:

```javascript
ply.trackGoal('Free trial')           // uses the goal's Default value
ply.trackGoal('Free trial', 49)       // overrides the value for this hit
```

`ply.trackGoal` only finds **Manual** goals. Calling it with the name of a Click or Event goal throws "Could not find the goal".

## Configuration

| Option                     | What it does                                                       | Values / default                                                                                                                                            |
| -------------------------- | ------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Goal name                  | Shown in goal pickers and reports                                  | Text                                                                                                                                                        |
| Action                     | The goal type                                                      | Page view (default), Click, Form submit, Time, Scroll, Event, Manual. **Can't be changed after the goal is created.**                                       |
| CSS Selector               | Element to watch (Click, Form submit)                              | Any CSS selector                                                                                                                                            |
| Time spent in seconds      | Threshold for Time goals                                           | Default 40                                                                                                                                                  |
| Scroll percent             | Threshold for Scroll goals                                         | Default 50                                                                                                                                                  |
| Event                      | Event to match (Event goals)                                       | Purchase, Add to cart, Checkout start, or Custom name                                                                                                       |
| Products                   | Count the event only if it contains at least one of these products | Product list. For Add to cart and Checkout start goals you create, required. Shopify only                                                                   |
| Tags                       | Count a purchase only if the order has at least one of these tags  | Order tags. Purchase goals you create on Shopify. A Purchase goal needs Products, Tags or both                                                              |
| All pages / Specific pages | Where the goal can be reached                                      | All pages (default). Page view goals always need a page. Not available for Manual and Purchase goals                                                        |
| Page                       | Page pattern to match                                              | Path pattern, e.g. `/checkout/thank-you` or `/products/*`                                                                                                   |
| Include query string       | Match the pattern against the path plus the query string           | Off                                                                                                                                                         |
| Count goal as reached      | How often one visitor can reach the goal                           | Every time (default), Once per session, Once per page. Page view offers Every time and Once per session. Shown for Page view, Click, Form submit and Scroll |
| Value / Default value      | Value recorded with each goal hit, in your website currency        | Optional number. Not shown for Purchase, Add to cart and Checkout start, which use real order and cart values                                               |

### Page patterns

Patterns match the URL path only, without the domain, and must match the whole path. A trailing slash is ignored.

| Pattern                                             | Matches                       | Doesn't match                                                           |
| --------------------------------------------------- | ----------------------------- | ----------------------------------------------------------------------- |
| `/pricing`                                          | `/pricing`, `/pricing/`       | `/pricing/team`                                                         |
| `/products/*`                                       | `/products/blue-shirt`        | `/products/blue-shirt/reviews`, `/collections/sale/products/blue-shirt` |
| `/blog/**`                                          | `/blog/`, `/blog/news/launch` | `/blogs/news`                                                           |
| `/thank-you?plan=pro` with **Include query string** | `/thank-you?plan=pro`         | `/thank-you?plan=pro&ref=x`                                             |

`*` matches one path segment. `**` matches any number of segments.

## Goals on campaigns and widgets

- **Campaigns** track the goals you pick in the campaign's goal selector. The starred goal is the primary goal, and it's the default goal shown in the campaign report. You can view any of the campaign's other goals in the report too. See [Reading campaign reports](docId\:Xb9pSvXG7zF45wIEXc7Sp).
- **Widgets** also have a goals list and a primary goal. By default, a widget gets credit for a goal only if the visitor **converted** in the widget (a **Track conversion** automation ran, for example on form submit or button click). Turn on **Attribute on view** to credit the goal to every visitor who saw the widget. **Track conversion** is added automatically when you add a Button, Survey, Products or Form element.

## Behavior details and limitations

- **One goal hit, many campaigns.** A single purchase is credited to every campaign and widget that tracks the goal and was seen within the attribution window. Reports for different campaigns can therefore include the same order.
- **Conversion rate counts visitors.** A visitor who reaches a goal three times counts once toward conversion rate, but all three hits count toward goal hits and revenue. See [Statistics methodology](docId\:Jl7imbqyTMR8uy4RyPYQL).
- **Once per page on single-page apps.** On storefronts that change pages without a full reload, every detected page change resets "Once per page" counting and restarts Time and Scroll tracking for the new page.
- **Time goals add up across pages.** Time spent on every matching page in the session counts toward the threshold. A goal limited to `/blog/**` only counts time on blog pages.
- **Scroll goals fire once per page view**, the first time the visitor passes the threshold.
- **Form submit needs a real form submit.** Forms that send data with JavaScript without firing the browser's submit event aren't detected. Use a Click goal on the button, or a Manual goal from your form's success callback.
- **Click goals work on elements added later**, such as a button in a drawer that opens after page load.
- **Purchase goals with tags check the order's tags when Personizely records the order.** Tags another app adds much later won't make the order count toward the goal. The [Report filters, outliers and resetting stats](docId\:lTocNv-A4qdZG05vt1x51) always uses the order's latest tags.
- **Custom-event goals match the exact name.** `Purchase`, `purchase ` (trailing space) and `purchase` are different events.
- **Editing a goal doesn't rewrite history.** Goal hits already recorded keep their credit. Changes to page, product or tag filters apply to new hits.

## Examples

- **Lead-gen site:** a Form submit goal on `form#demo-request`, plus a Page view goal on `/thank-you` as a backup, with **Once per session**.
- **Category-level purchase goal (Shopify):** an Event goal on **Purchase** with **Products** set to your bundle products. Use it as the primary goal of a bundle-promotion test so unrelated orders don't dilute the result.
- **Subscription signups:** a Purchase goal with **Tags** set to `Subscription`, to measure a test on subscription orders only.
- **App-like flows:** call `ply.trackEvent('onboarding_done')` and create an Event goal on the custom event `onboarding_done`.

## Troubleshooting

- **Click goal never fires** → the selector doesn't match the element, or the click opens a new page before the event is sent. Test the selector in the browser console with `document.querySelectorAll('<selector>')`, and prefer a Page view goal on the destination page for links.
- **`ply.trackGoal` throws "Could not find the goal"** → the goal isn't a Manual goal, or the name doesn't match exactly. Use the goal ID to avoid typos.
- **`ply.trackEvent` throws "Invalid event format"** → the name has uppercase letters, hyphens or spaces. Use `snake_case`.
- **Purchase goal shows no data on Shopify** → see [Shopify order tracking](docId\:hS2Gsx3K3YcJ2NRssNAmX#troubleshooting).

## Related

- [Revenue attribution](docId\:jpQKiTTVFyptseo8UEQOD)
- [Shopify order tracking and profit](docId\:hS2Gsx3K3YcJ2NRssNAmX)
- [Custom checkouts: GoKwik, ShipRocket, Shopflo](docId\:X4-4KmLJTdX84oVkwOtfJ)
- [Reading campaign reports](docId\:Xb9pSvXG7zF45wIEXc7Sp)
- [JavaScript API (window.ply)](docId\:d64TegyOiwNA2GFG1eXPm)
- [Widget automations](docId\:J2UM-jhfDgQFopQlTvf_l)
