Skip to main content

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

ObjectDescriptionExample
user.*Properties captured about the useruser.username, user.tier
event.*Properties from the triggering eventevent.distance, event.elapsedTime
trigger.*Custom properties passed via API triggertrigger.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.
ObjectDescriptionExample
device.idUnique device identifier{{ device.id }}a8c9e1...
device.platformPlatform name (IOS or ANDROID){{ device.platform }}IOS
device.localeDevice locale code{{ device.locale }}US
device.languageDevice language{{ device.language }}en
device.timezoneDevice timezone{{ device.timezone }}Asia/Seoul
user.idProject user ID{{ user.id }}clix_user
event.nameEvent name{{ event.name }}run_completed
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.
{{ 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
{% if event.distance >= 10 %}
Amazing! You completed a long run today 💪
{% else %}
Nice work! Keep it up!
{% endif %}
Nested conditions are supported:
{% 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 %}.
{% for badge in user.badges %}
- {{ badge }}
{% endfor %}
Handle empty collections with a guard:
{% 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.
FilterDescriptionExample
upcase / downcaseConverts all characters to upper or lower case.{{ “Clix” | upcase }} → CLIX
capitalizeMakes the first character of a string capitalized and converts the remaining characters to lowercase.{{ “hello world” | capitalize }} → Hello world
defaultProvides a fallback when the value is empty or missing.{{ user.username | default: “Guest” }} → Guest (if username is undefined)
joinCombines array elements into a single string with a separator.If user.tags = ["active", "runner", "beta"], then {{ user.tags | join: ”, ” }} → active, runner, beta
splitSplits a string into an array using a delimiter.{{ “a,b,c” | split: ”,” }} → ["a", "b", "c"]
escapeEscapes special HTML characters.{{ “<div>” | escape }} → &lt;div&gt;
stripRemoves leading and trailing whitespace.{{ ” Clix ” | strip }} → Clix
replaceReplaces all occurrences of a substring.{{ “hello world” | replace: “world”, “Clix” }} → hello Clix

Chaining Filters

Filters can be applied in sequence:
{{ user.username | default: "Guest" | upcase }}
The default filter runs first, then the result is converted to uppercase.

Full Example

Event Payload

{
  "name": "run_completed",
  "properties": {
    "distance": 7.4,
    "elapsedTime": 2320
  },
  "user": {
    "username": "Alex"
  }
}

API Trigger Example with Custom Properties

{
  "audience": {
    "broadcast": true
  },
  "properties": {
    "promotion": "Holiday Sale",
    "discount": "30%"
  }
}

Message Title (Event Example)

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

Message Body (Event Example)

Hi {{ user.username }}, you ran {{ event.distance }} miles in {{ event.elapsedTime }} seconds.
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:
🎉 {{ 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.