Skip to content

Date Range

Capture a start and an end date from a single calendar — for bookings, rentals, hire periods, and delivery windows.

Overview

Date Range sits alongside the existing Date type rather than replacing it: Date captures one day, Date Range captures a span — and knows how long that span is.

The customer sees two read-only fields. Clicking either opens one calendar: the first click sets the start, the second sets the end.

Use Date Range for:

  • Equipment and vehicle hire
  • Accommodation and stay bookings
  • Rental periods
  • Delivery or service windows

Key characteristics:

  • Dates are stored as YYYY-MM-DD and written to the cart as one property
  • Knows its own length, in either days or nights
  • Can be marked as required
  • Works as a condition source, evaluated against the whole span
  • Unavailable days are greyed out rather than silently rejected

Pricing is not part of this option type

Date Range captures a span and its length. It does not price that span — there's no per-day or per-night rate here. Use Price Add-Ons for pricing, or read the hidden duration property from your theme (see Cart Properties).

Configuration

Basic Settings

SettingDescription
LabelOption name displayed to customers (e.g., "Hire period")
Option is required for this option setIf enabled, customers must pick a range before adding to cart
Hide Label from storefrontIf enabled, only the two fields are shown

The option's settings card is grouped into four sections: Duration, Availability, Booking window, and Labels.

Duration

SettingOptions (default)What it controls
Count asdays (default) / nightsDays counts both the first and last date; nights counts the stays between them. 1st → 7th is 7 days or 6 nights — hire versus hotel
Minimum durationnumber (empty)The shortest range a customer can select. Leave empty for no limit
Maximum durationnumber (empty)The longest range a customer can select. Leave empty for no limit

Availability

SettingOptions (default)What it controls
Available datesAll dates (default) / All dates except… / Only specific datesChoose whether customers can pick any date, or only some. The fields below switch with this
Blocked days of the weekseven toggles (none)Shown under All dates except… — greys that weekday on every occurrence, every month
Blocked dateslist of dates (empty)Specific dates customers cannot select, such as holidays or closures
Available periodslist of ranges (empty)Shown under Only specific datesonly dates inside these periods can be selected
Available individual dateslist of dates (empty)Single dates that can be selected, on top of any periods above

Booking window

SettingOptions (default)What it controls
Disable past datestoggle (on)Customers cannot select a date earlier than today
Earliest dateNo limit (default) / Specific date / Days from todayThe relative mode is lead or prep time — blocks dates within this many days of the order date
Latest dateNo limit (default) / Specific date / Days from todayHow far ahead customers can book

"Days from today" is a rolling window

Set Earliest date → Days from today = 5 and today through today+4 are greyed; today+5 is the first selectable day. The window moves with the calendar, so you never have to update a fixed date.

Labels

SettingOptions (default)What it controls
Start field labeltext (empty, hint Check in)The label on the first field
End field labeltext (empty, hint Check out)The label on the second field

Advanced Settings

SettingDescription
Internal LabelAdmin-only identifier (replaces label in the options list)
Help TextAdditional guidance shown to customers (based on display mode)
CSS class / CSS IDYour own selectors on this option's container — see CSS Class & CSS ID

Date format and separator live on the template

How dates are displayed — the format and the separator between them — is a styling setting on the assigned Customization template, not on the option. Stored dates are always ISO. See Types Settings.

Validation

Nothing turns red until you press Save

Choosing "Days from today" and leaving the offset empty for a moment doesn't flag an error. Validation runs on save, so the form doesn't scold you mid-edit.

MessageCause
The maximum must be greater than or equal to the minimum.Minimum duration exceeds Maximum duration
Enter a whole number of 1 or more.A duration is zero, negative, or fractional
That duration is too long.A duration is oversized
The latest date must be on or after the earliest date.Latest date precedes Earliest date
The latest offset must be greater than or equal to the earliest offset.Latest "days from today" is below Earliest's
Choose a date.A date is missing for the chosen mode
Enter a number of days.An offset is missing for the chosen mode
Enter a valid date.A date field isn't a valid date
Add at least one available period or date, or no date can be selected.Only specific dates with an empty allow-list
Every day of the week is blocked, so no date can be selected.All seven weekday toggles are on

How to Add a Date Range

  1. Navigate to Option Sets and open your option set
  2. Click Add Option
  3. Select Date Range from the Option Type modal (it's under the Input category)
  4. Enter a Label (e.g., "Hire period")
  5. Under Duration, choose Count as and set a minimum or maximum if you need one
  6. Under Availability, restrict dates if some are closed
  7. Under Booking window, set lead time and how far ahead customers can book
  8. Under Labels, name the two fields (e.g., "Check in" and "Check out")
  9. (Optional) Click Advanced Settings for an Internal Label, Help Text, or a CSS class/ID
  10. Click Save in the contextual save bar

How Customers Pick a Range

  1. First click sets the start and marks it selected immediately; the end stays empty
  2. Hovering after that previews the span — the hovered day takes the end colour, the days between take the in-range colour
  3. Second click completes the range and closes the calendar (unless the template renders it inline)
  4. Clicking on or before the start restarts the range from there
  5. With a range already complete, the next click starts a new range rather than stretching the old one
  6. A same-day range is allowed when no minimum forbids it — 1 day, or 0 nights

What gets greyed out

Unavailable days stay visible and readable by screen readers; only their styling changes.

  • Past dates, when Disable past dates is on
  • Blocked weekdays, on every occurrence in every month
  • Dates outside the booking window
  • Everything outside the allow-list, under Only specific dates
  • Once a start is chosen: any day that cannot legally end the range under your min/max duration. The start itself and everything before it stay clickable

A range can't span a closed day

If a blocked date sits between the start and a candidate end, that end is unavailable — a hire can't run straight through a day you're shut.

If a chosen start leaves no bookable end at all — say a 3-night minimum starting Friday with the weekend closed — the summary says so rather than asking for an end date that can't exist.

Accessibility

The calendar is a role="grid": arrow keys move day to day, and the grid holds exactly one tab stop. Unavailable days use aria-disabled, so they're still reachable and announced rather than hidden. Choosing a start announces that an end is wanted; completing the range announces its length.

Cart Properties

A completed range produces one visible property plus three hidden ones:

PropertyExampleNotes
Hire period12/08/2026 – 15/08/2026Visible on the cart line, using the template's date format and separator
_Hire period start2026-08-12Hidden, always ISO
_Hire period end2026-08-15Hidden, always ISO
_Hire period days (or nights)4Hidden, named after the option's Count as setting

The hidden properties are there so you don't have to parse the visible one

Shopify hides _-prefixed properties from the cart but keeps them on the order. Read them in Liquid or from the Admin API to get the machine-readable start, end, and length — no need to reverse-engineer a localized date string.

An unfinished pick emits nothing. If a customer sets a start but no end on an optional option, no property is written — a half-formed range would put a start with no end on the order line.

Conditions

A Date Range can be used as a condition source with six comparators. The rule value is a single date, and every operator is evaluated against the whole span:

ComparatorEvaluates asAug 10–15 vs Aug 12
isThe range covers the date (start ≤ date ≤ end)✅ matches
is notThe range does not cover it
is beforeThe whole range is earlier (end < date)
is afterThe whole range is later (start > date)
is emptyNeither date has been chosen
is not emptyA start has been picked

Containment is the useful reading of is: a booking of Aug 10–15 plainly includes Aug 12. For before and after, containment doesn't apply, so each takes the far edge — they read as "entirely before" and "entirely after", as in "if the rental ends before the season opens".

is / is before / is after are mutually exclusive

For any complete range, every date satisfies exactly one of the three, and no date satisfies two. That makes rule sets easy to reason about.

Edge cases:

  • A same-day range behaves exactly like the single Date type
  • A half-picked range (start chosen, end not yet) counts as a one-day range at the start, so conditions stay steady between the two clicks instead of flickering
  • A rule value that isn't a valid date matches nothing — including is not
  • Conditions re-evaluate live as the customer picks; the dependent option shows or hides without a page reload

Use Cases

Equipment hire

Label: Hire period · Count as: days Minimum duration: 1 · Maximum duration: 14 Earliest date: Days from today = 2 Labels: "Collection" / "Return"

Result: 1–14 day hires with two days' prep time

Accommodation

Label: Your stay · Count as: nights Minimum duration: 2 Available dates: All dates except… → Blocked dates for closures Labels: "Check in" / "Check out"

Result: Two-night minimum stays, with closure dates unbookable

Seasonal rental

Label: Rental period · Count as: days Available dates: Only specific dates → Available periods covering the season

Result: Bookings restricted to the open season

Delivery window

Label: Delivery window · Count as: days Available dates: All dates except… → Blocked days of the week: Saturday, Sunday Latest date: Days from today = 30

Result: Weekday-only delivery windows up to a month ahead

Best Practices

Get "Count as" right first:

  • It changes the number on the order and the minimum a customer must meet
  • Hire and services usually count days; stays count nights

Prefer relative windows to fixed dates:

  • "Days from today" keeps working without maintenance
  • A specific Latest date silently stops accepting bookings once it passes

Block closures rather than relying on customers to notice:

  • Blocked days and dates grey out and can't be booked through
  • Remember a range can't span a closed day — long minimums plus frequent closures can leave very few valid ranges

Name the fields for the job:

  • "Check in / Check out" for stays, "Collection / Return" for hire
  • The defaults are only hints; an unlabelled pair is harder to read

Use the hidden properties in your theme:

  • Read _{label} start, _{label} end, and _{label} days/nights for fulfilment logic
  • Don't parse the visible string — its format is a styling setting and can change

Troubleshooting

Every end date is greyed after I pick a start: A minimum or maximum duration, or a blocked day inside the span, leaves no legal end. The summary says so when no end exists at all

Customers can't book far enough ahead: Check Latest date — a fixed Specific date may have passed. Prefer "Days from today"

The calendar shows nothing selectable: Under Only specific dates, the allow-list may be empty or entirely in the past

No cart property appeared: The range was left half-picked. Both dates are required before anything is written

The cart shows a different date format than I expected: Format and separator are template settings — see Types Settings

A condition on a date inside the range isn't matching: Confirm you're using is. is before / is after test the whole span, not containment

Styling

Date Range has its own dedicated styling — field layout, the calendar panel, day cells and range fill, unavailable-day treatment, date format, and the selection summary are all configurable via named templates.

See Date Range Styling for the full settings reference, and Sandbox & Live Preview for how to build a test calendar while you style.