How to Add a Delivery Date Picker to Shopify Order Emails

2026-10-20 · shipping fulfillment

How to Add a Delivery Date Picker to Shopify Order Emails

Most "where is my order" emails arrive because the customer has no idea when to expect the package. Adding a delivery date picker to your storefront and surfacing that date in the order confirmation email sets expectations before the customer ever has to ask. This guide walks through a working no-app setup using theme snippets, cart attributes, and Shopify's order email variables—plus the point at which you should stop hand-rolling and reach for an app.

Why a Delivery Date in Order Emails Cuts WISMO Tickets

WISMO ("where is my order") tickets are the single largest support category for most small e-commerce stores. They spike not because deliveries are late, but because customers have no anchor date. A confirmation email that says "Order confirmed" leaves the customer guessing; one that says "Order confirmed — requested delivery: Friday, 14 March" gives them something to plan around.

The mechanics are simple:

The catch: Shopify's native checkout does not include a delivery date field. You have to build it with theme code and cart attributes. That's what the rest of this guide covers.

What You Can and Can't Do Natively in Shopify (No App Required)

Shopify's admin has no built-in delivery date picker. But the platform exposes two primitives that make a no-app build possible:

Capability Native support How it works
Date picker field on cart page Yes (via theme code) Standard HTML <input type="date"> plus a cart attribute
Date picker on Shopify checkout No Checkout is locked; you need a cart attribute or a checkout UI extension (Plus)
Save date to order Yes Cart attributes become order attributes automatically
Show date in order confirmation email Yes {{ order.attributes }} or a specific attribute key in the email template
Show date in packing slip / admin order page Yes Order attributes appear in the admin order detail and can be referenced in templates
Validation (block past dates, limit range) Partial Do it client-side with min/max on the input, plus a Liquid/JS guard

The practical takeaway: build the picker on the cart page, not the checkout. Cart attributes survive into the order and are readable in every notification email. Anything on the checkout page itself requires a Shopify Plus checkout UI extension, which is out of scope for most small stores.

Before You Start: What You'll Need

Step 1: Create a Delivery Date Snippet in Your Theme

Create a new file at snippets/delivery-date-picker.liquid. This snippet renders the date input and reads back any previously saved value so the field doesn't reset on cart updates.

{%- assign min_date = 'now' | date: '%Y-%m-%d' -%}
{%- assign max_date = 'now' | date: '%s' | plus: 1209600 | date: '%Y-%m-%d' -%}
<div class="delivery-date-picker">
  <label for="delivery-date">Preferred delivery date</label>
  <input
    type="date"
    id="delivery-date"
    name="attributes[Delivery date]"
    min="{{ min_date }}"
    max="{{ max_date }}"
    value="{{ cart.attributes['Delivery date'] }}"
  >
  <small>Choose a date up to 14 days from today.</small>
</div>

Two things matter here. The name="attributes[Delivery date]" is what tells Shopify to save the value as a cart attribute (and later an order attribute). The value="{{ cart.attributes['Delivery date'] }}" keeps the field populated after the customer updates their cart. The min/max attributes block past dates and cap the range at 14 days (1209600 seconds) — adjust the plus: value if you need a longer window.

Step 2: Add the Date Picker to Your Cart or Checkout Page

Open sections/main-cart.liquid (in Dawn it's sections/main-cart-items.liquid plus sections/main-cart-footer.liquid). Inside the cart <form> — the one that posts to /cart — render the snippet just above the checkout button:

{% render 'delivery-date-picker' %}

The field must live inside the cart form so its value is submitted with the rest of the cart. If you place it outside the form, the attribute won't save.

To make the date persist as the customer changes quantity, add a small listener in your theme's cart.js (or inline below the form):

document.querySelector('#delivery-date')?.addEventListener('change', (e) => {
  fetch('/cart/update.js', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ attributes: { 'Delivery date': e.target.value } })
  });
});

This saves the date to the cart the moment it's picked, so it survives page reloads and quantity edits.

Step 3: Save the Chosen Date to the Order

Nothing extra is required here — this is the part Shopify handles for you. Any cart attribute submitted with the cart becomes an order attribute at checkout. You can verify it worked by opening a test order in the admin: the attribute appears under Additional details on the order page.

Two checks worth doing:

Step 4: Insert the Delivery Date Into Your Order Confirmation Email

Go to Settings → Notifications → Order confirmation. In the email body, add a line after the order summary:

{% if order.attributes['Delivery date'] %}
  <p><strong>Requested delivery date:</strong> {{ order.attributes['Delivery date'] }}</p>
{% endif %}

The {% if %} guard matters: orders placed before you added the picker (or by customers who skip it) have no attribute, and an unguarded reference would print a blank line. If you want the date visible in the admin order list, add the same attribute to your packing slip template under Settings → Notifications → Packing slip.

If you use Shopify Email or a third-party ESP, the same order.attributes data is available in the order confirmation template as long as the email is triggered by Shopify's native notification.

Step 5: Test the Full Flow Before You Go Live

Place at least three test orders and check each stage:

  1. Cart page — pick a date, change quantity, confirm the date persists.
  2. Checkout — complete the order and confirm the date appears on the order detail page in admin.
  3. Email — confirm the date renders in the order confirmation email (use a real inbox, not the preview).
  4. Edge cases — place an order with no date selected and confirm the email doesn't show an empty line.
  5. Mobile — the native date picker behaves differently on iOS and Android; test on a real phone.

If any step fails, the usual culprits are a mismatched attribute key, the picker sitting outside the cart form, or a theme script resetting cart attributes.

When a No-App Setup Isn't Enough (and What to Use Instead)

The manual build has real limits. It can't validate against your actual inventory or cutoff times, it can't block dates you're closed (holidays, weekends), it can't offer time slots, and it can't show the picker on the checkout page itself unless you're on Shopify Plus. If you ship perishables, run a bakery, or offer local delivery windows, those gaps matter.

In that case, look at apps built for this:

Evaluate apps on three criteria: whether they write the date to the order as an attribute (so your email template keeps working), whether they support your fulfillment model (single date vs. time slots), and whether the free tier covers your order volume. If an app writes the date to a different field, you'll need to update the email template to match.

Conclusion

A delivery date picker built from a theme snippet and a cart attribute costs nothing and takes about an hour to ship. It gives every confirmation email a concrete date, which is the single cheapest way to reduce "where is my order" tickets. Start with the manual build, measure your WISMO volume for a month, and only move to a paid app if you need slot-based or inventory-aware scheduling.

FAQ

Will the delivery date picker work on Shopify's new checkout? The picker lives on the cart page, not the checkout, so it works on all plans. The date is captured as a cart attribute before the customer reaches checkout and carries through to the order.

Do I need Shopify Plus to show a delivery date in emails? No. Order attributes are available on every plan, and {{ order.attributes['Delivery date'] }} works in all native notification templates. Plus is only required if you want a picker inside the checkout itself.

What happens if a customer doesn't choose a date? The attribute is simply absent from the order. The {% if %} guard in the email template prevents an empty line, and your fulfillment team can treat missing dates as "no preference."