Skip to content
Personalization

Variable Bindings

Connect user attributes and event properties to component properties for dynamic, personalized content.

Variable Bindings

Variable bindings let you insert real user data into your flow screens at render time. Instead of showing static text, you connect component properties to user attributes or event properties -- and the SDK resolves them on the device before the screen appears.

How bindings work

A binding is an expression embedded in a component property value. When the SDK renders the screen, it replaces each expression with the actual value from the current user's context.

For example, a text component with the value:

Welcome back, {{user.firstName}}!

Renders as:

Welcome back, Sarah!

The SDK evaluates bindings client-side, so the resolved content never leaves the device.

Binding syntax

Bindings use double curly braces with a source prefix and a property path:

{{source.propertyPath}}

Binding sources

SourcePrefixWhere data comes from
User attributeuserAttributes passed via the SDK identifyUser call.
Event propertyeventProperties attached to the event that triggered the flow.

Examples

ExpressionResolves to
{{user.firstName}}The user's firstName attribute.
{{user.plan}}The user's plan attribute.
{{event.productName}}The productName property from the triggering event.
{{user.company.name}}Nested attribute access using dot notation.

Adding a binding in the dashboard

  1. Select a component on the screen editor.
  2. Click the binding icon next to a text property (e.g., the text content of a Text component or the label of a Button).
  3. Choose the binding source: User Attribute or Event Property.
  4. Select or type the attribute key.
  5. Optionally set a fallback value and a format.

You can also type the binding expression directly into any text property field using the {{source.path}} syntax.

Fallback values

When the SDK cannot resolve a binding -- for example, the user does not have a firstName attribute set -- it uses the fallback value you define. If no fallback is set, the binding resolves to an empty string.

Always set fallback values for bindings that may not be available for all users:

BindingFallbackResult if attribute is missing
{{user.firstName}}there"Welcome back, there!"
{{user.plan}}Free"Your current plan: Free"
{{event.discount}}10%"Save 10% today"

If a binding has no fallback and the attribute is missing, the expression resolves to an empty string. This can result in awkward text like "Welcome back, !" -- always set fallback values for user-facing content.

Formatting options

Bindings support format modifiers that transform the resolved value before rendering. Add a format by appending a pipe character after the property path:

{{source.propertyPath|format}}

Available formats

FormatInputOutput
currency49.99$49.99
percentage0.2525%
number12345671,234,567
date2026-06-15T00:00:00ZJun 15, 2026
uppercaseproPRO
lowercaseENTERPRISEenterprise

Formatting examples

Your balance: {{user.accountBalance|currency}}
→ Your balance: $1,249.00

You have completed {{user.progress|percentage}} of onboarding
→ You have completed 75% of onboarding (attribute value: 0.75)

Member since {{user.signupDate|date}}
→ Member since Jan 15, 2026

Current plan: {{user.plan|uppercase}}
→ Current plan: PRO

Currency and number formats respect the user's locale when available.

Where bindings work

You can use binding expressions in most string-type component properties:

  • Text content -- the primary text of Text, Title, and Subtitle components.
  • Button labels -- the label text of Button components.
  • Image URLs -- dynamically load different images per user.
  • Placeholder text -- input field placeholders.
  • Link URLs -- web URLs opened from buttons.
  • Any string property -- if the property accepts a string, it supports bindings.

Bindings are evaluated after localization. If you localize a screen, put binding expressions in the translated text too -- the SDK resolves bindings regardless of language.

Combining multiple bindings

A single property can contain multiple binding expressions mixed with static text:

Hi {{user.firstName}}, your {{user.plan|uppercase}} plan renews on {{user.renewalDate|date}}.

Each expression is resolved independently.

Best practices

  • Set fallbacks for every user-facing binding. Not all users will have every attribute.
  • Use descriptive attribute keys. firstName is clearer than fn when building flows months later.
  • Test with missing data. Preview your flow without attributes to see how fallbacks render.
  • Keep bindings in localized text. When translating screens, include the same binding expressions in the translated strings.
  • Send attributes before flows trigger. Call identifyUser with up-to-date attributes before the SDK evaluates flow triggers, so bindings have fresh data.

On this page