Adding Subscription Experiences to the Novum Theme Engine
This guide provides step-by-step instructions for implementing the Surprise and Delight Subscription Experience for the default version of the Novum theme. The same logic applies to Novum 5.0.1 and later themes.
Platform
- Recharge Checkout on Shopify
- Shopify Checkout Integration
Before you start
- You must be on the Retain paid add-on using Rewards and have Theme Engine enabled to add Subscription Experiences to the Novum portal.
- Your store must allow cancellations to add the Cancellation Prevention strategy.
- All themes prior to Novum 5.0.1 (legacy themes) require additional logic to fully support Subscription Experiences.
Add the Surprise and Delight banner and logic to Novum theme
This guide provides step-by-step instructions for implementing the Surprise and Delight Subscription Experience for the default version of the Novum theme. The same logic applies to Novum 5.0.1 and later themes.
Step 1 - Duplicate the theme
- In the Recharge merchant portal, click Storefront, and select Theme Editor.
- Make a copy of the current active theme by clicking the ellipsis and select Duplicate.
Step 2 - Add the Surprise and Delight banner logic
-
Return to the Theme editor main page, and select Edit code for the duplicated theme.
-
Navigate to the
subscriptions.html
template and add the logic to display the Surprise and Delight banner at the end of the file, before the{% endblock %}
tag. In the default Novum 5.3.2 theme, this is located on line 203.const settings = {{ settings | json }}; async function fetchQueuedCharges() { const schema = `{ "charges": { "status": "QUEUED" } }`; try { const url = `${ReCharge.Endpoints.request_objects()}&schema=${schema}`; const response = await axios(url); ``` return response?.data?.charges; ``` } catch (error) { console.error({ error }); return { charges: \[], }; } } async function checkChargeLineItems() { const charges = await fetchQueuedCharges(); if (!charges.length) return; let giftItem = null; charges.filter((charge) => { return charge.line_items.filter((lineItem) => { const giftProperty = ReCharge.Utils.getGiftLineItem(lineItem); if (giftProperty) { giftItem = lineItem; } }); }); return giftItem; } async function init() { const flowItem = await checkChargeLineItems(); if (flowItem && settings?.customer_portal?.wfs_flows_enabled) { window.ReCharge.Components.renderSurpriseAndDelight({ selector: "#rc_te-template-wrapper", className: "rc_subscription_card_element_wrapper", settings, flowItem, }); } } if (settings?.customer_portal?.wfs_flows_enabled) { init(); }
-
In the
subscription.html template
, adddata attribute
to the<p>
element that displays the subscription price. -
Below the
data attribute
, add an additional<p>
element to display the offer price. In the default Novum 5.3.2 theme, this is located on line 123.<p data-rc-subscription-price>{{ subscription.price | money_localized }}</p> <p data-rc-flow-item-price></p>
-
Add logic that would render the item price in the subscription.html template. In the default Novum 5.3.2 theme, this is located on line 333, above the closing script tag.
Step 3 - Update the schedule.html template
-
In the
schedule.html template
, add the logic that displays the discounted offer price. In the default Novum 5.3.2 theme, this is located on line 162 below the isSubscriptionSkippable constant.const chargeItem = charge?.line_items?.find( (item) => item.subscription_id === subscription.id, ); let isOfferItem = false; let discountedPrice = price; if (chargeItem) { const offerProperty = ReCharge.Utils.getOfferLineItem(chargeItem); if (offerProperty) { isOfferItem = true; discountedPrice = chargeItem.price; } } const priceOutput = `${ReCharge.Novum.Utils.getCurrency()}${Number( discountedPrice, ).toFixed(2)}`;
-
Add logic to dynamically render the price label if the offer exists. In the default Novum 5.3.2 theme, this is located on line 212 below the
element that renders Quantity.
${ isOfferItem ? `${ReCharge.translations.flows.activeChurn.discountedOfferLabel}: ${priceOutput}` : `${priceOutput}` }
Step 4 - Update the _orders.js file
- In the
_orders.js
file, located insideorder.line_items.forEach
, deconstructoriginal_price
fromline_item
on lines 69-70. - On lines 72-76 perform checks for gift and discount offers.
- On line 93, render
${lineItemLabel}
in the element.
// Deconstruct original_price from line_item
const { quantity, title, price, variant_title, images, original_price } =
line_item;
// Check for gift/offer product
const giftProperty = ReCharge.Utils.getGiftLineItem(line_item);
const offerProperty = ReCharge.Utils.getOfferLineItem(line_item);
let lineItemLabel = giftProperty
? `${ReCharge.translations.flows.surpriseAndDelight.giftStatus}`
: offerProperty
? `${formatCurrency(price, order.currency)} <s>${formatCurrency(
original_price,
order.currency,
)}</s>`
: formatCurrency(price, order.currency);
// Render lineItemLabel in <span> element
<span class="order-price text-font-14">${lineItemLabel}</span>;
Step 5 - Update the In _helpers.js file
- In
_helpers.js
, on lines 54-58, located inside therenderLineItems
function, perform checks for gift and discount offer. - On line 76, render
${lineItemLabel}
using the element.
// Check for gift/offer product
const giftProperty = ReCharge.Utils.getGiftLineItem(line_item);
const offerProperty = ReCharge.Utils.getOfferLineItem(line_item);
let lineItemLabel = giftProperty
? `(${ReCharge.translations.flows.surpriseAndDelight.giftStatus})`
: offerProperty
? `(${ReCharge.translations.flows.activeChurn.discountedOfferLabel})`
: "";
// Render lineItemLabel in <span> element
<span>${lineItemLabel}</span>;
Step 6 - Update _translations.js
- In
_translations.js
, add logic to support translations of the Subscription Experience.
flows: {
surpriseAndDelight: {
giftStatus: `{{ 'cp_experiences_surprise_free' | t }}`,
giftTitle: `{{ 'cp_experiences_surprise_title' | t }}`,
giftDescription: `{{ 'cp_experiences_surprise_description' | t }}`,
giftBody: `{{ 'cp_experiences_surprise_body' | t }}`
},
activeChurn: {
discountedOfferLabel: `{{ 'cp_active_churn_discount_label' | t }}`
}
},
Step 7 - Save and publish your theme
- After adding the code into your theme, Save the updated code.
- Click the kebab menu and select Publish to publish the updated theme.
Surprise and Delight must be active and customers must meet qualification criteria before customers can claim offers.
Add the Cancellation Prevention landing page redirect to custom Novum theme
This section provides step-by-step instructions to implement the Cancellation Prevention Subscription Experience for the default version of the Novum theme.
The same logic applies for Novum 5.0.1 and later themes. All themes prior to Novum 5.0.1 (legacy themes) require additional logic and changes to fully support Subscription Experiences.
Step 1 - Duplicate your existing theme
- In the Recharge merchant portal, click Storefront, and select Theme Editor.
- Click the kebab menu and select Duplicate to make a copy of the current active theme.
Step 2 - Update the cancel button
- Return to the Theme editor main page, and select Edit code for the duplicated theme.
- Find the cancel button. In the default Novum 5.3.2 theme, it is located on the
/subscriptions/id
page. It is referenced in the_scripts.js
file on line 32. - Modify the
_scripts.js
file to add theredirectToLandingPage
function. This is on line 26, aftercheck for hasMinimumOrderAmount
.
redirectToLandingPage: function() {
const redirectUrl = `https://${ReCharge.Novum.store.platform_domain}/tools/recurring/pages/${ReCharge.Novum.customer.hash}/subscriptions/${ReCharge.Novum.subscription.id}/cancel?token=${window.customerToken}&subscription=${ReCharge.Novum.subscription.id}`;
```
window.location.assign(redirectUrl);
```
},
Step 3 - Confirm if landing pages are enabled
Perform checks on whether the store has landing pages enabled. This should be added after the check for customer portal settings for the pause subscription feature, on line 43 in default Novum 5.3.2 theme.
const isLandingPageActive = ReCharge.Novum.settings.customer_portal.wfs_active_churn_landing_page_redirect;
Using an if statement, on lines 53 - 60, add the following code:
JavaScript
if (
hasPauseSubscriptionEnabled
) {
const handler = isLandingPageActive ? this.redirectToLandingPage : pauseSubscriptionFlow;
cancelBtn?.addEventListener("click", handler);
return;
} else if (cancel_subscription && this.hasMinimumOrderAmount(orders) && !hasPauseSubscriptionEnabled) {
const handler = isLandingPageActive ? this.redirectToLandingPage : cancelSubscriptionFlow;
cancelBtn?.addEventListener("click", handler);
return;
} else {
ReCharge.Utils.contactStoreWording(
cancelBtn,
ReCharge.Utils.renderCancelSubscriptionLayout(),
`{{ 'cp_cancel_cancel_title' | t }}`
);
}
Step 4 - Save and publish your theme
- After adding the code into your theme, Save the updated code.
- Click the kebab menu and select Publish to publish the updated theme.
You must have an active Cancellation Prevention Subscription Experience to redirect customers to the landing page. If there are no active experiences, the default cancellation (modal with cancellation reasons in default Novum 5.3.2 theme) will be used.
Updated about 2 months ago