Skip to main content

Product page integration

On a designable product page the frontend orchestrates the full customization flow: it loads the FPD product configuration, mounts the designer, wires up the external modules, and intercepts the add-to-cart.

Lifecycle​

  1. Bootstrap — the bundle (injected by the app embed) verifies window.FPD / window.Shopify, loads shop options and language, and reads the Shopify product from #ProductJson-FPD.
  2. Product load — the FPD product configuration (views, elements, modules, prices) is fetched from the FPD backend. If the URL carries ?_fpd-hash=…, the saved design is loaded in parallel.
  3. Designer creation — the designer mounts into the container (#fpd by default). Depending on the designer mode it renders inline, or stays hidden behind a "customize" button/modal.
  4. Operators attach — add-to-cart interception, price display, save button, view selection, 3D preview, bulk order, and the external modules connect to the designer instance.
  5. Ready — <body> gets the class fpd-enabled; the productPageDone callback fires; FPD.instance is available.

External modules​

The external modules render designer functionality outside the canvas — as cards directly in your product page layout. They live in shadow DOM, configure themselves via a JSON data-config attribute (usually filled by theme editor block settings), and connect to the designer automatically once it exists.

ElementPurposeKey config
fpd-images-moduleImage upload (drag & drop, gallery of previous uploads, optional QR-code tab)showUploadTab, showGallery, showDropZone, enableQrCodeTab, targetMode (upload-zone / replace / add), uploadZoneName, replaceValue, displayMode, imageSize, imagesPerRow
fpd-texts-moduleAdd text and edit all existing text layers (font, size, style, color)showTextLayers, showAddText, showFontSize, showFontFamily, showFontStyles, showFontColor, showTextTemplates, textTemplates, editMode
fpd-layouts-moduleSwitch the view between predefined layoutsdisplayMode, imagesPerRow, showClearOption, collapsible, autoApplyFirst, showPrices, swapLayoutConfirmation, layoutIds
fpd-products-moduleChoose between multiple FPD products (designs)displayMode, imageSize, imagesPerRow
fpd-designs-moduleBrowse and add pre-made designs/clipartsdisplayAs (inline / popup), categoryLayout, categories, imagesPerRow, buttonText
fpd-add-elements-moduleCard grid combining "add text", "text templates", and "designs"showAddText, showTextTemplates, showDesigns, hiddenCards, labels, defaultText, designs* passthrough
fpd-info-popoverInfo icon with a popover next to a module headingtext, moduleType, language
fpd-share-buttonSave & share the current designbuttonLabel

Shared config for every module: language (auto / en / de), customCss, and additionalConfig — a free-form JSON object whose keys override the block settings (bind it to a product metafield for per-product behavior, see Configuration).

In the Shopify theme editor the modules render a static design-mode preview and re-read their config on shopify:section:load — safe to configure live.

Add-to-cart flow​

When the customer clicks add-to-cart on a customized product:

  1. The original submit is intercepted (the button is replaced by a cloned one under FPD's control).
  2. The optional beforeAddToCart callback runs — throwing aborts the add (custom validation).
  3. Elements outside the printing area trigger a warning modal.
  4. The design is uploaded to the FPD backend (line item cache), producing the _fpd-hash and preview URL.
  5. The line item properties are built (see Cart page) and the item is added according to the configured strategy:
    • Form strategy — properties are written as hidden properties[…] inputs and your theme's form submits normally.
    • JSON strategy — the frontend POSTs /cart/add.js itself (including Section Rendering data for cart drawers).
    • Event strategy — the frontend emits fpd:atcPrepared with the finished properties and leaves the cart add to your code.
  6. Afterwards, the configured after-behavior runs: redirect to cart, page refresh, fpd:addToCart event, or opening the cart drawer.

Strategies and after-behaviors are shop options — see Configuration.

Uncustomized products​

With shopify_add_lic_only_when_customized enabled, a product that was not customized is added as a plain Shopify product without any design data.

Variant changes​

The frontend watches URL changes (including history.pushState by your theme) for a new ?variant=:

  • Same product, new variant → prices refresh; if the theme morphs the product section's DOM, the designer re-initializes in place.
  • The displayed price = variant base price + designer extra (FPD.instance.calculatePrice() + optional FPD.additionalPrice), rendered into the element matching the price selector (.fpd-shopify-price by default) or an auto-created .fpd-total-extra block.

For products with more than 250 variants the frontend falls back to the Storefront GraphQL API to resolve the current variant.

Editing an existing design​

When the page is opened through a cart edit link (?_fpd-hash=…&li-key=…, see Cart page):

  • The saved design is fetched and loaded into the designer.
  • The designer auto-opens (option shopify_open_designer_when_edit, default on).
  • Add-to-cart switches to update mode: the old cart line (li-key) is removed and the edited design is added in its place.
  • The main product image is replaced with a snapshot of the loaded design.

Save button​

Independent of add-to-cart, a dedicated save button can be enabled (shopify_use_save_button, or ?sbs= for testing). It stores the current design (line item cache) without adding to the cart — used for save-for-later / wishlist flows. By default it replaces the ATC button; with shopify_save_button_replace_atc disabled it appears alongside (anchor: #fpd-save).

Bulk orders​

If your product template contains <div id="fpd-bulk-order-container">, the normal ATC button and quantity selector are hidden and a variant/quantity table renders instead. All selected combinations are added in one cart call, sharing a single stored design. Dispatch fpd:preview on document to refresh its preview image after external changes.