Configuration
The frontend is configured through several layers. Understanding which layer owns which setting saves a lot of guessing:
| Layer | Set where | Scope | Examples |
|---|---|---|---|
Shop options (shopify_*) | FPD admin, delivered via the site-options API | whole shop | add-to-cart strategy, edit links, selectors |
Inline window.FPD object | Theme code, before the bundle loads | whole shop (theme-controlled) | FPD.shopOptions, FPD.lang, FPD.ta, FPD.callbacks, FPD.debug |
Plugin options (plugin_options) | FPD admin, delivered with the product JSON | per product | designer products/designs, language JSON, line item property blocks |
Block settings (data-config) | Shopify theme editor, per module block | per section/block (per product via metafields) | which cards a module shows, labels, additionalConfig |
Precedence for shop options: inline FPD.shopOptions (theme) wins over the values delivered by the API. For selectors, non-empty values win over empty ones, in the order defaults → auto-detected suggestions → shop options → inline FPD.ta.
Shop options reference
All keys below are shop options (set in the FPD admin) and can also be provided inline via window.FPD.shopOptions = { ... } in the theme.
Add-to-cart behavior
| Option | Effect |
|---|---|
shopify_atc_strategy | How the design is added to the cart: save_to_form / add_form_data (hidden form fields, theme form submits) or add_json (direct /cart/add.js call) |
shopify_after_add_to_cart_strategy | What happens after a JSON add: submit_form, refresh_page, or trigger_event |
shopify_no_redirect_after_add_to_cart | Suppress the redirect after add-to-cart |
shopify_no_reload_after_add_to_cart | Suppress the page reload (results in event-trigger behavior) |
shopify_disable_add_to_cart_until_customize | Keep the ATC button disabled until the product was customized |
shopify_disable_add_to_cart | Disable add-to-cart entirely |
shopify_show_atc_spinner | Show a spinner on the ATC button while the design uploads (default on) |
shopify_atc_excluded_field_names | Form field names to exclude from the ATC payload |
shopify_always_keep_product | Always create/keep a custom product for customized items |
shopify_add_lic_only_when_customized | Only attach design data when the customer actually customized something |
Save button
| Option | Effect |
|---|---|
shopify_use_save_button | Show a separate "save customization" button |
shopify_save_button_replace_atc | The save button replaces the ATC button (default on) |
shopify_save_button_strategy | Strategy used when saving |
Cart & line items
| Option | Effect |
|---|---|
shopify_cart_link_edit | Rewrite cart product links into edit links (default on) |
shopify_add_edit_link | Append an extra .fpd-edit-button edit link per row (default on) |
shopify_link_print_pdf | Add _fpd_print_pdf property with the print-PDF URL |
shopify_link_assets | Add _fpd-asset-N properties with uploaded image URLs |
shopify_no_text_count | Suppress the visible Custom Texts property |
shopify_no_image_count | Suppress the visible Custom Images property |
Designer behavior
| Option | Effect |
|---|---|
shopify_open_designer_on_product | Auto-open the designer when the product page loads |
shopify_open_designer_when_edit | Auto-open the designer when following an edit link (default on) |
shopify_done_as_atc | The designer's "Done" button behaves like add-to-cart |
shopify_select_element_on_add | Auto-select an element right after it is added |
shopify_spinner_on_variant_change | Show a spinner while a variant change reloads the designer |
enableDynamicViews | Enable the dynamic-views feature (note: no shopify_ prefix; also available per product) |
shopify_dynamicViewsUpdateOnViewSelection | Update dynamic views when the selected view changes (default on) |
Value caching (restore customer input)
| Option | Effect |
|---|---|
shopify_cache_text_value | Cache and restore entered texts |
shopify_cache_text_values_mode | Cache key mode (default textLinkGroupAndTitle) |
shopify_cache_color_value | Cache and restore color selections |
shopify_cache_image_value | Cache and restore uploaded/selected images |
shopify_cache_long_term | Persist the cache beyond the session (default on) |
Pricing, previews, designs
| Option | Effect |
|---|---|
shopify_fpd_money_format | Money format string used for designer prices |
shopify_preview_last_view | Use the last view for preview thumbnails |
shopify_three_d_preview_width / shopify_three_d_preview_height | 3D preview thumbnail size (default 150×150) |
shopify_sort_designs_by_title | Sort designs alphabetically |
advanced_fabricjsTextureSize | Maximum canvas texture size (default 8192) |
fpdOverwrite | Advanced: object that is deep-merged over the per-product plugin options |
Theme abstraction: pointing FPD at your theme's DOM
The frontend never hardcodes your theme's markup — every element it touches is found through a configurable selector ("theme abstraction"). Suggested selectors are auto-detected per theme; you can override any of them as shop options or inline via window.FPD.ta.
Product page
| Option | Default | Purpose |
|---|---|---|
shopify_ta_product_page_selector | #fpd | Container where the designer mounts |
shopify_ta_product_page_form | form[action='/cart/add'] | The add-to-cart form |
shopify_ta_product_page_add_cart_button | button[type='submit'] | The ATC submit button |
shopify_ta_product_page_price | .fpd-shopify-price | Product price element |
shopify_ta_product_save_customization | #fpd-save | Save-customization trigger |
shopify_ta_product_page_main_image | .product_image img | Main product image (modal mode) |
shopify_ta_product_page_customize_button | #fpd-customize-button | Customize button (modal mode) |
shopify_ta_product_designer_mode | legacy | Designer mode: legacy (auto-detect), page (inline), customize (modal), advanced (both), button (deferred — see below) |
In button mode the designer is only built when the shopper clicks
#fpd-open-designer-button. Where it then goes depends on the viewport at page
load: above 768px it renders inline, replacing the designer container; below, it
goes into a modal, opened by the customize button
(shopify_ta_product_page_customize_button, #fpd-customize-button by default).
That button is the theme's own if it has one — keep it hidden until
body.fpd-designer-active, since it cannot open a designer that has not been
built — otherwise one is created next to add-to-cart on activation. Editing an
existing customization builds the designer right away in both cases, without
opening it.
In the modal layout the merchant's module blocks stay in the page while the
designer is closed (body.fpd-designer-active), so the design can change
without the modal being open. The main product image
(shopify_ta_product_page_main_image) is re-rendered whenever that happens, at
most once per second of quiet, and again after a variant switch once the
shopper has changed something. The rendering runs on an offscreen canvas, so
the designer itself is never touched.
Cart page
| Option | Default | Purpose |
|---|---|---|
shopify_ta_cart_page_form | form[action='/cart'] | Cart form/container |
shopify_ta_cart_page_row | — | One line item row (must usually be set per theme) |
shopify_ta_cart_page_row_image | .fpd-item-image | Preview image inside a row |
shopify_ta_cart_page_row_item_price | .fpd-item-price | Per-item price |
shopify_ta_cart_page_row_line_item_price | .fpd-item-line-price | Line total |
shopify_ta_cart_page_total_price | .fpd-total-price | Cart total |
shopify_ta_cart_page_update_input | input[name='updates[]'] | Quantity update input |
AJAX cart / drawer
| Option | Default | Purpose |
|---|---|---|
shopify_ta_cart_js_cart_drawer | cart-drawer | The drawer custom element |
shopify_ta_cart_js_cart_element | form[action='/cart'] | Cart container |
shopify_ta_cart_js_cart_item | .cart-drawer__item | One line item |
shopify_ta_cart_js_cart_image | .cart-drawer__item-image | Item image |
The inline window.FPD object
Everything below can be set in the theme before the bundle loads:
window.FPD = window.FPD || {};
window.FPD.shopOptions = { shopify_add_edit_link: false }; // override shop options
window.FPD.ta = { cart: { checkoutFormItem: '.cart-item' } }; // override selectors
window.FPD.lang = { /* override core designer labels */ };
window.FPD.callbacks = { /* hook functions, see JavaScript API */ };
window.FPD.debug = true; // verbose console logging
window.FPD.errorReporting = true; // enable error tracking
See JavaScript API for what the bundle itself exposes on FPD at runtime.
URL parameters
Useful for testing and deep links:
| Parameter | Effect |
|---|---|
?debug | Enables FPD.debug — verbose console output, translation lookups, theme-abstraction logs |
?no_cache | Bypasses the API cache for options, designs, and languages |
?open_designer_on_product | Force-opens the designer on page load |
?_fpd-hash=<hash> | Loads a saved customization by its hash |
?li-key=<key> | Marks an edit of an existing cart line (design save replaces that line) |
?variant=<id> | Preselects a variant |
?atc_b=<value> | Overrides the add-to-cart behavior/target |
?sbs=<strategy> | Forces the save-button strategy on (testing) |
Per-product module configuration
External modules (the web components in your theme sections) read their settings from a data-config attribute — normally filled by Shopify theme editor block settings. Two mechanisms make this per-product capable:
additionalConfig— a free-form JSON textarea in the block settings. Its keys are merged over the other block settings. Bind it to a product metafield via Shopify's dynamic-source picker to give individual products their own module config.hiddenCards(Add-Elements module) — a comma-separated list (text,templates,designs) that hides individual cards; also designed to be bound to a product metafield.
Invalid JSON in additionalConfig is ignored with a console warning — a typo can't break the module.
The designer content itself (FPD products, designs, layouts, per-product language) is always per product and comes from the FPD admin (plugin_options), not from the theme editor.