Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.elasticfunnels.io/llms.txt

Use this file to discover all available pages before exploring further.

This page covers cart usage: cartItems, item properties, and data attributes for quantity and remove. For checkout-only topics (totals, form fields, coupon, payment), see Checkout.

Scope: cartItems / items

cartItems (or items) is an array of line items. The cart plugin fills it; UI updates are reactive when cart scope changes.
Item propertyTypeDescriptionIn template
codestringProduct/cart line codeUse with qty/remove data attributes
namestringProduct name[[ item.name ]]
imagestringProduct image URL[[ item.image ]]
quantitynumberQuantity[[ item.quantity ]]
pricestringUnit price (formatted)[[ item.price ]] — do not use formatPrice
totalstringLine total (formatted)[[ item.total ]] — do not use formatPrice
retail_pricestringOriginal/retail price (formatted)[[ item.retail_price ]]
discount_totalstringPer-line savings (formatted)[[ item.discount_total ]]
currencystringCurrency code[[ item.currency ]]
is_subscriptionbooleantrue when this is a subscription product[[ item.is_subscription ]]
subscriptionobject | nullSubscription details (see below) — null for one-time products[[ item.subscription.frequency ]]
bonusesarrayBonus products included with this item (see below)template-foreach loop
coursesarrayCourses linked to this product (see below)template-foreach loop
price and total are already formatted. Use [[ item.price ]] and [[ item.total ]] as-is. See Functions for when to use formatPrice.bonuses, courses, is_subscription, and subscription are populated after a brief async fetch from the server when the cart loads. They are always present (empty array / false / null) so templates never error.

Subscription details (item.subscription)

When item.is_subscription is true, item.subscription contains billing cadence and trial settings:
PropertyTypeDescription
frequencynumberHow often the subscription bills (e.g. 3)
frequency_unitstringUnit for the frequency: "day", "week", "month", or "year"
trial_daysnumberFree trial length in days (0 = no trial)
first_charge_freebooleantrue when the first billing cycle is free
Example — showing billing cadence next to the price:
<template-foreach data-each="item in cartItems">
  <span>[[ item.name ]]</span>
  <span>[[ item.price ]]</span>
  <template-if data-condition="item.is_subscription">
    <span>Every [[ item.subscription.frequency ]] [[ item.subscription.frequency_unit ]]</span>
  </template-if>
</template-foreach>
The same is_subscription and subscription fields are available on checkout scope for single-product checkout pages (e.g. [[ checkout.is_subscription ]], [[ checkout.subscription.frequency ]]).

Bonus products (item.bonuses)

Each cart item may include a bonuses array — products that are included free with that item (configured in the product catalog under Bonuses). Populated automatically from the /api/cart-products response after the cart loads. Each element in item.bonuses has:
PropertyDescription
codeBonus product code
nameBonus product name
imageBonus product image URL
pricePrice (formatted) — typically $0.00 for free bonuses
retail_priceRetail value (formatted) — useful for “valued at” display
original_priceSame as retail_price
currencyCurrency code
Example:
<template-foreach data-each="item in cartItems">
  <div class="cart-line">
    <img src="[[ item.image ]]" alt="[[ item.name ]]" />
    <span>[[ item.name ]]</span>
    <span>[[ item.price ]]</span>
    <template-foreach data-each="bonus in item.bonuses">
      <div class="cart-bonus">
        <img src="[[ bonus.image ]]" alt="[[ bonus.name ]]" />
        <span>[[ bonus.name ]]</span>
        <span>FREE (valued at [[ bonus.retail_price ]])</span>
      </div>
    </template-foreach>
  </div>
</template-foreach>
item.bonuses is always an array — empty when the product has no bonuses configured.

Courses (item.courses)

When a product has linked courses, they are available as item.courses. Populated automatically from the /api/cart-products response after the cart loads. Each element in item.courses has:
PropertyDescription
idCourse ID
titleCourse title
slugURL slug (used to link to the course page)
descriptionShort description
coverCover image URL
instructor_nameInstructor name (if set)
statusPublication status ("published", "draft", etc.)
Example — listing included courses beneath a cart line:
<template-foreach data-each="item in cartItems">
  <span>[[ item.name ]]</span>
  <template-foreach data-each="course in item.courses">
    <div class="cart-course">
      <img src="[[ course.cover ]]" alt="[[ course.title ]]" />
      <span>[[ course.title ]]</span>
    </div>
  </template-foreach>
</template-foreach>
item.courses is always an array — empty when the product has no linked courses.

Quantity and remove (data attributes)

Use these so the cart plugin handles +/- and remove without custom script:
AttributeElementPurpose
data-cart-qty-minusButtonDecrease quantity
data-cart-qty-plusButtonIncrease quantity
data-cart-qty-removeButton/linkRemove line (set qty to 0)
data-code="[[ item.code ]]"Same element or parentSo the plugin receives the actual product code
data-disable-when-oneMinus button (optional)Disable when item.quantity <= 1
Example:
<template-foreach data-each="item in cartItems">
  <div class="cart-line">
    <img alt="[[ item.name ]]" src="[[ item.image ]]" />
    <span>[[ item.name ]]</span>
    <button type="button" data-cart-qty-minus data-code="[[ item.code ]]" data-disable-when-one aria-label="Decrease"></button>
    <span>[[ item.quantity ]]</span>
    <button type="button" data-cart-qty-plus data-code="[[ item.code ]]" aria-label="Increase">+</button>
    <span>[[ item.total ]]</span>
    <button type="button" data-cart-qty-remove data-code="[[ item.code ]]" aria-label="Remove">Remove</button>
  </div>
</template-foreach>
You can wrap the Remove button in <template-if data-condition="cartItems.length > 1"> so it only shows when there is more than one item (use &gt; for > in data-condition). For custom behavior, use @click with window.ef.addToCart(code, options?, quantity?), window.ef.setCartQuantity(code, quantity), or window.ef.removeFromCart(code, allowClear?) if the app exposes window.ef.

Order bumps (on checkout)

On checkout pages, bump cards use these data attributes so the bump-products plugin can toggle and style:
AttributeWherePurpose
data-bump-code="[[ bump.code ]]"Card/containerPlugin adds .selected / .bump-selected when selected
data-bump-checkbox="[[ bump.code ]]"CheckboxLinks checkbox to bump code
data-bump-toggle="[[ bump.code ]]"Label or clickable wrapperClick toggles the checkbox
name="bump" or name="bump[]", value="[[ bump.code ]]"CheckboxForm submit and plugin read selected codes
For scope (checkout.bump_products, checkout.selectedBumpLines) and full offer vs added template pattern, see Checkout — Order bumps.

Summary

  • Use cartItems and [[ item.* ]]; item.price and item.total are already formatted.
  • item.is_subscription / item.subscription — billing cadence; also on checkout scope for single-product pages.
  • item.bonuses — free bonus products linked to the item; always an array.
  • item.courses — courses linked to the product; always an array.
  • Use data-cart-qty-minus/plus/remove and data-code for qty and remove.
  • Bumps: use data-bump-* attributes; scope and patterns are in Checkout.