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

# Personalization

> Use dynamic variables and expressions to personalize message content, URLs, and audience targeting in Clix campaigns.

## Overview

Clix supports template-based personalization so you can insert variables and light business logic in message content, deep links, and audience targeting rules. Reference user traits, event properties, and app context to tailor each message to a recipient.

You can apply the syntax in:

* **Message content** – title, body, subtitle
* **Links** – dynamic URL or deep link parameters
* **Audience targeting** – conditional logic that includes or excludes users

***

## Data You Can Use

| Object      | Description                              | Example                                 |
| ----------- | ---------------------------------------- | --------------------------------------- |
| `user.*`    | Properties captured about the user       | `user.username`, `user.tier`            |
| `event.*`   | Properties from the triggering event     | `event.distance`, `event.elapsedTime`   |
| `trigger.*` | Custom properties passed via API trigger | `trigger.promotion`, `trigger.discount` |

Missing or undefined variables render as an empty string.

### Device and System Variables

In addition to `user.*`, `event.*`, and `trigger.*`, Clix templates also support device and environment variables you can use for targeting or message personalization.

| Object            | Description                        | Example                                |
| ----------------- | ---------------------------------- | -------------------------------------- |
| `device.id`       | Unique device identifier           | `{{ device.id }}` → `a8c9e1...`        |
| `device.platform` | Platform name (`IOS` or `ANDROID`) | `{{ device.platform }}` → `IOS`        |
| `device.locale`   | Device locale code                 | `{{ device.locale }}` → `US`           |
| `device.language` | Device language                    | `{{ device.language }}` → `en`         |
| `device.timezone` | Device timezone                    | `{{ device.timezone }}` → `Asia/Seoul` |
| `user.id`         | Project user ID                    | `{{ user.id }}` → `clix_user`          |
| `event.name`      | Event name                         | `{{ event.name }}` → `run_completed`   |

```liquid theme={null}
Hi {{ user.username | default: "Guest" }},
You're using {{ device.platform }} in {{ device.locale }}.
Your last event: {{ event.name }} ({{ event["distance"] }} km)
```

***

## Output Variables

Use double curly braces `{{ ... }}` to print a value.

```liquid theme={null}
{{ user.username }}
```

### Example (message content)

```
Hi {{ user.username }}, you ran {{ event.distance }} miles today!
```

### Example (URL)

```
myapp://run/summary?distance={{ event.distance }}&time={{ event.elapsedTime }}
```

***

## Conditional Logic

Wrap conditional blocks in `{% if %}`, `{% else %}`, and `{% endif %}`.

Supported operators:

* `==`, `!=`, `>`, `<`, `>=`, `<=`
* `and`, `or`, `not`

```liquid theme={null}
{% if event.distance >= 10 %}
Amazing! You completed a long run today 💪
{% else %}
Nice work! Keep it up!
{% endif %}
```

Nested conditions are supported:

```liquid theme={null}
{% if user.tier == "pro" %}
Pro stats updated successfully.
{% else %}
{% if event.elapsedTime > 3600 %}
You ran for more than an hour! Great job!
{% else %}
New record saved.
{% endif %}
{% endif %}
```

***

## Loops

Iterate over arrays with `{% for %}`.

```liquid theme={null}
{% for badge in user.badges %}
- {{ badge }}
{% endfor %}
```

Handle empty collections with a guard:

```liquid theme={null}
{% if user.badges and user.badges.size > 0 %}
{% for badge in user.badges %}
{{ badge }}
{% endfor %}
{% else %}
No badges yet.
{% endif %}
```

***

## Filters

Filters transform values inside `{{ ... }}` blocks and can be chained with the pipe (`|`) operator.

| Filter                | Description                                                                                           | Example                                                                                                      |
| :-------------------- | :---------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------- |
| `upcase` / `downcase` | Converts all characters to upper or lower case.                                                       | \{\{ "Clix" \| upcase }} → `CLIX`                                                                            |
| `capitalize`          | Makes the first character of a string capitalized and converts the remaining characters to lowercase. | \{\{ "hello world" \| capitalize }} → `Hello world`                                                          |
| `default`             | Provides a fallback when the value is empty or missing.                                               | \{\{ user.username \| default: "Guest" }} → `Guest` (if username is undefined)                               |
| `join`                | Combines array elements into a single string with a separator.                                        | If `user.tags = ["active", "runner", "beta"]`, then \{\{ user.tags \| join: ", " }} → `active, runner, beta` |
| `split`               | Splits a string into an array using a delimiter.                                                      | \{\{ "a,b,c" \| split: "," }} → `["a", "b", "c"]`                                                            |
| `escape`              | Escapes special HTML characters.                                                                      | \{\{ "\<div>" \| escape }} → `&lt;div&gt;`                                                                   |
| `strip`               | Removes leading and trailing whitespace.                                                              | \{\{ "  Clix  " \| strip }} → `Clix`                                                                         |
| `replace`             | Replaces all occurrences of a substring.                                                              | \{\{ "hello world" \| replace: "world", "Clix" }} → `hello Clix`                                             |

### Chaining Filters

Filters can be applied in sequence:

```liquid theme={null}
{{ user.username | default: "Guest" | upcase }}
```

The `default` filter runs first, then the result is converted to uppercase.

***

## Full Example

### Event Payload

```json theme={null}
{
  "name": "run_completed",
  "properties": {
    "distance": 7.4,
    "elapsedTime": 2320
  },
  "user": {
    "username": "Alex"
  }
}
```

### API Trigger Example with Custom Properties

```json theme={null}
{
  "audience": {
    "broadcast": true
  },
  "properties": {
    "promotion": "Holiday Sale",
    "discount": "30%"
  }
}
```

### Message Title (Event Example)

```liquid theme={null}
{% if event.distance >= 10 %}
Long run completed! 💪
{% else %}
Good run today!
{% endif %}
```

### Message Body (Event Example)

```liquid theme={null}
Hi {{ user.username }}, you ran {{ event.distance }} miles in {{ event.elapsedTime }} seconds.
```

### Deep Link (Event Example)

```
myapp://run/summary?distance={{ event.distance }}&time={{ event.elapsedTime }}
```

### Message Body (API Trigger Example)

With the API trigger properties above (`promotion` and `discount`), personalize your message using the `trigger` namespace:

```liquid theme={null}
🎉 {{ trigger.promotion }} is here! Get {{ trigger.discount }} off now!
```

Result: `🎉 Holiday Sale is here! Get 30% off now!`

***

## Best Practices

* Use simple, serializable data types (numbers, strings, booleans).
* Pre-format data (e.g., `"7.4 miles"`, `"38m 40s"`) before sending, then reference it directly.
* Add guards for missing data.
* Keep logic minimal. Complex branching belongs in your app or segmentation setup, not inside message templates.

***

## Error Handling

* Unknown variables render as an empty string.
* Invalid conditions evaluate to `false`.
* Template rendering errors appear in **Message Logs** with error details.
