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

  1. In the Recharge merchant portal, click Storefront, and select Theme Editor.
  2. Make a copy of the current active theme by clicking the ellipsis and select Duplicate.

Step 2 - Add the Surprise and Delight banner logic

  1. Return to the Theme editor main page, and select Edit code for the duplicated theme.

  2. 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();  
    }
    
  3. In the subscription.html template, add data attribute to the <p> element that displays the subscription price.

  4. 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>
    
  5. 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

  1. 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)}`;
    
  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

  1. In the _orders.js file, located inside order.line_items.forEach, deconstruct original_price from line_item on lines 69-70.
  2. On lines 72-76 perform checks for gift and discount offers.
  3. 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

  1. In _helpers.js, on lines 54-58, located inside the renderLineItems function, perform checks for gift and discount offer.
  2. 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

  1. 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

  1. After adding the code into your theme, Save the updated code.
  2. 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

  1. In the Recharge merchant portal, click Storefront, and select Theme Editor.
  2. Click the kebab menu and select Duplicate to make a copy of the current active theme.

Step 2 - Update the cancel button

  1. Return to the Theme editor main page, and select Edit code for the duplicated theme.
  2. 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.
  3. Modify the _scripts.js file to add the redirectToLandingPage function. This is on line 26, after check 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

  1. After adding the code into your theme, Save the updated code.
  2. 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.


Need Help? Contact Us