Skip to main content

Cart page integration

On the cart page (and in AJAX cart drawers) the frontend does two things:

  1. Replace line item thumbnails with the customized preview image.
  2. Rewrite product links into edit links so the customer can re-open their design.

Both rely on the line item properties written at add-to-cart, so this page also documents those.

Line item properties

Every customized line item carries a set of properties. Keys prefixed with _ are hidden by Shopify in cart, checkout, and notification emails; keys without the prefix are shown to the customer.

PropertyVisibleContents
_fpd-hashnoIdentifier of the server-side line item cache (LIC) — the stored design. Everything else (edit, preview, print files) is looked up through this hash.
_fpd-urlnoURL of the preview image of the customized design. Used to swap the cart thumbnail.
_fpd-handlenoHandle of the original Shopify product. Used to build the edit link.
_fpd-variant-idnoThe originally selected real variant ID. Present when the cart line uses a generated custom variant, so the edit link can restore the customer's real size/color selection.
_fpd_print_pdfnoDirect URL to the print-ready PDF. Only written when the shop option shopify_link_print_pdf is enabled.
_fpd-asset-0, _fpd-asset-1, …noSource URLs of each customer-uploaded image, one property per image. Only written when shopify_link_assets is enabled.
Custom TextsyesNumber of customized text elements. Suppressed via shopify_no_text_count.
Custom ImagesyesNumber of customized image elements. Suppressed via shopify_no_image_count.
danger
Never strip _fpd* properties

Everything prefixed with _fpd belongs to the designer integration. If your theme or another app rewrites line item properties, it must pass all _fpd* keys through unchanged (filter by prefix, not by a fixed key list). Removing them breaks thumbnails, editing, and — worst case — order fulfillment.

Where the design itself lives

The design data is not stored in the properties. At add-to-cart the full design (all views and elements), print data, and a preview image are uploaded to the FPD backend as a line item cache record; the cart line only carries the _fpd-hash reference. This keeps carts small and makes designs survive across devices and sessions.

Thumbnail replacement

On the cart page the frontend fetches /cart.js, walks your cart rows, and swaps each customized item's image for its _fpd-url preview.

For this to work your cart markup must line up with three configurable selectors (see Configuration for how these are set per shop):

PurposeOptionDefault selector
Cart form/containershopify_ta_cart_page_formform[action='/cart']
One line item rowshopify_ta_cart_page_row(must be set per theme, e.g. .cart-item)
Image inside a rowshopify_ta_cart_page_row_image.fpd-item-image

Two rules your theme must follow:

  1. Row order must match /cart.js order. Items are matched to DOM rows by index, not by ID. If your theme renders cart rows in a different order than Shopify's cart JSON, wrong images will be swapped.
  2. The image target should be an <img> or <a>. For <img> both src and srcset are replaced; for <a> the href (and a CSS background-image, if present) is updated. If the matched element is neither, a new <img> is appended into it as a fallback.

When the customer changes the cart, the frontend detects calls to /cart/change and /cart/update, refreshes its cart data, and re-runs the replacement automatically.

For each customized line item the frontend builds an edit URL:

https://<shop>/products/<_fpd-handle>?variant=<variant>&_fpd-hash=<hash>&li-key=<line item key>
  • variant prefers _fpd-variant-id (the customer's real selection) over the line's variant.
  • _fpd-hash tells the product page which stored design to load.
  • li-key is the Shopify cart line key, used to replace the existing line instead of adding a second one when the customer saves their edit.

Behavior is controlled by two options:

  • shopify_cart_link_edit (default on) — existing product links inside the row are rewritten to the edit URL.
  • shopify_add_edit_link (default on) — an extra <a class="fpd-edit-button">Edit</a> is appended to the element matching shopify_ta_cart_page_row_attach (default .product-option:last-child). Style it via the fpd-edit-button class.

What happens on the product page when an edit link is opened is described in Product page.

AJAX carts and cart drawers

Outside the cart page a general handler runs on every page and performs the same thumbnail/link updates for JS-rendered carts (drawers, mini carts). It uses its own selector set:

PurposeOptionDefault
Cart drawer elementshopify_ta_cart_js_cart_drawercart-drawer
Cart containershopify_ta_cart_js_elementform[action='/cart']
One line itemshopify_ta_cart_js_item.cart-drawer__item
Item imageshopify_ta_cart_js_image.cart-drawer__item-image

Two hooks matter when your theme re-renders the cart drawer itself:

  • Event fpd:cartChanged — the frontend listens for this on document and re-runs image and link updates. The frontend does not observe your drawer DOM, so after a custom re-render, dispatch:

    document.dispatchEvent(new CustomEvent('fpd:cartChanged'));
  • FPD.func.updateCartJSImages() — imperative alternative to the event; call it after your drawer finished rendering.

After the designer's own add-to-cart (JSON strategy), the frontend already triggers the drawer refresh itself, including Shopify Section Rendering (sections / sections_url) and calling renderContents() + open() on the drawer element.

note

In JS carts, product links are only enriched with _fpd-hash (no li-key), so following them opens the design for editing but adds a new line rather than replacing the existing one. Full replace-on-edit is available from the cart page.

Bulk orders

When the bulk order form is active (a #fpd-bulk-order-container element exists on the product page), all selected variant/quantity combinations are added in a single /cart/add.js call and share one line item cache: every resulting line carries the same _fpd-hash, _fpd-url, and related properties.