How targeting works
Personizely checks a visitor against a Targets at specific moments: when a page loads, when a single-page app changes page, when a widget's trigger fires, and when new visitor data arrives. What the visitor matches at that moment decides whether they enter an A/B test, which personalization variation they get and whether a widget shows. This page explains those moments, what data each check sees, and how Live and Permanent targeting modes change things for campaigns.
Available on: all platforms.
When targets are evaluated
- The page loads. The snippet starts, recognizes the visitor (see Visitor identity, sessions and storage) and records any new traffic-source data from the URL, such as UTM parameters.
- Visitor data is resolved. If the visitor is being Identifying visitors on this page (an email= link, an email-platform click ID, a logged-in Shopify customer), that happens first, so targets see the identified profile.
- Targets used on the page are evaluated. Only targets used by running campaigns and widgets are checked. Data that some filters need, such as visitor history, location or order data, is loaded at this point.
- Campaigns run. Each campaign checks its target (or each variation's target, for personalizations) and applies the matching variation.
- Widgets start. Each widget checks its page-load Widget display rules and starts its triggers. Its Target rule is checked later, when a trigger fires.
- The page view is recorded. Only after targets have been evaluated is the page view saved to the visitor's history.
Re-evaluation
Event | What's re-checked |
|---|---|
Next page load | Everything, from scratch |
Page change in a single-page app (the URL path changes without a full reload) | Every target, including fresh history and location data. The page counts as a new page view |
A widget trigger fires | The widget's Target rule, using the latest data (see below) |
The visitor is identified during the page view (form submit, ply.identifyVisitor, parser) | Targets that depend on profile data, once the profile has been updated |
Nothing is re-checked just because time passes, the visitor scrolls, or your code calls ply.setData. A campaign that didn't match on page load stays off until the next page load or page change, even if the visitor's cart or data changes in the meantime. Widgets catch up when their trigger fires.
What data a check sees
When a widget trigger fires, the Target rule reads the current values of filters about the page, the cart and the device: cart value, size and items, page content (Selector), cookies, website data, device, browser, locale, the visitor's time, and remembered traffic-source values. Filters based on history, location, weather, order history and email-platform lists use the values loaded when the page loaded. Goal, Event and Widget history also count what the visitor did earlier on this page.
Live vs Permanent targeting (campaigns)
Campaigns with a target have a Targeting mode. Widgets don't: their Target rule is checked on every trigger.
Mode | What happens on later pages | Use it when |
|---|---|---|
Live (default) | The target is checked again on every page. Where the visitor doesn't match, they see the original. In an A/B test they keep their assigned arm and see it again when they match; in a personalization they may get a different variation | The target uses stable attributes (country, device, traffic source), or the change only makes sense while the condition holds |
Permanent | Once the visitor has been assigned (to a variation or to control), the target isn't checked again for them in this campaign | The target uses something that changes during the visit, such as cart value, pages viewed or time on site, and you want a consistent experience. Price campaigns always use Permanent |
Example. A personalization shows free-shipping messaging to visitors whose cart value is at least $50. In Live mode, the banner disappears on the next page if the visitor removes items and drops below $50. In Permanent mode, the banner stays once they've seen it.
Traffic allocation is still checked in Permanent mode. See How visitors are assigned to variations.
History counts exclude the current page view
Because a page view is recorded after targets are evaluated, history filters describe what happened before this page:
- Page view history: "at least 3 pages" on page load means the visitor viewed at least 3 pages before the current one. On a visitor's first page, the count is 0.
- Visit history: the current visit isn't counted on its first page. From the second page of the visit onward, it is. A visitor on their second visit has a count of 1 on their landing page and 2 after that.
- Last page view: refers to the previous page view, not the current one. For a brand-new visitor there's no value, so "was" is false and "was not" is true.
When a widget trigger fires later on the page, a Page view history check set to During this session may already include the current page view. If you need an exact page count for a widget, test it on the page where it should first appear.
Remembered traffic-source values
The UTM Parameters, Query String, Referrer and Entry page filters don't read only the current URL. Personizely stores these values for the visitor and keeps them across pages and visits, so an audience defined by how a visitor arrived keeps matching after they navigate away from the landing page.
Filter | Value used | When it changes |
|---|---|---|
Referrer | The full URL of the first external site that sent the visitor | Never. Set once, on the first visit that has an external referrer (first-touch) |
Entry page | The path of the very first page the visitor ever landed on | Never. Set once, on the first page view (first-touch) |
UTM Parameters | The stored value of each of utm_source, utm_medium, utm_campaign, utm_term and utm_content | Each parameter is updated whenever it appears in a URL the visitor opens. A parameter that isn't in the new URL keeps its earlier value |
Query String | The stored value of each URL parameter the visitor has arrived with | Each parameter is updated whenever it appears in a URL. Parameters are never cleared |
What this means in practice:
- A visitor who lands with ?utm_source=instagram&utm_campaign=spring still matches "UTM source is instagram" on every later page and on later visits.
- If they come back weeks later through ?utm_source=google, their source becomes google, but their stored campaign is still spring, because the new link didn't include utm_campaign.
- Referrer and Entry page stay as they were on the visitor's first visit, however they arrive later.
- Values are remembered per visitor, so a new device or cleared site data starts fresh.
To react only to the URL of the current page, use the widget Query string rule instead of a target.
Filters that need data
Filters that need visitor history, location or order data may take a moment to resolve; content that depends on them stays hidden until they do.
- Campaigns: elements a campaign changes are hidden until the targets it depends on have resolved, then shown with the right variation. This avoids showing the original and then switching. See Performance and flicker.
- Widgets: a widget whose Target rule uses such filters starts its triggers once the data is ready.
- If data can't be loaded, the filter counts as not matched and hidden content is revealed with the original.
Targets that only use filters like device, page, cookie, website data or traffic source resolve immediately.
Behavior details and limitations
- Only targets in use are evaluated. A target that no running campaign or widget uses isn't checked, and adds nothing to page load.
- Brand-new visitors. On a visitor's first page view, history counts are 0, "First visit is now" and "First page view is now" are true, and profile fields are empty until the visitor is identified.
- Identification can change results mid-visit. When a visitor is merged into an existing profile with an earlier first visit, "First visit is now" turns false from then on, and history counts include the merged profile's history.
- Personalizations check variations in order. The first variation whose target matches is used. See Personalizations.
- Preview ignores targeting. A preview link shows the chosen variation whatever the target says. To test the target itself, visit the site as a visitor who matches it, and use ?ply_debug=1 to see which campaigns and widgets ran and why.
- Bots don't run targeting. The snippet doesn't run for recognized bots, with ?ply_disable=1, or when tracking is paused.
Examples
- Ad landing personalization: a variation for UTM campaign is summer-sale, in Live mode. The visitor keeps matching on every page and on return visits until a new link changes their stored campaign.
- Cart-threshold banner: a personalization targeting Cart value at least 50, in Permanent mode, so the message doesn't vanish when the cart changes.
- Welcome-back widget: a widget whose Target is one don't match group with "First visit is now". It matches visitors on every page of any visit after their first, which is more predictable than counting visits with Visit history.
Troubleshooting
- Campaign shows on the landing page but not later → the target uses something that changes between pages (Selector, Cart value, a page-based Data value) in Live mode. Switch to Permanent or use a stable filter.
- Visitor still matches an old UTM campaign → stored UTM values persist until a new link sets that parameter. Target on a combination of parameters, or use the Query string rule for current-URL checks.
- History filter is off by one → the current page view isn't counted when the page loads. Lower the number by one.
- Content appears late on some pages → the target uses history, location or order filters. Use them only where the audience needs them.