How to Add a Delivery Date Picker to Shopify Cart Without an App

2026-10-29 · shipping fulfillment

How to Add a Delivery Date Picker to Shopify Cart Without an App

A delivery date picker on the cart page lets customers choose when they want their order to arrive before they check out. Most "delivery date" apps charge a monthly fee and inject code across your theme anyway. You can build the same thing yourself with a date input, a hidden cart attribute, and a few lines of Liquid and JavaScript — no recurring cost, and you keep full control of the markup. This guide walks through the whole build in Shopify's current Dawn-based themes (Dawn, Refresh, Craft, Sense and similar), with notes for older themes like Debut and Brooklyn.

Why Add a Delivery Date Picker to Your Shopify Cart (and Why Skip the App)

A date picker does two practical things. It cuts down on "where is my order" emails, because customers have told you in advance when they need the parcel. And it lets you manage expectations around weekends, holidays, and made-to-order items without writing a banner every week.

Skipping the app is worth considering when:

The tradeoff is that you maintain it. If you switch themes, you redo the snippet. If you need blackout dates synced to a calendar, or per-product lead times, an app starts to look cheaper than the hours you'd spend building it.

What You'll Need Before You Start

Step 1: Add the Date Picker to Your Cart Template

Open your cart section. In Dawn and its siblings that's sections/main-cart-items.liquid. In older themes it's templates/cart.liquid.

Add this block near the cart footer, just above the checkout button:

<div class="delivery-date-wrapper">
  <label for="delivery-date">Preferred delivery date</label>
  <input
    type="date"
    id="delivery-date"
    name="attributes[Delivery date]"
    min=""
    required
  >
  <small>Orders placed before 2pm can usually be delivered within 2 business days.</small>
</div>

Two details matter here. The name="attributes[Delivery date]" is what turns this into a cart attribute — Shopify stores it on the cart and copies it to the order automatically. And the empty min="" gets filled in by JavaScript so customers can't pick yesterday.

Now add the script. Put it at the bottom of the same section file, inside a <script> tag, or in assets/cart.js if your theme has one:

document.addEventListener('DOMContentLoaded', function () {
  const input = document.getElementById('delivery-date');
  if (!input) return;

  const leadDays = 2; // change to your lead time
  const min = new Date();
  min.setDate(min.getDate() + leadDays);

  // skip weekends if you don't deliver on them
  while (min.getDay() === 0 || min.getDay() === 6) {
    min.setDate(min.getDate() + 1);
  }

  const iso = min.toISOString().split('T')[0];
  input.min = iso;
  input.value = iso;
});

That handles the minimum date and a sensible default. If you need to block specific holidays, add an array of ISO date strings and loop past them the same way you skip weekends.

Step 2: Save the Chosen Date to the Cart Line Item

Here's the part most tutorials skip. If you put the input inside the cart form, it submits as a cart attribute when the customer clicks checkout — but in Dawn, the cart form posts via AJAX and the attribute only saves if the field is inside the form element. Two reliable approaches:

Option A — cart attribute (recommended for one delivery date per order). Wrap the input in the existing <form action="/cart" method="post"> on the cart page. On submit, Shopify saves it. To make it stick even if the customer changes quantity later, add a listener that posts the value to /cart/update.js:

input.addEventListener('change', function () {
  fetch('/cart/update.js', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ attributes: { 'Delivery date': input.value } })
  });
});

Option B — line item property (needed if each product can have its own date). Use name="properties[Delivery date]" inside the cart line item loop instead, and add a hidden id field for the line item key. This is the right choice for bakeries where each cake has its own pickup date, but it means one date field per row and more markup.

For most small stores, Option A is the correct call. The attribute is visible in the cart, on the order, and in the admin's order detail page under Additional details.

Step 3: Show the Delivery Date on Orders and Notifications

Cart attributes flow to the order automatically, but they don't appear in notification emails unless you add them. In Settings → Notifications → Order confirmation, find the line items table and add:

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

Repeat for Shipping confirmation and Order canceled if relevant. The attribute also shows on the order page in admin, in the packing slip, and in any order export — so your fulfillment team sees it without extra work.

If you want the date on the order list view, that requires a metafield or an order tag. The simplest version: add a hidden input in Step 1 with name="attributes[Delivery date]" and a second script that also writes the date into a tag via Shopify Flow (trigger: Order created → action: Add order tags). That's optional polish.

Step 4: Test the Picker Across Themes and Devices

Test in this order:

  1. Desktop Chrome and Safari. Safari's native date input looks different and its min handling is stricter — check the default date actually appears.
  2. iOS Safari and Android Chrome. Native date pickers on mobile open as a wheel or calendar; confirm the field is reachable and the label doesn't overlap the input.
  3. Your theme's cart drawer, if it has one. Dawn's cart drawer uses sections/cart-drawer.liquid — a picker on the cart page won't appear there. Decide whether you need it in the drawer too (it's a separate snippet).
  4. Place a real test order. Confirm the date shows in admin under the order's Additional details, in the confirmation email, and on the packing slip.
  5. Edit the cart after choosing a date. Change a quantity and re-check that the attribute survived. This is where Option A's update.js call earns its keep.

Keep a short checklist:

Common Issues and How to Fix Them

Symptom Likely cause Fix
Date doesn't appear on the order Input is outside the cart <form>, or the AJAX submit didn't include it Move input inside the form; add the /cart/update.js listener from Step 2
Attribute shows as attributes[Delivery date] literally Field name typo or theme escaping the brackets Use exactly name="attributes[Delivery date]"
Customer can pick a past date min never set, or JS error earlier on page Check console; confirm the script runs after the input exists
Picker disappears after quantity change Theme re-renders the cart section via AJAX and drops your markup Put the picker in the section that re-renders, or re-run your JS on cart update events
Works on desktop, broken on mobile Custom CSS styling the native input Remove custom appearance styling; native pickers are more reliable on mobile
Date saved but not emailed Notification template doesn't reference attributes Add the Liquid snippet from Step 3 to each template

When an App Might Still Be Worth It

Build it yourself when your rules fit in a short script: a lead time, weekend skipping, a handful of holidays. Buy an app when you need capabilities that would take days to build and maintain:

Apps in this category include Order Delivery Date and similar tools in the Shopify App Store — check current pricing and reviews against your actual requirements rather than the feature list, since most charge monthly and some charge per order volume.

Conclusion

A delivery date picker on the Shopify cart is a cart attribute, a native date input, and about twenty lines of JavaScript — no app subscription, no third-party script on your cart page. Build it on a duplicated theme, test a real order end to end, and add the attribute to your notification templates so the date reaches the people who pack the box. If your delivery rules outgrow a short script, that's the moment to look at an app, not before.

FAQ

Will the delivery date survive if a customer abandons checkout and comes back? Yes, if you used the /cart/update.js approach in Step 2 — cart attributes persist with the cart for the standard cart cookie lifetime. Line item properties also persist but are tied to that specific line.

Does this work on Shopify's new "One" checkout? The cart attribute is saved to the cart before checkout, so it carries into any checkout version. You can't add custom fields inside checkout without Shopify Plus, which is why the cart page is the right place for this.

Can I hide the picker for certain products or shipping methods? Yes — wrap the markup in a Liquid condition based on cart contents ({% if cart.items ... %}), or hide it with JavaScript when a specific shipping rate is selected. Hiding by shipping method requires reading the selected rate, which Shopify doesn't expose on the cart page without additional work; hiding by product is straightforward.