How to Add a Gift Message Field to Shopify Order Emails

2026-11-02 · support

Gift messages get lost the moment a customer hits checkout unless you capture them deliberately. Shopify doesn't include a gift message field out of the box, so most stores either bolt on a paid app or build it with cart attributes and a small theme edit. This guide walks through the second option: adding a gift message field to your cart or product page, saving it as an order attribute, and surfacing it in the order confirmation email using Liquid. You'll need edit access to your theme and notification templates, plus about 30–45 minutes for setup and testing.

Why Use Order Attributes Instead of a Paid Gift Message App

Cart attributes are built into Shopify's data model. Any input named attributes[Gift message] in a cart or product form is stored on the order and exposed to Liquid as order.attributes. That means no third-party script, no extra monthly cost, and no data leaving your store.

Paid gift message apps (Giftnote, Gift Message & Gift Wrap by Zengate, and similar) earn their fee when you need gift wrapping SKUs, scheduled delivery, or printed gift cards. If all you need is a text field that appears in the confirmation email and the admin order page, attributes do the job. Check current pricing on the Shopify App Store before deciding — app costs change, and a free tier may cover your needs.

A few practical differences:

One limitation to know: attributes are per-cart, not per-line-item. If a customer buys three items and wants a different message for each, you need line item properties instead, which are set on the product form and appear under each line in the email.

Step 1: Add the Gift Message Field to Your Cart or Product Page

You have two placement options. A cart-level field suits stores where most orders are single gifts. A product-level field suits stores selling multiple giftable items per order.

Cart-level (recommended for most stores): In your theme editor, open sections/main-cart-footer.liquid (Dawn and most Online Store 2.0 themes) or sections/cart-template.liquid (older themes). Find the <form action="{{ routes.cart_url }}" method="post" novalidate> block and place this above the checkout button:

<div class="cart-attribute__field">
  <label for="gift-message">Gift message (optional)</label>
  <textarea id="gift-message" name="attributes[Gift message]" maxlength="200" placeholder="Add a short note for the recipient"></textarea>
</div>

The name must be exactly attributes[Gift message]. Shopify uses that name to create the attribute; the bracket contents become the attribute's key.

Product-level: In snippets/product-form.liquid or sections/main-product.liquid, add inside the product form:

<p class="line-item-property__field">
  <label for="gift-note-{{ product.id }}">Gift note (optional)</label>
  <textarea id="gift-note-{{ product.id }}" name="properties[Gift note]" maxlength="200"></textarea>
</p>

Note the difference: properties[...] creates a line item property, which is what you want per product. Don't mix the two namespaces.

Add a maxlength so customers can't paste a 5,000-character essay into your email template. 200 characters fits comfortably in most email clients.

Step 2: Confirm the Field Saves as a Cart Attribute

Before touching email templates, verify the data is actually being captured. Add an item to the cart, type a test message, and go to /cart.js in your browser. You should see something like:

"attributes": { "Gift message": "Happy birthday, Sam!" }

If attributes is empty, check three things:

You can also confirm in the admin: open the draft order or abandoned checkout, and the attribute appears under "Additional details." Attributes save to the cart immediately, so a customer who abandons checkout still has the message attached.

Step 3: Edit the Order Confirmation Notification in Shopify

Go to Settings → Notifications → Order confirmation and click Edit code. The default template includes a product table and totals. Place the gift message block after the product table and before the totals, so it reads in the order a customer scans the email.

Wrap the block in a conditional so orders without a message don't show an empty heading:

{% if order.attributes["Gift message"] != blank %}
  <div style="margin: 20px 0; padding: 12px 16px; border-left: 3px solid #999; background: #f7f7f7;">
    <p style="margin: 0 0 6px; font-weight: bold;">Gift message</p>
    <p style="margin: 0; white-space: pre-wrap;">{{ order.attributes["Gift message"] }}</p>
  </div>
{% endif %}

white-space: pre-wrap preserves line breaks if a customer presses Enter in the textarea. Without it, multi-line messages collapse into one paragraph.

If you used line item properties instead, loop through them inside the line items loop:

{% for p in line.properties %}
  {% if p.first == "Gift note" %}
    <p><em>Gift note: {{ p.last }}</em></p>
  {% endif %}
{% endfor %}

Shopify's notification editor has a Preview button that renders the template with sample data. Use it before saving — Liquid syntax errors block the save anyway, but a missing conditional won't.

Step 4: Display the Gift Message with the Right Liquid Variables

The exact variable depends on where the attribute lives:

Data source Liquid variable Where it appears in admin
Cart attribute order.attributes["Gift message"] Order → Additional details
Line item property line.properties["Gift note"] Under the line item on the order
Note (legacy) order.note Order → Notes
Checkout custom attribute order.attributes["Key"] Order → Additional details

Two gotchas worth knowing. First, attribute keys are case-sensitive in Liquid — "Gift message" and "gift message" are different keys. Match the name attribute exactly. Second, if you rename the field later, old orders keep the old key. Either keep the key stable or add a second conditional for the legacy name.

To surface the message in other notifications, repeat the same conditional in Shipping confirmation, Order edited, and the New order internal alert (useful so your packing team sees the note). The order.attributes object is available in every order-related template.

Step 5: Test the Full Flow with a Real Test Order

Place a test order using Shopify's Bogus Gateway (enable it under Settings → Payments → Manage), or use a 100% off discount code on a live payment method. Then check each surface:

Test with a blank message too. The conditional should hide the block entirely — no empty grey box.

Common Issues and Quick Fixes

Conclusion

Adding a gift message field with cart attributes takes one theme edit, one notification edit, and a test order — no monthly app fee and no third-party script on your storefront. The field captures data Shopify already stores natively, so it flows into admin orders, exports, and every notification template you choose to update. Set it up once, test the blank and multi-line cases, and you've closed a common gap in the gifting experience.

FAQ

Will the gift message show up on the packing slip automatically? No. You need to add the same order.attributes["Gift message"] conditional to the packing slip template under Settings → Notifications. It's a two-minute edit and worth doing so your fulfilment team actually sees the note.

Can customers edit the gift message after placing an order? Not through the storefront. You can edit the attribute in the admin order page under Additional details, or use an order editing app. If edits are common, mention in the confirmation email that customers should reply to change their message.

Does this work with Shopify's new checkout extensibility? Yes. Cart attributes set on the cart page carry into checkout and are stored on the order regardless of checkout customisation. If you add the field inside checkout itself, use checkout UI extensions and read the value from order.attributes in the same way.