DOPP API: Interceptors
If you want to opt out of our app's storefront price rendering for specific products or variants (while still letting the discount apply at cart and checkout), use the price rendering interceptor on the DOPP API.
The interceptor is a function you register that runs every time our app is about to update a price on the storefront. You return { shouldRenderDiscountedPrices: false } to skip the price rewrite for that product / variant, or { shouldRenderDiscountedPrices: true } to let it run normally.
The discount itself is unaffected. Shopify Functions still applies it in the cart and at checkout. The interceptor only controls what the app does to prices that customers see on the page.
Example Use Cases
- You have custom pricing logic on the product details page for specific variants (e.g., "Custom" or "Made to order" variants) and you don't want our app to overwrite that.
- You have a wholesale variant whose price is managed by another app and shouldn't be touched.
- You're A/B testing whether to render discounted prices on certain collections and want to gate it client-side.
Setting an Interceptor
Wait for the DOPP API to initialize, then register your interceptor via api.interceptors.setPriceRenderingInterceptor:
const excludeCustomVariants = async (api) => {
await api.interceptors.setPriceRenderingInterceptor(async (event) => {
if (event.variant?.title?.toLowerCase().includes("custom")) {
return { shouldRenderDiscountedPrices: false };
}
return { shouldRenderDiscountedPrices: true };
});
};
if (window.RegiosDOPP?.api?.v0) {
excludeCustomVariants(window.RegiosDOPP.api.v0);
} else {
window.addEventListener("regios-dopp:api-initialized", (e) => {
excludeCustomVariants(e.detail.api);
});
}
The interceptor runs on every storefront price update across all surfaces our app handles (product page, collection grid, search, recommendations, featured products). Use event.extensionType if you want to scope your decision to specific pages:
import { DOPPPublicApiExtensionType } from "./dopp_public_api"; // from our TS definition
await api.interceptors.setPriceRenderingInterceptor(async (event) => {
if (event.extensionType === DOPPPublicApiExtensionType.ProductPage) {
if (event.variant?.title?.toLowerCase().includes("custom")) {
return { shouldRenderDiscountedPrices: false };
}
}
return { shouldRenderDiscountedPrices: true };
});
The Event Argument
Your interceptor receives a DOPPPriceRenderingInterceptorEvent with:
extensionType— where on the storefront the price is about to render. Values arePRODUCT_PAGE,COLLECTION_PAGE,SEARCH_PAGE,PRODUCT_RECOMMENDATIONS, orFEATURED_PRODUCTS.product— aDOPPPublicApiProductwith the product id, variants, collections, tags, vendor, etc.variant— the selected variant (DOPPPublicApiProductVariant), if one is in scope.quantity— the quantity being used for the pending price update.
Read the full type definitions in our TypeScript definition file.
The Return Value
Return an object with shouldRenderDiscountedPrices: boolean. Returning false causes our app to leave the existing price markup on the page untouched.
The return type is an object (rather than a plain boolean) so we can extend it with additional fields later without breaking interceptors you've already shipped.
Chaining Interceptors
There is only one active interceptor at a time. If another integration (or an earlier piece of your own code) already registered one, you can chain on top of it by reading the previous interceptor first and falling through:
const previous = await api.interceptors.getPriceRenderingInterceptor();
await api.interceptors.setPriceRenderingInterceptor(async (event) => {
if (myCondition(event)) {
return { shouldRenderDiscountedPrices: false };
}
return (
(await previous?.(event)) ?? { shouldRenderDiscountedPrices: true }
);
});
Clearing the Interceptor
Pass null to unregister:
await api.interceptors.setPriceRenderingInterceptor(null);
Notes
- Your interceptor function is
async. You canawaitwork inside it (e.g., fetch a flag from your own backend), but slow interceptors will delay price rendering on the page, so keep them fast. - If your interceptor throws, our app logs the error and falls back to rendering normally rather than blocking the page.
- The interceptor only affects what our app renders on the storefront. The cart and checkout discount is calculated by Shopify Functions and is not affected.
Your Feedback Matters
Your review helps keep this small business running. Please leave one on the Shopify App Store.
Updated on: 08/06/2026
Thank you!