Before you start
Things you need to know:
The information in this article is best suited for advanced users with some HTML knowledge.
For an introduction to the use of Jinja in Cart layouts specifically, see Cart layout editing using Jinja.
Product merges
Products can be iterated using a for loop: {% for product in products %}.
The merge codes below assume you use product as your loop variable name.
Each product has the following attributes:
Merge code | Description |
{{ product.img }} | Image URL |
{{ product.img_tn }} | Image thumbnail URL Not always available. |
{{ product.n }} | Name |
{{ product.desc }} | Description Only certain cart types provide this. |
{{ product.prid }} | Product ID |
{{ product.qty }} | Quantity in the cart. |
{{ product.u }} | URL of the product page. |
{{ product.up }} | Unit price as string, including currency symbol. |
{{ product.rup }} | Regular unit price, as string, including currency symbol. If available |
{{ product.uv }} | Unit value (price) as number. |
{{ product.ruv }} | Regular unit value (price) as number. |
{{ product.sku }} | Product SKU If available |
{{ product.opt }} | Dictionary of shopper-specific choices for this product. For example, If available. Learn more in the section Custom fields. |
{{ product.ex }} | Dictionary of product-specific extra data for this product. For example, If available. Learn more in the section Custom fields. |
{{ product.stock }} | Stock level If available. |
{{ product.curr }} | ISO 4217 currency code, for example, GBP , USD. If available. |
{{ product.lang }} | Language If available. |
{{ product.sbr }} | Site Brand. Optionally used to separate products from different site brands or storefronts. If available. |
{{ product.cat }} | Array of categories for the product. |
{{ product.cat[n].id }} | ID of tag value n in the list of categories, for example, cameras-and-tripods. |
{{ product.cat[n].name }} | Name of tag value n in the list of categories, for example, Cameras and Tripods. |
{{ product.cat[n].gid }} | Tag group in the list of categories, for example, shoe-size. |
{{ product.cat[n].groupname }} | Tag group name of category n in the list of categories, for example, Shoe Size. |
{{ product.social_proof.browsed }} | The number of people who have browsed this product in the period specified in the SmartBlock Options tab. If enabled. |
{{ product.social_proof.carted }} | The number of people who have carted this product in the period specified in the SmartBlock Options tab. If enabled. |
{{ product.social_proof.purchased }} | The number of people who have purchased this product in the period specified in the SmartBlock Options tab. If enabled. |
{{ product.related }} | An array of related products that have been loaded into Fresh Relevance with the product import. If enabled. Requires the Related Product add-on. Learn more in the section Related Products. |
{{ product.old_uv }} | Only available when using the Price Drop Products data source in a product recommendation SmartBlock. This field is an array of prices that this shopper saw this product at before it reduced in price. The current price is available in the The uv field is always the current price for products from the Price Drop Products data source, even if the Prioritize Person data option is selected. |
{{ product.variants[vid] }} | The data for each of the product's SKU-level variants, if there are any, is stored in an object in
There's also a Jinja function called getVariantFromProduct that merges the special variant data with the base product to get the complete product variant object. For example, |
Common merge fields for layouts and SmartBlocks
These are different to merge fields you might use with your messaging provider.
Here is a selection of common merge fields.
Merge Code | Description |
{{ products }} | Array of products. |
{{ cart.cp }} | Cart Price. Only available in cart layouts for cart abandon and purchase complete triggers. |
{{ cart.o_num }} | Cart order number. Only available in cart layouts for cart abandon and purchase complete triggers. |
{{ person.email }} | Email address of the visitor. |
{{ person.mobile }} | Mobile number of the visitor. |
{{ products|length }} | Number of products the layout displays. |
{{ trigger.contact_type }} | Reason for contact - cart layout and trigger field mapping only:
|
{{ trigger.active_action_index }} | Step within the trigger program - cart layout and trigger field mapping only. Usually 1 for first message send, 3 for second send, 5 for third send.
This can be used for various purposes. For example, to use different Google Analytics campaign codes in the cart layout for the different steps of a multi-step campaign, you would specify different Google Analytics merges near the top of the cart layout. |
{{ currentProduct }} | When a Recommendation SmartBlock is placed on a product page this parameter contains the details of that product. Use of this parameter must be enabled on the SmartBlock Options tab and product option data ( |
{{ person.ff }} | Form factor of the last device used. Possible values are pc, tablet, or mobile. For SmartBlock content this is the visitor’s current device. |
{{ currentDevice.ff }} | Form factor of the current device. Possible values are pc, tablet, or mobile. Only available for SmartBlock content. |
{{ currentDevice.isProxy }} | Indicates whether the content is being loaded by either the Gmail or iOS privacy protection proxy. If so, then some data such as location and some rules such as current time may not be available. Only available for SmartBlock content. |
Trigger merge fields
Merge fields to access data about the trigger being sent.
These fields are only available in cart layouts.
Merge Code | Description |
{{ trigger.contact_type }} | Reason for contact.
|
{{ trigger.active_action_index }} | Step within the trigger program - cart layout and trigger field mapping only. Usually 1 for first message send, 3 for second send, 5 for third send.
This can be used for various purposes. For example, to use different Google Analytics campaign codes in the cart layout for the different steps of a multi-step campaign, you would specify different Google Analytics merges near the top of the cart layout. |
{{ trigger.name }} | Name of the trigger being sent. |
{{ trigger.key }} | ID of the trigger being sent. |
{{ trigger.template_id }} | ID of the ESP template being sent. |
Google Analytics merges
{% if trigger.active_action_index < 2 %}
{% set ga_campaign_code='ga_for_first_email' %}
{% else %}
{% set ga_campaign_code='ga_for_second_email' %}
{% endif %}
Replace ga_for_first_email
and ga_for_second_email
with the campaign codes you want to use.
You can then use these codes in links. For example, replace:
<a href={{ product.u | set_ga_tracking( utm_campaign='tms-cart-1' , utm_medium='email' , utm_source='tms' ) }}>
with:
<a href={{ product.u | set_ga_tracking( utm_campaign=ga_campaign_code , utm_medium='email' , utm_source='tms' ) }}>
Person merges
You can access properties of the person using these merge codes under the namespace person.
Personalization using Personally Identifiable Information (PII)
Using name personalization (or other PII) in personalization can be an effective tactic, but it is best applied in triggered emails or email marketing campaigns where the identity of the recipient is reasonably certain.
You should be particularly cautious about including PII in personalized content on your website. Fresh Relevance joins together streams of activity from different web sessions. This means that if consumers are using shared devices, then they might see the PII from another user of the same device. This would usually be another member of the same family, but may cause concern, confusion and even complaints, so we recommend you do not use PII in web personalization.
Merge code | Description |
{{ person.email }} | |
{{ person.mobile }} | Mobile |
{{ person.n}} | Full Name |
{{ person.fn }} | First Name |
{{ person.ln }} | Last Name |
{{ person.extend }} | Person extension data. Dictionary of custom data attached to the person, for example, If available. Learn more in the section Custom fields. |
Custom fields
The following custom data is captured from your website and is available to merge using these codes.
Merge Code | Sample Data | Type |
{{ product.opt.test }} | test value | str |
{{ product.opt.colour }} | rainbow | str |
{{ product.ex.shopify_alt_images }} | [{'src': 'https://cdn.shopify.com/s/f... | list |
{{ product.ex.test }} | test value | str |
{{ product.ex.colour }} | rainbow | str |
{{ product.ex.custom_bulb }} | ['A60', 'B50'] | list |
{{ product.ex.custom_bulbs }} | A50 | str |
{{ product.ex.my_fields_style }} | ['Casual', 'Formal', 'Semi Casual'] | list |
{{ product.ex.n }} | 163cm | str |
{{ product.ex.Size }} | 163cm | str |
{{ person.extend }} | None | NoneType |
Analytics
Analytics for the person are available under the namespace analytics.
Learn more in Analytics for email marketing.
Merge Code | Description |
{{ analytics.purchased_qty_90 }} | Total number of products purchased. Integer: 23 |
{{ analytics.purchased_price_90 }} | Total value of products purchased. (Currency) value: 20.55 |
{{ analytics.purchased_datetime_90 }} | Last purchased date-time. Accurate to about 1 hour: 2017-11-05T13:15:30Z |
{{ analytics.lapsed_buyer_90 }} | This is a previous buyer who has not bought over a period of 90 days. Boolean: True or False You must also choose Purchased Products for 1 Year. |
{{ analytics.purchased_qty_365 }} | Total number of products purchased. Integer number: 23 |
{{ analytics.purchased_price_365 }} | Total value of products purchased. (Currency) value: 20.55 |
{{ analytics.purchased_datetime_365 }} | Last purchased date-time. Accurate to about 1 hour: 2017-11-05T13:15:30Z |
Current device merge fields
SmartBlock content is able to access information about the visitor’s current device using the currentDevice
field.
This data is not available for trigger layouts.
Merge Code | Description |
{{ currentDevice.ff }} | Current device's form factor. Possible values: pc, tablet or mobile. |
{{ currentDevice.os }} | Current device's operating system. Possible values include Windows 10, Mac OS X and iOS. |
{{ currentDevice.browser }} | Current device's browser. Possible values include Chrome, Mobile Safari and Firefox. |
{{ currentDevice.vendor }} | Current device's Vendor. Possible values include Apple, Samsung and Huawei. Only available for mobile and tablet devices. |
{{ currentDevice.model }} | Current device's model. Possible values include iPhone, iPad and Pixel 2. Only available for mobile and tablet devices. |
{{ currentDevice.isProxy }} | Indicates whether the content is being loaded by either the Gmail or iOS privacy protection proxy. If so, then some data such as location and some rules such as current time may not be available. There will also be no other |
{{ currentDevice.isAppleMailProxy }} | Indicates whether the content is being loaded by the Apple iOS privacy protection proxy. If so, then some data such as location and some rules such as current time may not be available. There will also be no other |
Geocoded location from IP Address or CRM person import
If Geocode by IP is enabled, then extra data about the predicted location of the user can be accessed using location.
The IP based geolocation is only a prediction based on the user’s IP address and may not be correct, especially for the more specific fields such as the postcode and city.
The location field can also be populated by a location import.
Learn more in Import person data.
Merge Code | Description |
location.type | Identifies where this location data came from. Either ip or import. |
location.country.name | The human readable name of the users country in English: United States |
location.country.iso_code | The country code for the users current country: US or GB |
location.continent.name | The human readable name of the users continent in English: Europe |
location.continent.code | The code for the users current continent: EU |
location.city.name | The name of the city where the user is: New York |
location.time_zone | The time zone string of the user: America/New_York |
location.postal.code | The predicted zip code/postcode of the user: SO16 |
Location helpers
To convert a date to the user’s local time zone — based on their predicted location — you can use the convertUTCTimeToTimezone
helper.
Below is an example of converting the time 10:30 UTC to the user’s local time zone. This could be useful for displaying shop open times to the customer in their time zone.
{{ "10:30"|convertUTCTimeToTimezone(location) }}
If the location or time zone of the user can't be found, then the result stays in UTC. You can add a fallback time zone by passing it in as the second parameter. This fallback is used if the user’s location hasn't been found or if we don't know the time zone for their location.
{{ "10:30"|convertUTCTimeToTimezone(location, "America/New_York") }}
To show the time in a custom format pass in a moment format string in as the third parameter. For example, the below prints the time without the : between the hour and minutes, using the format string HHmm.
{{ "10:30"|convertUTCTimeToTimezone(location, null, "HHmm") }}
There is also the helper convertToTimezone that takes a date and converts it to the local time zone. The second parameter is an optional fallback time zone, used if the location doesn't contain any time zone data. The third parameter is an optional format string. If no format is provided, a moment date object is returned instead.
{{ "2022-04-23T14:09:12.837Z"|convertDateToTimezone(location, "America/New_York", "LLLL") }}
Full list of available location fields
Below is an example of the full location object's structure, showing all the fields which may be available:
{
continent: {
code: 'EU',
name: 'Europe'
},
country: {
is_in_european_union: true,
iso_code: 'GB',
name: 'United Kingdom'
},
city: {
name: 'Southampton'
},
location: {
accuracy_radius: 5,
latitude: 50.9463,
longitude: -1.4055
},
postal: {
code: 'SO16'
},
time_zone: 'Europe/London'
}
The field location.accuracy_radius
indicates how far from the specified location the user may be in km.
Person signal merges
These store details of significant person actions.
Merge Code | Description |
{{ person.signals }} | Signals for this shopper, for products browsed, abandons, or purchases. Contact your Account Manager or client support for more information.
Person.signals is a dictionary structured like this: <signal_type><list of signals> For example: { The array of each type of signal contains a maximum of 30 signals, which can be increased for you by Support, provided your signals do not contain an unusually large amount of data. |
{{ person.actions }} | Actions for this shopper, for example, emails sent. Contact your Account Manager or client support for more information. |
Available person signals
Below is a list of the signals that can be stored in the person record. The merge code is for an array of signal objects of that type.
Signal Name | Merge Code | Description |
Product Details (pd) | {{ person.signals.pd }} | When a shopper visits a product details page. |
Browse Abandon (ba) | {{ person.signals.ba }} | When someone browses products but doesn't add anything to their cart or make a purchase. |
Cart Abandon (b) | {{ person.signals.b }} | When someone carts some products but doesn't purchase anything. |
Purchase Complete (t) | {{ person.signals.t }} | When someone makes a purchase. |
Session Expired (se) | {{ person.signals.se }} | When a visitor to your website leaves. |
Custom (cu) | {{ person.signals.cu }} | Custom signal, raised by JavaScript. |
Cart (c) | {{ person.signals.c }} | When a visitor adds a product to their cart. |
Price Drop (pcv) | {{ person.signals.pcv }} | A product browsed by this person has dropped in price. |
Back In Stock (pcs) | {{ person.signals.pcs }} | A product browsed by this person has come back into stock. |
Data Capture Interaction (popover) | {{ person.signals.popover }} | When a shopper interacts with a Data Capture SmartBlock.
The valid interaction types are show which is when a shopper is shown a Data Capture Popup/Form, dismiss which is when they close it and submit which is where the fill in the form and submit it.
The type of interaction is stored in the
Example: person.signals.popover[n] = { |
Cart Changed (cc) | {{ person.signals.cc }} | When cart contents are changed. |
Message Sent (ms) | {{ person.signals.ms }} | Message sent. Currently SMS only. |
Message Delivered (md) | {{ person.signals.md }} | Message delivered. Currently SMS only. |
Message Inbound (mi) | {{ person.signals.mi }} | Inbound message received. Currently SMS only. |
There are also other signals which are used only by UBX.