Add a package
Add a package and its included items to a customer's cart.
Use the add_package_to_cart form tag to add a package to the customer's cart.
If the customer does not already have a cart, one is created automatically. When the form is submitted, all included package items are added to the cart together.
If any included package item is sold out, or if the requested quantity is greater than the available stock, the package is not added to the cart.
Basic usage
{% form "add_package_to_cart" %}
<input name="package[id]" value="{{ package.id }}" type="hidden" />
<input name="package[quantity]" min="1" value="1" type="number" />
<input type="submit" value="Add package" />
{% endform %}Form fields
| Field name | Description |
|---|---|
package[id] | The ID of the package to add to the cart. |
package[quantity] | The number of packages to add. |
package[start_date] | The customer's selected start date. Required when package.requires_date is true. |
package[start_time] | The customer's selected start time. Optional. |
package[adult_count] | The number of adults for the package. Only available for flexible adult count packages. Defaults to the package's minimum adult count. |
package[items][][id] | The ID of the package item receiving modifier selections. |
package[items][][modifier_ids][] | The ID of a selected modifier. |
Date, time, and adult count
Packages may require additional booking details, such as a start date, start time, or adult count.
{% form "add_package_to_cart" %}
<input name="package[id]" value="{{ package.id }}" type="hidden" />
<input name="package[quantity]" min="1" value="1" type="number" />
<input name="package[start_date]" type="date" />
<input name="package[start_time]" type="time" />
<input name="package[adult_count]" type="number" />
<input type="submit" value="Add package" />
{% endform %}Modifier selections
Package items can include pre-checkout modifier groups, such as room type, entry time, or other customer choices.
Each selected modifier should be submitted with the package item it belongs to.
{% form "add_package_to_cart" %}
<input name="package[id]" value="{{ package.id }}" type="hidden" />
<input name="package[quantity]" min="1" value="1" type="number" />
<h3>{{ package.name }}</h3>
{% for item in package.items %}
<h4>{{ item.variant.name }}</h4>
<input
type="hidden"
name="package[items][][id]"
value="{{ item.id }}"
/>
{% for group in item.variant.pre_checkout_modifier_groups %}
<fieldset>
<legend>{{ group.name }}</legend>
{% for modifier in group.modifiers %}
<label for="modifier-{{ modifier.id }}">
<input
id="modifier-{{ modifier.id }}"
type="checkbox"
name="package[items][][modifier_ids][]"
value="{{ modifier.id }}"
/>
{{ modifier.name }}
</label>
{% endfor %}
</fieldset>
{% endfor %}
{% endfor %}
<input type="submit" value="Add package" />
{% endform %}If a required modifier selection is omitted for any package item, the entire package is not added to the cart.
Clear the cart first
To remove all existing cart items before adding the package, include the clear_cart field.
{% form "add_package_to_cart" %}
<input name="package[id]" value="{{ package.id }}" type="hidden" />
<input name="package[quantity]" min="1" value="1" type="number" />
<input type="hidden" name="clear_cart" />
<input type="submit" value="Add package" />
{% endform %}This is useful when the booking flow should replace any existing cart contents before starting the package.
Forwarding parameters to the booking journey
You can forward selected values to the package booking template by including hidden inputs under the step_params namespace.
These values are appended as query parameters when the customer is redirected to the first step of the booking journey. They are then available through the page.params object.
Only search parameters are supported. Other keys are ignored.
Supported step parameters
| Field name | Description |
|---|---|
step_params[search][start_date] | Start date to forward to the step page URL. |
step_params[search][end_date] | End date to forward as a search query parameter. |
step_params[search][occupancy][] | Guest occupancy values to forward as search query parameters. |
step_params[search][occupancy_match] | Occupancy matching mode. Supports all or any. Defaults to any. |
step_params[search][sort] | Sort order for products on accommodation steps. Supports price_asc or price_desc. Other values are ignored and the default order is used. Only applies to the first package step. |
Forwarding dates
{% form "add_package_to_cart" %}
<input name="package[id]" value="{{ package.id }}" type="hidden" />
<input name="step_params[search][start_date]" value="2025-06-15" type="hidden" />
<input name="step_params[search][end_date]" value="2025-06-20" type="hidden" />
<input type="submit" value="Add package" />
{% endform %}Forwarding occupancy filters
{% form "add_package_to_cart" %}
<input name="package[id]" value="{{ package.id }}" type="hidden" />
<input name="step_params[search][occupancy][]" value="2" type="hidden" />
<input name="step_params[search][occupancy][]" value="4" type="hidden" />
<input name="step_params[search][occupancy_match]" value="all" type="hidden" />
<input type="submit" value="Add package" />
{% endform %}Forwarding a sort order
{% form "add_package_to_cart" %}
<input name="package[id]" value="{{ package.id }}" type="hidden" />
<input name="step_params[search][sort]" value="price_asc" type="hidden" />
<input type="submit" value="Add package" />
{% endform %}You can then access these values in the package booking template:
{{ page.params.search.start_date }}
{{ page.params.search.end_date }}
{{ page.params.search.occupancy | join: ", " }}
{{ page.params.search.occupancy_match }}
{{ page.params.search.sort }}Developer considerations
When adding packages to the cart:
- Include
package[id]for every package form. - Include
package[quantity]when customers can add more than one package. - Include required date, time, or adult count fields when the package configuration requires them.
- Submit required modifier selections for each package item.
- Use
clear_cartwhen the booking flow should replace any existing cart contents. - Use
step_paramsonly for values that should be forwarded into the package booking journey. - Treat package add-to-cart as atomic: if one included item cannot be added, the package is not added.
- After a successful submission, the customer is redirected to the first step of the package booking journey (if the package has steps) or back to the current page.