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

# Personalizing

> Personalizing is the way to adjust Experience content to match the User who is viewing an Chameleon Experience.

***

<a id="examples-global" />

## Examples for `global` helper

```javascript theme={null}
window.chameleonTheme = { background: "#1f1f24", primary: "#7856ff" };
window.chameleonContent = {
  more_help_demo_offering: {
    title: "Need a bit more help?",
    body: "We're invested in seeing you succeed",
    cta: "Book a demo",
    account_manager_calendly: "https://calendly.com/your-account-manager/book-a-demo",
  },
  ...
};
```

#### Book a demo with the User's account manager | `global` helper

```text theme={null}
# title
{{global "chameleonContent.more_help_demo_offering.title"}}

# body
{{global "chameleonContent.more_help_demo_offering.body"}}

# as the text of the Primary call to action button
{{global "chameleonContent.more_help_demo_offering.cta"}}

# as the "Additional action" field for the Primary call to action button
{{global "chameleonContent.more_help_demo_offering.account_manager_calendly"}}
```

#### Call a function (show a alert modal)

> Note that this function should be added to your product's codebase to provide extended functionality. In this example we will assume you have a `performAction` function defined like this:

```javascript theme={null}
//
// Example showAlert function added to your frontend codebase
//
window.performAction = (type, text, options) => {
  if(type === 'create_draft') {
    // Create the new draft and then route to the editing page
    //  Use the text as the title of the new Draft or to generate AI content
    //
    // From example [1], type='create_draft' and text='My first draft' (leaving options undefined)
    //
  } else if(type === 'create_import') {
    // Create a new data import and route to where the data import workflow starts
    //  Use the text as the input to GPT to generate the template
    //
    // From example [2], type='create_import', text='First Contacts' and options={ data_type: 'Contact', via: 'Chameleon' }
    //
  }
}
```

```text theme={null}
# [1] Create a new draft with this title
{{global 'performAction' 'create_draft' 'My first draft'}}

# Create a new draft with this Prompt to your draft generator
{{global 'performAction' 'create_draft' 'Generate placeholder text relating to a list of important items to remember for publishing content'}}

# [2] Create a new data import passing the data_type and via options
{{global 'performAction' 'create_import' 'First Contacts' data_type='Contact' via='Chameleon'}}

# [3] Using user properties in function calls
# ✅ Correct - user property without quotes (gets resolved to user's value)
{{global 'performAction' 'create_draft' first_name}}

# ✅ Correct - mixing user properties and literal strings
{{global 'performAction' 'create_import' company.name data_type='Contact' via='Chameleon'}}

# ❌ Incorrect - user property with quotes becomes literal text
{{global 'performAction' 'create_draft' 'first_name'}}

# ❌ Incorrect - nested braces not supported in function arguments
{{global 'performAction' 'create_draft' {{first_name}}}}
```

> **Important**: When passing user properties to functions, use the property name **without quotes or double braces**. Quoted values (`'text'`) are passed as literal strings, while unquoted properties (`user_property`) are resolved to the user's actual property value.

<a id="examples-delivery" />

## Examples using `delivery` helper

**More information about Deliveries can be found on the [Deliveries API reference](/apis/deliveries).**

A Delivery is a REST API for directly **triggering an Experience** for a **specific User**.

> With a Delivery you can include personalized content for that specific instance of that Delivery.
> Note that the `delivery` helper documented here only works for the specific Experience that was triggered via Delivery.
> Make sure to configure your Experience to **only** show Manually.

##### Example Delivery

```json theme={null}
{
  "id": "5f3c4232c712de665632a6d4",
  "model_type": "survey",
  "model_id": "5f3c4232c712de665632a6d5",
  "options": {
    "salutation": "Good day",
    "account_manager": {
      "name": "Julia",
      "calendly": "https://calendly.com/your-account-manager-julia/book-a-demo"
    }
  }
}
```

#### Book a demo with the User's account manager | `delivery` helper

```text theme={null}
{{delivery "salutation"}} {{first_name}}, we have a new product launching next month, can we show it off to you?
Good day Alice, we have a new product launching next month, can we show it off to you?

Book a demo with {{delivery "account_manager.name"}} ✨
# Book a demo with Julia ✨
```

```text theme={null}
# as the "Additional action" field for the Primary call to action button
{{delivery "account_manager.calendly"}}
```

```text theme={null}
# as the "Additional action" field for the Primary call to action button
{{delivery "account_manager.calendly"}}
```

<a id="examples-html" />

### Show a custom link | `html` helper

```text theme={null}
{{html 'Read' tagName='a' href='/read-more' target='read-more-tab' data-read-more='link' style='color: red'}}
# <a href="/read-more" target="read-more-tab" data-read-more="link style="color: red">Read</a>
```

<a id="examples-logic-if" />

### Use custom logic | `if` block helper

When the *condition* evaluates to truthy, the content in the `if` block is used, otherwise the `else` block is used.
A condition is a JS-like combination of a "left hand side", and "operator" and a "right hand side". If you're having
issues with this or have a use case that does not seem to be supported, please [Contact us](https://app.chameleon.io/help).

* Start an `if` block, use `{{if <CONDITION>}}`
* To end and `if` block use `{{/if}}`
* To add extra cases, use `{{elseif <CONDITION>}}`

Supported *condition* operators:

| Operator          | Description                                                                                              |
| ----------------- | -------------------------------------------------------------------------------------------------------- |
| `==`              | Equality: the values should be the same                                                                  |
| `!=`              | Inequality: the values should **not** be the same                                                        |
| `>`, `>=`         | Greater than + Greater than or equal: The left side should be greater than the right                     |
| `<`, `<=`         | Less than + Less than or equal: The left side should be less than the right                              |
| `&&`              | AND conjunction: The left side AND right side need to be true for the expression to be true              |
| <code>\|\|</code> | OR conjunction: The left side OR right side need to be true for the expression to be true                |
| `( )`             | Grouping: use parenthesis to group expressions to capture complex cases.                                 |
| `matches`         | Check if the left hand side                                                                              |
| `includes`        | Check if an array on the left hand side contains the value from the right hand side (same as `contains`) |
| `contains`        | Check if an array on the left hand side contains the value from the right hand side (same as `includes`) |

##### Basic examples

```handlebars theme={null}
# check for "truthy", "falsey", "equality", "inequality"
{{if plan.name}}You have a plan{{/if}}
{{if !plan.name}}You have no plan{{/if}}
{{if plan.name == 'gold'}}You have a Gold plan{{/if}}
{{if plan.name != 'gold'}}You do not have a Gold plan{{/if}}

# check the comparison of the left hand to the right hand side
{{if plan.spend > 500}}You spend more than 500{{/if}}
{{if plan.spend < 500}}You spend less than 500{{/if}}
{{if plan.spend <= 500}}You spend less than or equal to 500{{/if}}
{{if plan.spend >= 500}}You spend more than or equal to 500{{/if}}

# Check if an array contains an item
{{if plan.features includes "unlimited_widgets"}}You have Unlimited widgets{{/if}}
You have {{if plan.features includes "unlimited_widgets"}}Unlimited{{else}}limited{{/if}} widgets.

# does the left hand "Regex match" the right hand
{{if plan matches "helium|neon|argon"}}You have a Noble gas plan{{/if}}
{{if plan matches "gold|silver|copper"}}You have a Transition metal plan{{/if}}

# Use && for AND, || for OR to create complex conditions
{{if plan.spend <= 500 || plan.spend >= 1000}}You do not spend 501-999{{/if}}

# group conditions to evaluate them in complicated ways
{{if credits.remaining < 10 || (plan.spend < 500 && plan.upgrade_spend == plan.spend)}}
  You should probably contact us for more credits
{{/if}}

{{if plan}}You have a plan{{/if}}


```

##### An `if` block with a `else` block

> The data says spend is 734 and it's been 13 weeks (so the content in the "if block" will be used).

```handlebars theme={null}
{{if plan.spend > 500 && {time_ago started_on in="weeks"} > 12}}
  To get the most out of account, [book a review]({{account_info.csm_calendly}}) with your Account manager, {{account_info.csm_name}}.
{{else}}
  Check out these [additional resources](https://help.your-product.co/getting-started)
{{/if}}

# To get the most out of account, [book a review](https://calendly.com/acme-aria-j/30-min) with your Account manager, Aria Jones.
```

When the condition does not match, the content in the `else` case is used.

> The data says spend is 734

```handlebars theme={null}
{{if plan.spend > 1000}}
To get the most out of account, [book a review]({{account_info.csm_calendly}}) with your Account manager, {{account_info.csm_name}}.
{{else}}
Check out these [additional resources](https://help.your-product.co/getting-started)
{{/if}}

# Check out these [additional resources](https://help.your-product.co/getting-started)
```

An `elseif` can be used to capture a cascading set of conditions

```handlebars theme={null}
{{if !plan.spend}}
Start your free trial to use your widgets.
{{elsif plan.spend < 2050}}
Use the pre-built widget templates to work faster.
{{elsif plan.spend < 500}}
Start using your widget upgrades to widget
{{elsif plan.spend < 250}}
Upgrade to get more widgets.
{{else}}
Request a member of the Acme team to widgetize some stuff for you.
{{/if}}
```

##### To use an embedded Helper within the `if` condition, use *single curly braces*

This example assumes you have a `currentUser` variable attached to `window`
`window.currentUser = { id: '54s1', roles: { name: 'superadmin', items: ['invite_user', 'invite_admin'] } }`;

```handlebars theme={null}
{{if {global 'currentUser.roles.level'} == 'admin'}}
As an admin, you're in charge of your team's permissions
{{elsif {global 'currentUser.roles.level'} == 'superadmin'}}
As the owner of your account, you're in charge of your team's admins
{{/if}}
```

```handlebars theme={null}
{{if {global 'currentUser.roles.level'} includes 'invite_user'}}
Invite your teammates on the [Team page](/settings/team).
{{elsif {global 'currentUser.roles.level'} includes 'invite_admin'}}
As the owner of your account, you're in charge of your [Team's admins](/settings/admins).
{{/if}}
```

<a id="examples-filter" />

## Segmentation filter conditions | `filter` helper

Sometimes you need to do something especially complicated that can't be captured with `==` or `&&`; enter the `filter` helper.
You can use any of the [Segmentation filter expressions](/concepts/filters) and many of the simple
conditions on user properties can be handled with `filter`.

```handlebars theme={null}
{{if plan.spend > 500}}Your monthly bill is greater than 500{{/if}}

# as a filter
{{if {filter prop='plan' op='gt' value='500'}}}Your monthly bill is greater than 500{{/if}}

```

<a id="example-user-data" />

<a id="custom-helpers" />

## Custom helpers

* Your developers can define the implementation for a custom helper to fit you merge tag needs. A merge tag helper is simply a function that takes arguments (args) and options (opts) and outputs a string.
* A merge tag follows the typical "mustache syntax" like the other examples above `{{helper_name ["arg1", "arg2", ...] [option1="value1" option2="value2"]}}`
* To define a new merge tag pass the name and callback function to `chmln.lib.personalize.Mustache.addHelper`
* Please [Contact us](https://app.chameleon.io/help) if you need any help or inspiration

This is a fully working example 🎉

```javascript theme={null}
chmln.on('after:account', () => {
  chmln.lib.personalize.Mustache.addHelper('hello', (args, opts) => {
    // [1] args=['Alice'] opts={}
    // [2] args=['Alice'] opts={ prefix: '👋' }
    // [3] args=['foo'] opts={ prefix: '👋' }
    // [3] args=['Product manager'] opts={ postfix: '!!' }

    const name = args[0];

    return `${opts.prefix || 'Hey'} ${name}${opts.postfix || ''}`;
  });
});
```

Now, to use the merge tag (based on the [example data ↑](/concepts/personalizing#example-user-data))

```text theme={null}

{{hello first_name}} # [1]
# Hey Alice

{{hello first_name prefix="👋"}} # [2]
# 👋 Alice

{{hello 'foo' prefix="👋"}} # [3]
# 👋 foo   *Caution: using a quoted argument means a literal string is passed*

{{hello role postfix="!!"}} # [4]
# Hey Product manager!!

{{hello 'role' postfix="!!"}}
# Hey role!!   *Caution: using a quoted argument means a literal string is passed*
```
