Migrating your Giftnote email flows from Klaviyo to Attentive

Step-by-step guide to moving your Giftnote gift message and gift card emails from Klaviyo to Attentive, including merge fields, images, testing and common errors.

Written By Giftnote Team

Last updated About 1 hour ago

If you're moving your ESP from Klaviyo to Attentive, you can keep your existing Giftnote email designs. This guide walks through converting your Klaviyo templates into Attentive journeys: exporting the HTML, swapping merge fields, moving images, testing with real event data, and rolling out across multiple stores.

Before you start

  • Set up the Attentive integration first. See How to set up Attentive Integration.

  • Giftnote must be installed and connected to Attentive on every Shopify store that has its own Attentive account.

  • Attentive can't copy journeys between accounts. If you run several regional stores, you'll build each journey once, then copy it into each account manually (your Attentive rep can help).

  • Giftnote emails sent through Attentive are always transactional. Keep marketing content light.

Which flows move over

Klaviyo flow

Sent to

Attentive

Gift order confirmation (send now / send later / on delivery)

Gifter

Supported

Gift message delivered confirmation

Gifter

Supported

Gift message email

Recipient

Supported

Gift card purchased / gift card sent

Gifter

Supported

Gift card received (with or without a message)

Recipient

Supported

Backend-issued gift card

Customer

Supported

Gift card balance update

Customer

Not supported by the Attentive integration

Shortcut: use AI to convert your templates

You can use an AI assistant like ChatGPT or Claude to do most of the conversion for you. Copy the prompt below, paste it into the assistant, then paste your Klaviyo template HTML underneath it. Do one email at a time.

I'm migrating Giftnote email templates from Klaviyo to Attentive. Convert the Klaviyo HTML I paste below into Attentive-ready HTML. Return the full HTML, then a short list of anything I need to check.

Rules:
1. Merge fields. Attentive uses Liquid with Giftnote data under triggerEvent.custom. Replace:
   - {{ event.To|default:'' }} -> {{ triggerEvent.custom['To'] | strip | default: 'there' }}
   - {{ event.From|default:'' }} -> {{ triggerEvent.custom['From'] | strip | default: 'Someone special' }}
   - {{ event.Message|default:'' }} -> {{ triggerEvent.custom['Message'] | strip | escape | newline_to_br }}
   - event|lookup:'Delivery Method' -> triggerEvent.custom['Delivery Method'] (values: On Delivery, Send Now, Send Later)
   - event|lookup:'Gift Card Value' -> triggerEvent.custom['Gift Card Value'] (number only, no currency symbol)
   - event|lookup:'Gift Card Code' -> triggerEvent.custom['Gift Card Code']
   - Order items loop: {% for item in triggerEvent.custom['Order Items'] %} with item['Title'], item['Quantity'], item['Image'], item['URL'] (URL in capitals), item['Variant']
   - Use Attentive's filter syntax: default: 'text' (with a space), not Klaviyo's default:'text'. Never use Klaviyo's |lookup: filter.
2. Replace {{ organization.url }} and {{ organization.url|trim_slash }} with my store URL: [YOUR STORE URL]
3. Currency: put [YOUR CURRENCY SYMBOL] before the gift card value. Remove any $ typed in by Klaviyo if my currency is different. To trim .0 or .00 from whole amounts, use this exact snippet and never index a split array like [1]:
   {% assign gcv = triggerEvent.custom['Gift Card Value'] | strip %}{% if gcv contains '.' %}{% assign gcvparts = gcv | split: '.' %}{% if gcvparts.last == '0' or gcvparts.last == '00' %}{{ gcvparts.first }}{% else %}{{ gcv }}{% endif %}{% else %}{{ gcv }}{% endif %}
4. Add {{companyAddress}} as a small line at the bottom of the footer. Attentive requires it.
5. Remove the Klaviyo font @import line and the TRACKING_PIXEL_TOP / TRACKING_PIXEL_BOTTOM comments.
6. Fix any {% if %} that opens inside one HTML element and closes inside another, so each {% if %} and {% endif %} sit in the same element.
7. Wrap the gift message section in {% if triggerEvent.custom['Message'] != blank %} ... {% endif %} so it hides when there's no message.
8. If a "button" is plain text styled to look like a button with no link, turn it into a real link to my store URL.
9. List every image URL that starts with d3k81ch9hvuctc.cloudfront.net (hosted by Klaviyo) so I can move them to Shopify Files.
10. Keep the design, colours, layout and Outlook conditional comments the same.
11. Also give me an Attentive version of the subject line and preview text if I paste them.

Klaviyo HTML:
[PASTE YOUR KLAVIYO TEMPLATE HTML HERE]

Replace the three items in square brackets before sending. Always review the result and run the test in Step 6 before publishing. AI can make mistakes, and Attentive sends transactional emails even when there are errors in them.

Step 1: Export your Klaviyo templates

In Klaviyo, open each Giftnote flow email and export or copy its HTML. Keep one file per email so you can work through them one at a time.

While you're in there, remove Klaviyo-only code that won't work in Attentive:

  • The Klaviyo custom font import (@import url(https://static-forms.klaviyo.com/...))

  • The <!-- TRACKING_PIXEL_TOP --> and <!-- TRACKING_PIXEL_BOTTOM --> comments

Step 2: Move your images off Klaviyo

Images added in Klaviyo's editor are hosted in your Klaviyo account (URLs starting d3k81ch9hvuctc.cloudfront.net). If you close or clean up that account, those images break.

We recommend hosting them in Shopify Files:

  1. Download each image from the Klaviyo template.

  2. In Shopify admin, go to Content > Files > Upload files.

  3. Copy each file's link and replace the matching src in your HTML.

Shopify file links are public, so one set of links works across all your Attentive accounts. Don't delete these files later, or the emails will show broken images. Replace Klaviyo's default social icons the same way.

Step 3: Swap the merge fields

Attentive uses Liquid, and Giftnote data sits under triggerEvent.custom. Field names are case-sensitive and must match exactly.

Data

Klaviyo

Attentive

Recipient name

{{ event.To|default:'' }}

{{ triggerEvent.custom['To'] | strip | default: 'there' }}

Gifter name

{{ event.From|default:'' }}

{{ triggerEvent.custom['From'] | strip | default: 'Someone special' }}

Gift message

{{ event.Message|default:'' }}

{{ triggerEvent.custom['Message'] | strip | escape | newline_to_br }}

Delivery method

{{ event|lookup:'Delivery Method' }}

{{ triggerEvent.custom['Delivery Method'] }} (values: On Delivery, Send Now, Send Later)

Gift card value

{{ event|lookup:'Gift Card Value' }}

{{ triggerEvent.custom['Gift Card Value'] }}

Gift card code

{{ event|lookup:'Gift Card Code' }}

{{ triggerEvent.custom['Gift Card Code'] }}

Store link

{{ organization.url }}

No equivalent. Type your store URL in directly.

Why the extra filters

  • strip removes trailing spaces customers often leave in names ("Sam " becomes "Sam").

  • default gives a fallback so a missing name doesn't read "Hey !". Note Attentive's syntax is default: 'text', not Klaviyo's default:'text'.

  • newline_to_br keeps the line breaks in multi-line gift messages. Without it, a letter-style message collapses into one paragraph.

  • escape stops characters like < or & in a message from breaking the email.

Order items loop

Gift order events include an Order Items list. Each item has Title, Quantity, Image, URL, Variant, Price and Sku. Note URL is all capitals.

{% if triggerEvent.custom['Order Items'] %}
  {% for item in triggerEvent.custom['Order Items'] %}
    <img src="{{ item['Image'] }}" alt="{{ item['Title'] }}" width="100">
    <a href="{{ item['URL'] }}">{{ item['Title'] }} x {{ item['Quantity'] }}</a>
    {% if item['Variant'] %}Variant: {{ item['Variant'] }}{% endif %}
  {% endfor %}
{% endif %}

Check your Klaviyo HTML for {% if %} tags that open inside one element and close inside another. Klaviyo's editor often produces these. Keep each {% if %} and its {% endif %} inside the same element.

Gift card value and currency

Gift Card Value is a number only, with no currency symbol, so add the symbol yourself (for example &pound; for Β£). Klaviyo templates often have $ typed in, so check this on non-USD stores.

To show whole amounts cleanly (Β£50 rather than Β£50.0) while keeping pence where they exist:

{% assign gcv = triggerEvent.custom['Gift Card Value'] | strip %}{% if gcv contains '.' %}{% assign gcvparts = gcv | split: '.' %}{% if gcvparts.last == '0' or gcvparts.last == '00' %}{{ gcvparts.first }}{% else %}{{ gcv }}{% endif %}{% else %}{{ gcv }}{% endif %}

Don't use split with an index like gcv[1]. Attentive throws an "Index out of bounds" error when the value has no decimal point.

Branching by delivery method

Rather than building separate journey paths, you can vary the wording inside one email:

{% assign method = triggerEvent.custom['Delivery Method'] | strip %}
{% if method == 'Send Later' %}
  Your gift message is scheduled.
{% elsif method == 'On Delivery' %}
  Your gift message will be sent once the order is delivered.
{% else %}
  Your gift message is on its way.
{% endif %}

Attentive requires your company address in every email. Add this to your footer, and make sure your address is set in each Attentive account:

{{companyAddress}}

Step 5: Build the journey in Attentive

  1. Create a new journey and choose the matching Giftnote event as the trigger.

  2. Add a Send email step and paste your HTML into the HTML editor. Don't use the HTML block inside the drag-and-drop editor, as it doesn't support {% for %} loops.

  3. Mark the email as transactional.

  4. Set entry frequency to 0 hours, so someone who receives two gifts close together gets both emails.

  5. Update the subject line and preview text with Attentive merge fields too.

Check the right event and recipient

Each Giftnote event is sent to a specific person. For example, Placed Gift Order goes to the gifter. Make sure recipient-facing emails ("Hey Sam, Alex sent you a gift!") use an event that's sent to the recipient, not the gifter.

Fields also differ between events. A gift card sent without a message may not include From. Open the personalisation (macro) picker in the email editor to see exactly which fields your trigger event has.

Step 6: Test with real event data

Attentive doesn't have a "send test event" button, so test with a real order to your own email address. Place a test order (or a test gift card purchase for gift card flows) with a gift message.

To see everything Giftnote sent, temporarily add this to the top of your email, trigger a test, then remove it:

<pre style="font-size:11px;white-space:pre-wrap;">{{ triggerEvent.custom }}</pre>

A gift order event looks like this:

{
  "Message": "Happy birthday!\nHope you love it.\nAlex",
  "Delivery Method": "On Delivery",
  "Order Items": [
    {
      "Price": "39.0",
      "Quantity": 1,
      "Image": "https://cdn.shopify.com/.../product.jpg",
      "Title": "Example Product",
      "URL": "https://your-store.myshopify.com/products/example-product",
      "Sku": "EXAMPLE-SKU-01",
      "Variant": "Blue / Large"
    }
  ],
  "Order Skus": ["EXAMPLE-SKU-01"],
  "To": "Sam ",
  "From": "Alex "
}

Check that:

  • Names, message and line breaks display correctly

  • Product images, titles and links show in the order items section

  • Gift card emails show the code and the correct currency and amount

  • Every image loads and links go to your store

  • The email looks right on mobile

Liquid errors don't stop transactional emails from sending. A typo in a merge field goes straight to your customer, so test every journey before publishing.

Step 7: Go live

  1. Publish your Attentive journeys.

  2. On the same day, turn off the matching Klaviyo flows so customers don't get two emails, or none.

  3. Make sure Giftnote's native email notifications are also off (Settings > Notifications in the Giftnote app).

Rolling out to other stores

Treat your first completed store as the master copy. For each additional Attentive account:

  • Install Giftnote on that Shopify store and connect the Attentive integration

  • Copy each journey and email HTML across

  • Update the currency symbol in gift card emails

  • Update store links if the store uses a different domain

  • Confirm the company address is set in that account

  • Run one test order before publishing

Troubleshooting

Error or issue

Fix

Please include {{companyAddress}} in the email

Add {{companyAddress}} to the footer (Step 4).

Please remove or replace the following invalid macro(s)

That field isn't on the journey's trigger event. Check the macro picker and remove or replace it, including in the subject line.

Invalid liquid syntax: Index 1 out of bounds

Avoid indexing split values like [1]. Use the gift card value snippet above.

Product links all go to the homepage

Use item['URL'] in capitals, not item['url'].

Gift message shows as one long paragraph

Add | newline_to_br to the message field.

Wrong currency symbol

The value has no symbol. Update the symbol typed before it for that store.

Product image missing in Outlook desktop

Outlook desktop doesn't display .webp images. Use JPG or PNG product images where possible.

Customers receive two emails

Turn off the matching Klaviyo flow and Giftnote's native notifications.

Need a hand? Contact us at hello@giftnote.com.