Skip to main content
window.FrenzyProductGridChangeCallBack is a global hook that lets theme developers modify each product card generated by Frenzy. Common uses include:
  • Displaying custom, sale, preorder, new, or sold-out badges
  • Rendering color or material swatches
  • Updating price presentation
  • Adding low-stock or delivery messages
  • Adding wishlist or compare buttons
  • Adding analytics attributes
  • Loading additional Shopify product information

1. Callback signature

Parameters

2. When the callback runs

The callback runs every time Frenzy formats a product card. Depending on the store configuration, that can include:
  • Collection grids
  • Search-result grids
  • Recommendation carousels
  • Cart-popup recommendations
  • Infinite-scroll results
  • Predictive-search suggestions
The same product can therefore pass through the callback more than once, or appear in multiple locations simultaneously. The callback must be:
  • Safe to run repeatedly
  • Scoped to the supplied cardRoot
  • Fast
  • Protected against missing data and missing elements
  • Careful about context-specific behavior

3. Understanding the product payload

The keys in the ‘data’ object is controlled from the Dashboard. (Search & Collections -> Filter Settings -> Extra Properties -> Response Fields. Below is an example image. This is done to limit the data in the API response and maintain the platform speed.
Image
The list of keys/internal names can be selected from Search & Collections -> Filter Settings -> Filter Options -> Internal Name.
Image
The exact fields depend on the store’s Frenzy feed and configuration. Frequently observed fields include: *Do not assume every field will exist. During development, inspect the real payload:
Remove or disable verbose logging before publishing the theme. Only one global callback can exist. Assigning the function again replaces the previous implementation. Use one coordinator that calls separate extension functions:
The outer try/catch is important. An uncaught exception can interrupt the product-grid rendering loop and affect subsequent cards. If the theme already defines this callback, either add new helpers to the existing implementation or wrap it:
The wrapper must load after the existing callback.

5. Use case: product badges

The following example supports:
  • Automatic sold-out badges
  • Percentage-off sale badges
  • Preorder tags
  • Custom _badge_ product tags
Example styling:
Use textContent when displaying product data. Avoid inserting untrusted field values directly through innerHTML.

6. Use case: color or material swatches

This example reads Color or Metal from all_options_details.

Render swatches synchronously

Handle clicks through event delegation

Install this listener once, outside the callback:
For a production swatch implementation, also update:
  • Product links with ?variant=...
  • Quick-add variant IDs
  • Price and compare-at price
  • Secondary product image
  • Size availability
  • The selected swatch state

7. Use case: custom merchandising rules

The callback can apply rules using product tags, inventory, template suffixes, collections, metafields, or request context.

8. Use case: context-specific behavior

Because the callback may run for collections, recommendations, predictive search, and cart popups, not every extension should run everywhere. Use org_request_type where available:
Request-type values depend on Frenzy configuration. Log product.org_request_type in the development theme before building an allowlist.

9. Use case: asynchronous product enrichment

Sometimes the Frenzy feed does not include everything required by the theme. Additional information may need to come from:
  • Shopify’s product JSON endpoint
  • A custom Shopify alternate view
  • A metafield endpoint
  • A third-party loyalty or review service
First, assign a stable identifier synchronously:
Then cache the request and update the live cards:
Caching prevents the same product from being requested repeatedly when it appears in multiple grids.

10. Other useful extensions

Price presentation

Developers can add:
  • “From” labels for products with a price range
  • Percentage-saved messages
  • Member pricing
  • Clearance styling
  • Regional price messages
Avoid replacing Frenzy’s price unless the custom price source is authoritative and uses the correct active currency.

Wishlist or compare integrations

The callback can synchronously insert the required placeholder, product ID, variant ID, and classes. Initialize the third-party library only after the card is present in the live document.

Analytics

The callback is useful for adding attributes:
Do not fire an impression event directly from the callback. Formatting a card does not guarantee that the user saw it. Use an IntersectionObserver on the live cards.

Accessibility

Custom extensions should include:
  • Buttons for interactive swatches
  • Descriptive aria-label values
  • aria-pressed for selected swatches
  • Proper disabled states
  • Visible keyboard focus
  • Text equivalents for color-only indicators

12. Production checklist

Before publishing an extension:
  • Use a single global callback.
  • Define it before Frenzy performs its first grid render.
  • Wrap the callback in try/catch.
  • Guard every optional selector and data field.
  • Make every modification idempotent.
  • Scope synchronous queries to cardRoot.
  • Do not attach event listeners to the detached card.
  • Use event delegation for interactive features.
  • Do not rely on an asynchronous callback return value.
  • Re-query the live document after asynchronous work.
  • Cache per-product network requests.
  • Use textContent for product-derived text.
  • Sanitize any non-theme HTML before inserting it.
  • Test collection, search, recommendations, predictive search, cart popup, filtering, sorting, and infinite scroll.
  • Test products with missing images, no variants, sold-out variants, price ranges, and incomplete metafields.