---
title: "Using Placeholders in Flows"
url: "https://help.productfruits.com/en/article/using-placeholders-in-flows"
language: "en"
last_updated: "2026-09-24T13:21:12.593Z"
---

# Using Placeholders in Flows

A placeholder is a small piece of live data you drop into a field in a Flow step, like `{{user.email}}`. When the step runs, Product Fruits swaps it for that user's actual value and leaves the rest of your text exactly as you typed it. So one Flow can send a personalized Slack message, email, or Jira issue to everyone who passes through it, instead of the same fixed text for all.

## Inserting a Placeholder

**In free-text fields** such as a subject, message body, or mapped value, type `{{` and a picker opens. It's grouped by where the data comes from and filters as you keep typing.

**In identifier fields**, some fields need a single value rather than a sentence, for example when you're looking up or matching a record. These show a source dropdown instead of the picker. Choose **User property**, **Enrollment variable**, **Fixed value**, or **Step output** (where the field allows it), and the placeholder is written for you.

**In Fixed value**, you get a plain text box with no picker. Anything you type there is still resolved, so you can type a placeholder by hand and it works.

## What You Can Insert

| Group | Written as | Example |
| --- | --- | --- |
| Built-in user fields | `{{user.<field>}}` | `{{user.email}}`<br>,<br>`{{user.firstname}}`<br>,<br>`{{user.role}}`<br>,<br>`{{user.signupat}}` |
| Your own user properties | `{{user.props.<name>}}` | `{{user.props.plan}}`<br>, or anything you send us. Nest with dots, like<br>`{{user.props.billing.tier}}` |
| Flow variables | `{{flow.vars.<name>}}` | `{{flow.vars.feedback}}`<br>, set earlier in the Flow by a card question, an AI step, or an Update Props step |
| Output of an earlier step | `{{steps.…}}` | Whatever an earlier step produced. Always insert these from the picker, which shows each step by name |
| Trigger data (Flows started by an event) | `{{trigger.payload.<field>}}` | `{{trigger.payload.comment}}`<br>, the feedback text that started the Flow |

The picker only offers steps that come earlier in the same Flow, so a step can never read its own output.

## Where Placeholders Work

Placeholders work in the value fields of a Flow step: subject, message, description, mapped field values, and any identifier you match a record on.

They resolve the moment the step runs, using the user's data as it is right then, not as it looked when you published the Flow.

A few fields name something instead of filling it in, and those don't resolve placeholders. If a step has a field like this, its article will point it out.

## Fallbacks and Formatting

You can add two optional extras after the name, each separated by `|`:

`{{name|format|fallback}}`

The format tells Product Fruits how to insert the value, and the fallback is the text to use when there's no value at all.

For example, `{{user.props.plan|raw|Free}}` inserts the user's plan, or the word "Free" if they don't have one. `{{user.props.plan||Free}}` does the same thing with the format slot left empty.

| Format | Use it when |
| --- | --- |
| `raw` | The default. The value goes in as it is. |
| `url` | The placeholder sits inside a link and the value could contain spaces or `&` |
| `json` | The placeholder sits inside a JSON body. Text gets its quotes, and a missing value becomes `null` |
| `html` | The placeholder sits inside HTML, such as an email body, so `<`and `&`can't break the markup. |

A few things to keep in mind:

-   The picker inserts the plain form only. To add a format or fallback, type the whole placeholder yourself.
-   Don't put spaces around the fallback text. Spaces are kept, so they'll show up in the result.
-   A fallback only kicks in when the value is missing entirely. If a property exists but is blank, it counts as present and renders as nothing.

## When a Placeholder Can't Be Resolved

If there's no value to fill in, the placeholder simply disappears. The `{{…}}` text is removed rather than sent on as-is.

This happens silently for a misspelled name, a property that user has never had, or a variable no earlier step set. For example, `Bug from {{user.props.company}}` goes out as "Bug from" for anyone without a company property.

**Tip:** Give a fallback to every placeholder that isn't guaranteed to have a value. And never build a required identifier, like a match value, from a property that might be missing.

## Example

Say a feedback-triggered Flow creates a support ticket with:

**Subject:** `Feedback from {{user.props.company|raw|an unknown account}} ({{user.email}})`  
**Description:** `{{trigger.payload.comment}}`

For a user with a company property, the subject arrives as:

> Feedback from Acme (jane@acme.com)

For a user without one, the fallback keeps the sentence intact instead of trailing off:

> Feedback from an unknown account (jane@acme.com)
