Client-Side Integration

Setting up client-side integration to trigger the Modulo referral modal.


A successful client-side integration of Modulo consists of 4 steps:

  1. Library Import: Load the Modulo JS library code into your webpage

  2. Purchase Registration: Register a purchase after it happens (trackPurchase())

  3. Referral Modal Open: Open the Modulo referral modal on your website (open())

  4. Get the Coupon: Set-up coupon getting logic (getCoupon())

Modulo does the rest on tracking referrals and dispatching the appropriate events to Klaviyo.

Library Import

Include the Modulo JS code via a script tag in the webpage <head> globally (loads on every page on your site).

<!-- Modulo JS -->
<script src="" async defer></script>
<!-- End Modulo JS -->

It is important that the Modulo JS script is loaded on every page, this ensures that Modulo can properly track when referred users go to your site.

Waiting for Script Load

You can listen on the window object for the moduloReady synthetic event to have an async event to hook into to know you are executing your code with the Modulo library loaded.

if(!window.Modulo) {
// Listen and wait for the Modulo JS library to initialize
window.addEventListener('moduloReady', () => {
console.log('% Modulo has loaded %');
// Your code goes here....
} else {
console.log('% Modulo is already loaded %');
// Your code goes here....

The window. prefix can be omitted and the Modulo object can be directly accessed in the global context. Javascript will still resolve the value as the window object is at the end of the Javascript "scope chain".

Register a Purchase (async trackPurchase())

For Modulo to track referrals, it must know when purchases complete. Behind the scenes Modulo will fetch cached tracking information and dispatch the appropriate events server-side to your marketing systems.

const { userId, referralId } = await Modulo.trackPurchase({
storeId: {YOUR_STORE_ID},

trackPurchase() takes two parameters:

It returns:

  • userId: The ID of the user in the Modulo system.

  • referralId: The ID of the referral to be used later for opening the referral modal.

Opening the Modal (open())

After tracking a successful purchase and getting the referralId, the referral modal can be opened.

<!-- Open the Modulo modal -->{
referralId: {REFERRAL_ID},
display: { ... },
reward: { ... },
refereeLandingUrl: "" // this is the link referred users will be sent to via text/email

The following describes the additional parameters you can use to dynamically configure the referral and the visible modal:

display: {
primaryColor: string; // use your primary brand color here to customize
inviteText: string; // this is the invite text that the user will see and can edit
maxReferrals?: number; // set a cap on the total referrals the modal will allow
reward: { // specify the reward that the advocate and friend will receive
referrer: RewardConfig;
referee?: RewardConfig;
type RewardConfig {
discountedSubscription: {
unit: 'month' | 'year';
duration: number; // total increments of the unit
discountPercent: number; // set to 100 if the product is made free

Closing The Modal

You can programmatically close the modal by calling the close function. The modal will also automatically close after the referral flow is complete, if a user does not close it themselves.

<!-- Close the Modulo modal -->

Full Modal Show Example

The following is a full example of the track-open flow to complete a successful modal show:

const moduloDisplayConfig = {
primaryColor: '#4558FF',
inviteText: 'I just joined this app and I love it!'
const moduloRewardConfig = {
referrer: {
discountedSubscription: { // referrer will get 2 months free
unit: 'month',
duration: 2,
discountPercent: 100
referee: {
discountedSubscription: { // the referred friend will get 1 month free
unit: 'month',
duration: 1,
discountPercent: 100
storeId: '1',
stripeId: 'cs_test_UqSPSmkcnAprWr2LP03LLSolXxHCLvEMWmFm7rqt3KKL6BZKoKB3t1Ux'
}).then(({ userId, referralId }) => {{
display: moduloDisplayConfig,
reward: moduloRewardConfig,
refereeLandingUrl: ''

Get a Coupon (async getCoupon())

The global share link is the link that a user sees (and can copy) right after completing their referrals in the Modulo referral modal. It contains only the Modulo tracking parameter and no coupon information is included.

Because the global share link is globally open for use, many users can use the link to get to the destination URL with tracking. A one-time coupon cannot be tagged to the global share link due to this.

It is important to always use getCoupon() as a user coming in through a global share link will not have gotten a coupon via email/text. Modulo will fetch a coupon for this user via their tracking information (if it exists).

You can fetch an appropriate coupon for a user on your site as follows:

<!-- Get a coupon for a referred user -->
await Modulo.getCoupon()

If a coupon exists or can be resolved, the return value is as follows:

coupon: string

If the user is not a referral and therefore has no coupons to be redeemed, the return value is null:


A convenient flow for your users would be to auto-apply a coupon at checkout or show a modal on landing so a user understands they are being rewarded for being referred.

You can fetch the most recent share link of a user with currentUser():

<!-- Get data on a user -->
await Modulo.currentUser({ email: "[email protected]" })

The return value consists of:

email: string;
name: string;
shareLink: string; // the user's share link
purchasedAt: number; // epoch date the user purchased on