---
title: Website data filter
slug: data-filter
description: How the Data filter works in Personizely: target visitors by website data set with ply.setData, plyData or parsers, with operators, timing and examples.
docTags: 
createdAt: 2026-10-17T09:49:04.408Z
---

The Data filter matches visitors by the website data your site passes to Personizely: key/value pairs you set with JavaScript (`ply.setData`, `window.plyData`) or that a [Parsers (data parsing engine)](docId\:n_O3ZB1_JFa-N-aEZ4u3U) collects from your page. Use it to target audiences that only your site knows about, such as a membership level, a logged-in state from your own system, or a value from your data layer.

**Available on:** all platforms.

## How it's evaluated

The filter reads: **Data matches all the following conditions**. Each condition compares one data key with a value, and the visitor matches only when **every** condition is true.

Website data lasts for the visitor's browser session. It's shared across their open tabs and cleared when the session ends. A key set on one page can therefore be used by campaigns and widgets on the next page.

- **Campaigns** use the data available when they run on page load.
- **Widgets** with a [Target rule](docId\:lKIsRCLhPiFzzx8QqEhXw) check it again when their trigger fires, so they see data set earlier on the same page.

Changing data later doesn't re-run a campaign that has already been applied to the page. It takes effect on the next page view.

## Options

Click **Add condition** for each key you want to check.

| Option   | What it does         | Values / default                                                                                                                          |
| -------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| Key      | Name of the data key | Required, case-sensitive, top-level keys only                                                                                             |
| Operator | How to compare       | is, is not, contains, does not contain, is empty, is not empty, is higher than, is lower than, is checked, is not checked. Default **is** |
| Value    | What to compare with | Required, except for **is empty**, **is not empty**, **is checked** and **is not checked**                                                |

## Setting website data

Set data before the snippet loads with `window.plyData`, or at any time with `ply.setData`. If your code can run before the snippet has loaded, queue the call with `plyLayer`:

```html
<script>
  // Before the Personizely snippet: read when the snippet starts
  window.plyData = { memberTier: 'gold', loggedIn: true }
</script>
```

```javascript
// After the snippet has loaded
ply.setData('cartValue', 129.5)
ply.setData({ memberTier: 'gold', newsletter: false })

// Safe at any time: queued until the snippet is ready
window.plyLayer = window.plyLayer || []
window.plyLayer.push(['setData', 'memberTier', 'gold'])
```

You can also create a parser with the destination **Data** to copy a value from a JavaScript variable, cookie, `localStorage`, the query string or a page element into website data, without changing your site's code. See [Website data (ply.setData and plyData)](docId\:F8Z6F1Bhw44oDyzHQoPE_) and the [JavaScript API (window.ply)](docId\:d64TegyOiwNA2GFG1eXPm).

## Behavior details

- **Missing keys are empty.** A key that was never set matches **is empty**, **is not**, **does not contain** and **is not checked**.
- **Values are compared as text.** `is 1` matches both `1` and `'1'`. Comparisons are exact and case-sensitive, with no wildcards.
- **Number comparisons read the first number.** "is higher than 100" works with `150`, `'150'` or `'$150.00'`. A value without a number counts as 0.
- **"is checked" means "has a truthy value".** It matches `true`, any non-zero number and any non-empty text, including the text `'false'`. Pass real booleans (`true`/`false`) for yes/no flags.
- **Top-level keys only.** Use `memberTier`, not `member.tier`. Flatten nested objects into separate keys.
- **`window.plyData` is read once.** It's read when the snippet starts. Changing `window.plyData` afterwards has no effect; use `ply.setData` instead.
- **Same data in text.** Data keys can also be inserted into widgets and campaigns with [Dynamic text (personalization variables)](docId\:EEz3US75criNjfndB--uS), for example `{data.memberTier}`. Dynamic text updates when the data changes.

## Examples

- **Members-only offer:** your site sets `ply.setData('memberTier', 'gold')` after login. A target "Data: memberTier is gold" personalizes the homepage banner.
- **Data layer value:** a parser copies `dataLayer.customerType` into the data key `customerType`. A popup targets "customerType is wholesale".
- **Trial accounts:** `window.plyData = { trialDaysLeft: 3 }` on a SaaS site, with a bar targeted to "trialDaysLeft is lower than 5".

## Related

- [Website data (ply.setData and plyData)](docId\:F8Z6F1Bhw44oDyzHQoPE_)
- [Parsers (data parsing engine)](docId\:n_O3ZB1_JFa-N-aEZ4u3U)
- [JavaScript API (window.ply)](docId\:d64TegyOiwNA2GFG1eXPm)
- [Visitor fields filter](docId:8O0nDK0HiHXgMjILAg_OC)
- [Cookie filter](docId:-3lZaQ8y88bclP2jMdSis)
- [Dynamic text (personalization variables)](docId\:EEz3US75criNjfndB--uS)
