Variables in Shopify Flow
Variables are placeholders that are replaced with values when a workflow runs. These variables describe the attributes of the customers, orders, and products that are involved in your workflows. For example, there are variables for the order number, order price, customer name, and so on.
Flow uses a different version of Liquid than Shopify themes, and can access any of the variables available through the GraphQL Admin API.
The names of most variables are self-describing. For example, the variable that displays the name of the product is {{ product.title }}
. When the message is sent, this variable is replaced with the name of the ordered product: Large Coffee Mug
.
Adding variables to actions
You can add variables to any text field that contains the Add variable link. Click the Add variable link beneath the relevant field, and then choose a variable from the list.
The variables in the Add variable list are filtered, so that you only see the variables that apply to the trigger that you've chosen. After you choose a variable from the list, it is properly formatted and added to the text box for you.
Flow supports almost all GraphQL Admin API fields.
Liquid variables
If you're a developer with experience writing Liquid code, then you can use Liquid to write your variables or edit variables that you insert using the Add variable link. To learn more, refer to GraphQL Admin API Reference.
Conditional and iteration tags
You can manually add Liquid variable tags to your workflow messages. You can use these tags to include more information in your messages.
For example, you can use a for loop
object to iterate through a list of objects, such as line items for an order. With these tags, you can create messages that contain details, such as the product title, SKU, price, and quantity for each line item in an order, and save your recipients from having to look up this information in your Shopify admin.
Flow supports the following Liquid conditional (or control flow) tags:
- if
- unless
- elsif/else
- case/when
- and/or (multiple conditions)
Flow also supports the following Liquid iteration tags:
Filters
Flow supports the following Liquid filters:
Filter name | Filter type |
---|---|
abs | Math |
append | String |
at_least | Math |
at_most | Math |
capitalize | String |
ceil | Math |
concat | Array |
date | Additional |
default | Additional |
divided_by | Math |
downcase | String |
escape | String |
first | Array |
floor | Math |
join | Array |
last | Array |
lstrip | String |
map | Array |
minus | Math |
modulo | Math |
newline_to_br | String |
plus | Math |
prepend | String |
remove | String |
remove_first | String |
replace | String |
replace_first | String | reverse | Array |
round | Math |
rstrip | String |
size | Array |
slice | String |
sort | Array |
split | String |
strip | String |
strip_html | String |
strip_newlines | String |
times | Math |
truncate | String |
truncatewords | String |
uniq | Array |
upcase | String |
url_encode | String |
where | Array |
Variable examples
For example, you want to create a workflow to send an email to an employee when a customer spends more than $500 on an order. You create a workflow using the Order created trigger, set a condition that is true if the order total is above $500, and use the Send internal email action. In the Message section of the Send internal email action, you use the following variables.
Input | Output |
---|---|
Please send a personal thank you note to {{ order.customer.firstName }} {{ order.customer.lastName }}({{ order.customer.email }}) for placing an order for $ {{ order.totalPriceSet.shopMoney.amount }}. | Please send a personal thank you note to Jeanne Dupont (jeanne@example.com) for placing an order for $763.42. |
You decide that you need to inform a staff member when product inventory is getting low and an order needs to be placed for more stock. You create a workflow that starts with the Inventory quantity changed trigger, and set a condition that is true if the inventory quantity prior is less than or equal to 10. In the Message section of the Send internal email action, you use the following variables.
Input | Output |
---|---|
Please reorder {{ product.title }}. Email owner@store.com to verify that they've received the purchase order. | Please reorder High Waist Leggings - Black. Email owner@example.com to verify that they've received the purchase order. |
You want to cancel orders that have a high risk level, but prefer for your staff to manually cancel the order. You create a workflow that starts with the Order created trigger, and set a condition that is true if the risk level of the order is equal to high. In the Message section of the Send internal email action, you use the following variables.
Input | Output |
---|---|
Our Shopify store has received an order with a high risk of fraud. We would like to cancel this order right away, before it is sent to production: {{ order.name }} {{ order.billingAddress.lastName }}, {{ order.billingAddress.firstName }} {{ order.email }} Please confirm the new order status. Thanks! |
Our Shopify store has received an order with a high risk of fraud. We would like to cancel this order right away, before it is sent to production: #1001 Dupont, Jeanne jeanne@example.com Please confirm the new order status. Thanks! |
For loop examples
When an order is received, it can be useful to send a message that contains the products ordered. You can do this by using for loop
, which repeatedly execute a block of code. Text fields that support variables also support for loops and the forloop object.
For example, you want to create a workflow that returns a list of all SKUs and quantities in an order. In the Message section of the Send internal email action, you use the following variables.
Input | Output |
---|---|
Order summary: {% for a in order.lineItems %} SKU: {{a.sku}} ( {{a.quantity}} ), {% endfor %} |
Order summary: 8987097979 (50) 8877778887 (3) 888998898B (1) |
You decide to add more information to the email, including the product name, SKUs, price per item, and the customer's shipping information. In the Message section of the Send internal email action, you use the following variables.
Input | Output |
---|---|
Order summary: {% for a in order.lineItems %} Product: {{a.title}} SKU: {{a.sku}} Price (per unit): $ {{a.originalUnitPriceSet.shopMoney.amount}} Quantity: {{a.quantity}} {% endfor %} |
Order summary: Product: High Waist Leggings - Black SKU: 8987097979 Price (per unit): $8.49 Quantity: 5 Product: Athletic Socks - Blue SKU: 888998898B Price (per unit): $5.61 Quantity: 2 |
You need to track items sold that are supplied by a specific vendor. In the Message section of the Send internal email action, you use the following variables and include an if
statement in your for loop
.
Input | Output |
---|---|
Acme product sold: {% for x in order.lineItems %} {% if x.vendor == 'acme-vendor' %} Product name: {{x.title}} SKU: {{x.sku}} {% endif %} {% endfor %} |
Acme product sold: Product name: High Waist Leggings - Black SKU: 8987097979 |
Complex data objects in Shopify Flow
Shopify Flow doesn't support outputting arrays and objects for the following reasons:
- Outputting data that isn't required is deprecated for GraphQL API, and it might create large query sizes that cause your workflow to fail.
- When new features are introduced, new API fields are added, which might break your workflow.
If too much data is sent automatically, the workflow fails. Instead of calling arrays and objects directly, loop over arrays and include only the fields that you want.
For example, instead of calling {{ order.lineItems }}
directly, use the following format to call specific fields. These examples include all the fields that would be included by calling the array or object directly. Copy and paste the fields that you need.
{% for li in order.lineItems %}
{% comment %}li.contract - omitted{% endcomment %}
{% for ca in li.customAttributes %}
{{ ca.key }}
{{ ca.value }}
{% endfor %}
{% for da in li.discountAllocations %}
{{ da.allocatedAmountSet.presentmentMoney.amount }}
{{ da.allocatedAmountSet.presentmentMoney.currencyCode }}
{{ da.allocatedAmountSet.shopMoney.amount }}
{{ da.allocatedAmountSet.shopMoney.currencyCode }}
{% endfor %}
{{ li.discountedTotalSet.presentmentMoney.amount }}
{{ li.discountedTotalSet.presentmentMoney.currencyCode }}
{{ li.discountedTotalSet.shopMoney.amount }}
{{ li.discountedTotalSet.shopMoney.currencyCode }}
{{ li.discountedUnitPriceSet.presentmentMoney.amount }}
{{ li.discountedUnitPriceSet.presentmentMoney.currencyCode }}
{{ li.discountedUnitPriceSet.shopMoney.amount }}
{{ li.discountedUnitPriceSet.shopMoney.currencyCode }}
{% comment %}li.duties - omitted {% endcomment %}
{{ li.fulfillableQuantity }}
{{ li.fulfillmentService.callbackUrl }}
{{ li.fulfillmentService.fulfillmentOrdersOptIn }}
{{ li.fulfillmentService.handle }}
{{ li.fulfillmentService.id }}
{{ li.fulfillmentService.inventoryManagement }}
{% comment %}rest of location omitted{% endcomment %}
{{ li.fulfillmentService.location.name }}
{{ li.fulfillmentService.productBased }}
{{ li.fulfillmentService.serviceName }}
{% for sm in li.fulfillmentService.shippingMethods %}
{{ sm.code }}
{{ sm.label }}
{% endfor %}
{{ li.fulfillmentService.type }}
{{ li.fulfillmentStatus }}
{{ li.id }}
{{ li.image.altText }}
{{ li.image.height }}
{{ li.image.id }}
{% comment %}li.image.metafield omitted{% endcomment %}
{% comment %}li.image.privateMetafield omitted{% endcomment %}
{{ li.image.width }}
{{ li.merchantEditable }}
{{ li.name }}
{{ li.nonFulfillableQuantity }}
{{ li.originalTotalSet.presentmentMoney.amount }}
{{ li.originalTotalSet.presentmentMoney.currencyCode }}
{{ li.originalTotalSet.shopMoney.amount }}
{{ li.originalTotalSet.shopMoney.currencyCode }}
{{ li.originalUnitPriceSet.presentmentMoney.amount }}
{{ li.originalUnitPriceSet.presentmentMoney.currencyCode }}
{{ li.originalUnitPriceSet.shopMoney.amount }}
{{ li.originalUnitPriceSet.shopMoney.currencyCode }}
{% comment %}rest of product omitted{% endcomment %}
{{ li.product.title }}
{{ li.quantity }}
{{ li.refundableQuantity }}
{{ li.requiresShipping }}
{{ li.restockable }}
{{ li.sellingPlan.name }}
{{ li.sku }}
{% for tl in li.taxLines %}
{{ tl.priceSet.presentmentMoney.amount | json }}
{{ tl.priceSet.presentmentMoney.currencyCode | json }}
{{ tl.priceSet.shopMoney.amount | json }}
{{ tl.priceSet.shopMoney.currencyCode | json }}
{{ tl.rate | json }}
{{ tl.ratePercentage | json }}
{{ tl.title | json }}
{% endfor %}
{{ li.taxable }}
{{ li.title }}
{{ li.totalDiscountSet.presentmentMoney.amount }}
{{ li.totalDiscountSet.presentmentMoney.currencyCode }}
{{ li.totalDiscountSet.shopMoney.amount }}
{{ li.totalDiscountSet.shopMoney.currencyCode }}
{{ li.unfulfilledDiscountedTotalSet.presentmentMoney.amount }}
{{ li.unfulfilledDiscountedTotalSet.presentmentMoney.currencyCode }}
{{ li.unfulfilledDiscountedTotalSet.shopMoney.amount }}
{{ li.unfulfilledDiscountedTotalSet.shopMoney.currencyCode }}
{{ li.unfulfilledOriginalTotalSet.presentmentMoney.amount }}
{{ li.unfulfilledOriginalTotalSet.presentmentMoney.currencyCode }}
{{ li.unfulfilledOriginalTotalSet.shopMoney.amount }}
{{ li.unfulfilledOriginalTotalSet.shopMoney.currencyCode }}
{{ li.unfulfilledQuantity }}
{% comment %}rest of variant omitted{% endcomment %}
{{ li.variant.title }}
{{ li.variantTitle }}
{{ li.vendor }}
{% endfor %}
{
"lineItems": [
{% for li in order.lineItems %}
{% if forloop.first != true %},{% endif %}
{
"contract": {
{% comment %}rest of contract omitted{% endcomment %}
"id": {{ li.contract.id | json }}
},
"customAttributes": [
{% for ca in li.customAttributes %}
{% if forloop.first != true %},{% endif %}
{
"key":{{ ca.key | json }},
"value":{{ ca.value | json }}
}
{% endfor %}
],
"discountAllocations": [
{% for da in li.discountAllocations %}
{% if forloop.first != true %},{% endif %}
"allocatedAmountSet": {
"presentmentMoney" : {
"amount": {{ da.allocatedAmountSet.presentmentMoney.amount | json }},
"currencyCode": {{ da.allocatedAmountSet.presentmentMoney.currencyCode | json }}
},
"shopMoney": {
"amount": {{ da.allocatedAmountSet.shopMoney.amount | json }},
"currencyCode": {{ da.allocatedAmountSet.shopMoney.currencyCode | json }}
}
}
{% endfor %}
],
"discountedTotalSet": {
"presentmentMoney" : {
"amount": {{ li.discountedTotalSet.presentmentMoney.amount | json }},
"currencyCode": {{ li.discountedTotalSet.presentmentMoney.currencyCode | json }}
},
"shopMoney": {
"amount": {{ li.discountedTotalSet.shopMoney.amount | json }},
"currencyCode": {{ li.discountedTotalSet.shopMoney.currencyCode | json }}
}
},
"discountedUnitPriceSet": {
"presentmentMoney" : {
"amount": {{ li.discountedUnitPriceSet.presentmentMoney.amount | json }},
"currencyCode": {{ li.discountedUnitPriceSet.presentmentMoney.currencyCode | json }}
},
"shopMoney": {
"amount": {{ li.discountedUnitPriceSet.shopMoney.amount | json }},
"currencyCode": {{ li.discountedUnitPriceSet.shopMoney.currencyCode | json }}
}
},
"duties": [
{% for duty li.duties %}
{% if forloop.first != true %},{% endif %}
{
{% comment %}rest of duties omitted{% endcomment %}
"id": {{ duty.id | json }}
}
{% endfor %}
],
"fulfillableQuantity": {{ li.fulfillableQuantity | json }},
"fulfillmentService": {
"callbackUrl":{{ li.fulfillmentService.callbackUrl | json }},
"fulfillmentOrdersOptIn": {{ li.fulfillmentService.fulfillmentOrdersOptIn | json }},
"handle": {{ li.fulfillmentService.handle | json }},
"id": {{ li.fulfillmentService.id | json }},
"inventoryManagement": {{ li.fulfillmentService.inventoryManagement | json }},
{% comment %}fulfillmentService.inventoryManagement - omitted {% endcomment %}
"productBased": {{ li.fulfillmentService.productBased | json }},
"serviceName": {{ li.fulfillmentService.serviceName | json }},
"shippingMethods": [
{% for sm in li.fulfillmentService.shippingMethods %}
{% if forloop.first != true %},{% endif %}
{
"code": {{ sm.code | json }},
"label": {{ sm.label | json }}
}
{% endfor %}
],
"type": {{ li.fulfillmentService.type | json }}
},
"fulfillmentStatus": {{ li.fulfillmentStatus | json }},
"id": {{ li.id | json }},
"image": {
"altText": {{ li.image.altText | json }},
"height": {{ li.image.height | json }},
"id": {{ li.image.id | json }},
{% comment %}li.image.metafield omitted{% endcomment %}
{% comment %}li.image.privateMetafield omitted{% endcomment %}
"width":{{ li.image.width | json }}
},
"merchantEditable": {{ li.merchantEditable | json }},
"name": {{ li.name | json }},
"nonFulfillableQuantity": {{ li.nonFulfillableQuantity | json }},
"originalTotalSet": {
"presentmentMoney" : {
"amount": {{ li.originalTotalSet.presentmentMoney.amount | json }},
"currencyCode": {{ li.originalTotalSet.presentmentMoney.currencyCode | json }}
},
"shopMoney": {
"amount": {{ li.originalTotalSet.shopMoney.amount | json }},
"currencyCode": {{ li.originalTotalSet.shopMoney.currencyCode | json }}
}
},
"originalUnitPriceSet": {
"presentmentMoney" : {
"amount": {{ li.originalUnitPriceSet.presentmentMoney.amount | json }},
"currencyCode": {{ li.originalUnitPriceSet.presentmentMoney.currencyCode | json }}
},
"shopMoney": {
"amount": {{ li.originalUnitPriceSet.shopMoney.amount | json }},
"currencyCode": {{ li.originalUnitPriceSet.shopMoney.currencyCode | json }}
}
},
"product": {
{% comment %}rest of Product omitted{% endcomment %}
"title": {{ li.product.title | json }}
},
"quantity": {{ li.quantity | json }},
"refundableQuantity": {{ li.refundableQuantity | json }},
"requiresShipping": {{ li.requiresShipping | json }},
"restockable": {{ li.restockable | json }},
"sellingPlan": {
"name": {{ li.sellingPlan.name | json }}
},
"sku": {{ li.sku | json }},
"taxLines": [
{% for tl in li.taxLines %}
{% if forloop.first != true %},{% endif %}
{
"priceSet": {
"presentmentMoney" : {
"amount": {{ tl.priceSet.presentmentMoney.amount | json }},
"currencyCode": {{ tl.priceSet.presentmentMoney.currencyCode | json }}
},
"shopMoney": {
"amount": {{ tl.priceSet.shopMoney.amount | json }},
"currencyCode": {{ tl.priceSet.shopMoney.currencyCode | json }}
}
},
"rate": {{ tl.rate | json }},
"ratePercentage": {{ tl.ratePercentage | json }},
"title": {{ tl.title | json }}
}
{% endfor %}
],
"taxable":{{ li.taxable | json }},
"title":{{ li.title | json }},
"totalDiscountSet": {
"presentmentMoney" : {
"amount": {{ li.totalDiscountSet.presentmentMoney.amount | json }},
"currencyCode": {{ li.totalDiscountSet.presentmentMoney.currencyCode | json }}
},
"shopMoney": {
"amount": {{ li.totalDiscountSet.shopMoney.amount | json }},
"currencyCode": {{ li.totalDiscountSet.shopMoney.currencyCode | json }}
}
},
"unfulfilledDiscountedTotalSet": {
"presentmentMoney" : {
"amount": {{ li.unfulfilledDiscountedTotalSet.presentmentMoney.amount | json }},
"currencyCode": {{ li.unfulfilledDiscountedTotalSet.presentmentMoney.currencyCode | json }}
},
"shopMoney": {
"amount": {{ li.unfulfilledDiscountedTotalSet.shopMoney.amount | json }},
"currencyCode": {{ li.unfulfilledDiscountedTotalSet.shopMoney.currencyCode | json }}
}
},
"unfulfilledOriginalTotalSet": {
"presentmentMoney" : {
"amount": {{ li.unfulfilledOriginalTotalSet.presentmentMoney.amount | json }},
"currencyCode": {{ li.unfulfilledOriginalTotalSet.presentmentMoney.currencyCode | json }}
},
"shopMoney": {
"amount": {{ li.unfulfilledOriginalTotalSet.shopMoney.amount | json }},
"currencyCode": {{ li.unfulfilledOriginalTotalSet.shopMoney.currencyCode | json }}
}
},
"unfulfilledQuantity": {{ li.unfulfilledQuantity | json }},
"variant": {
{% comment %}rest of variant omitted {% endcomment %}
"title": {{ li.variant.title | json }}
},
"variantTitle": {{ li.variantTitle | json }},
"vendor": {{ li.vendor | json }}
}
{% endfor %}
]
}