Skip to main content
All CollectionsIntegrationsOther Integrations
Custom Website Installation Guide
Custom Website Installation Guide
Updated over 2 months ago

You want to connect your website to Retention.com’s app to start using Grow and/or Reclaim.

By following this guide, you'll be ready to:

  • Collect Grow contacts

  • Prevent collecting known contacts by suppressing them

  • Record revenue generated from Grow

  • Collect abandonment events from Reclaim

If you're using a popular eCommerce platform like Shopify, WooCommerce, or BigCommerce, we have specific platform installation guides here: Platform Guides.


Table of Contents

Prerequisites

  • Access to Website Files/Code: To insert our JavaScript code, you need access to the backend or content management system (CMS) of your website.

  • Basic JavaScript and HTML Knowledge: A basic understanding of JavaScript and HTML is required. You will be working with a JavaScript snippet and potentially need to make minor adjustments to fit your website’s specific tech stack.

  • Unique Company ID: A unique identifier for your company is provided by your implementation manager. This ID is crucial for the correct functioning of the "Grow" and "Reclaim" products.

A) Prepare your Website to Collect Grow Contacts

  • Step 1: Locate the collection script in your Retention.com app.

  • Step 2: Insert the collection script into your website’s html.

  • Step 3: Authorize your domain in Retention.com’s app

  • Step 4: Verify the collection script is present and correctly configured.

  • Optional: Set custom collection rules

  • Step 5: Add the Revenue Tracking Script on Order Completion Page

  • Step 6: Add the Suppress Function for Voluntary Email Submission

  • Testing Your Grow Functions

B) Prepare your Website to Collect Reclaim Events

  • Step 1: Replace Placeholders with Your Dynamic Content

  • Step 2: Track the Add to Cart Event

  • Step 3: Track the Viewed Product Event

  • Step 4: (Optional) Implement the Viewed Category Event

Supplementary Resources

  • Klaviyo Users Quick Guide: Easily Install Reclaim (Add to Cart, Viewed Product, Checkout Started)

  • Platform-Specific Templates for Setting Product Attributes


A) Prepare your Website to Collect Grow Contacts

To complete Retention.com’s product functionality, it's essential that our scripts are present on every page of your website where you are collecting contacts, suppressing contacts, identifying abandonment actions, and capturing revenue.

Step 1: Locate the Collection script in Retention.com’s App

Your collection script consists of the base code snippet combined with a collection function.

The base code snippet is always included for any of our scripts.

For collection, the function used is geq.page(), which triggers the collection of a contact after 1 page view.

By adding the collection script to every page on your site, you can potentially collect new Grow contacts from any page.

  1. Go to your Retention.com dashboard. From the navigation menu on the left, click on "Code Script"

  2. Click on "</> View your Script" on the top right hand of the page.

  3. Select Collection to retrieve your “Collection" script. Then click "</>Copy Code".

The scripts are unique for your account.


Step 2: Insert the Collection Script into the Website’s HTML

Locate the <head> tag in your HTML:

  1. You’ll need to access your sites content/files.

  2. Find the <head> tag within the HTML structure. This tag is usually located near the top of the file and precedes the main content of the page.

  3. Paste the “Collection” script within the <head>.

Ensure Global Presence:

To collect anonymous visitors with Grow on every page of the website, check that the “Collection” script is included in the global header file (typically found in the <head> tag) of your website's templates or content management system (CMS).


Step 3: Authorize Your Domain in Retention.com’s App

You will need to add your site's URL as an authorized domain in our app.

  1. Select “</> code script” from the left navigation menu in the Retention.com app.

  2. Select the edit button to the right of the title Authorized Domains.

  3. Paste your website domain and save the changes.


Step 4: Verify the collection snippet is present and correctly configured.

In the Retention.com app:

  1. Select “</> code script”.

  2. Select “</> view your script”.

  3. Select “Collection”

  4. Select the button “Test My Script”.

  5. Enter the URL of your site to test.

  6. The Retention Script debugger will be activated on your site and you should see the Collection Script is Found and Fired.

  7. When you return to the section Authorized Domain section, your site's URL will be highlighted in green. This ensures a successful Collection script + domain setup.

If you’d like to verify with your development tools, look for a ‘ge.js’ script in the Network tab. If you see a 403 error, this is because your script is not set live by our team.


Optional: Set Custom Collection Rules

Our default setting collects a contact's information when they view one page. If you want to delay collection until your end users view more pages or spend more time on the site, you’ll want to modify the Collection Rules and your Collection script.

The Retention.com application features a built-in option to manipulate contact collection rates for the purpose of targeting higher intent users. These rules determine when the collection function geq.page()will fire— after an end user has clicked through X pages, or has been on a page for a X seconds.

To unlock this feature, you’ll want to only install the base code snippet on your website, and omit the collection function.

If you remove the collection function, the rules established in the Retention app will determine when this function fires.

Collection function:

<script>geq.page()</script>


If the collection function is present in your website code, collection will fire upon first page load regardless of what the Collection Rules display.


Step 5: Add the Revenue Tracking Script on Order Completion Page

The Revenue Tracking Script is used to track the success of Grow by reporting conversions back to our system.

1. Locate Your Order Completion Page: Find the HTML or template file for your order completion or 'Thank You' page.

2. Insert Track Order Function

  • On this page, insert the geq.trackOrder function call, replacing placeholders with actual order variables generated by your e-commerce system.

  • Substitute the ##{{ ORDER_NUMBER }}", ##{{ ORDER_AMOUNT }}", and ##{{ CUSTOMER_EMAIL }}" placeholders with the appropriate data from your e-commerce platform.

  • Please ensure our base script is present on this page as well. This should've been implemented in the global <head> tag of your site.

⚠️ Note that our placeholders contain double brackets: ##{{ order_number }}

They are specific to Shopify and used below as an example.

<script type="text/javascript"> 
geq.trackOrder({
order_number: "##{{ ORDER_NUMBER }}", // Replace with your order number variable
order_amount: "##{{ ORDER_AMOUNT }}", // Replace with your order amount variable
order_email: "##{{ CUSTOMER_EMAIL }}" // Replace with your customer email variable
});
</script>

3. Verify the Data: Make sure that the variables for the order number, amount, and customer email are dynamically populated with real data for each transaction. You can verify by printing these variables to the console.

4. Test the Functionality: After placing the script, test a transaction to ensure the script captures and sends the data correctly.


Step 6: Add the Suppress Function for Voluntary Email Submission

The geq.suppress() function should be called whenever a user voluntarily submits their email on your site. This ensures that the Grow identification script does not collect their information.

  1. Identify Email Submission Points: Determine where on your site users can enter their email (e.g., newsletter sign-up, pop-up, etc.).

  2. Insert Suppress Function: In the event handler for the email submission action, insert a call to geq.suppress().

  3. Ensure Proper Timing: The suppress function should be triggered immediately upon the successful submission of an email (i.e. form submission).

Suppression Function:

geq.suppress();

Optional: If you have access to the user's email entered on the site, you can pass it into our Suppression function using the following format:

geq.suppress(emailEntered); // "emailEntered" is a string variable


Testing Your Grow Functions

  • Collection: Navigate through your site and verify that the geq.page() function is being called on every page without errors.

  • Order Tracking: Conduct a test purchase to ensure that the order tracking is capturing and sending data accurately.

  • Email Submission: Test the email submission points to ensure that the geq.suppress() function executes as expected.

You may encounter a 403 error for the "ge.js" file. This is normal and will resolve once your implementation manager sets your scripts to live!


B) Prepare your Website to Collect Reclaim events

Reclaim is designed to retarget audiences browsing your website that show an intent to purchase, but abandon before they convert. The events we identify and send to you enable you to send targeted abandonment email campaigns.

We offer the following events:

  • Add To Cart

  • Viewed Product

  • Active On Site (Automatically installed with our Base Script)

  • Viewed Category (Optional)

  • Checkout Started (For Klaviyo users only)

Step 1: Replace Placeholders with Your Dynamic Content

The placeholders in the variables and functions (e.g., name: "Product Name") indicate where dynamic content should be inserted.

When implementing the scripts, replace these placeholders with actual product details, typically using platform specific code.

This process will be unique to your custom site. It may be helpful to reference other areas on your site where these properties are used.


Step 2: Track the Add to Cart Event

To track when a user adds a product to their cart, you need to trigger the geq.addToCart function with the relevant product details as a parameter. This event should be triggered when the "Add to Cart" button is clicked.

  1. Find the script or trigger that executes when a product is added to the cart.

  2. Implement the geq.addToCart function at this point, ensuring it fires with the product's details.

<script type="text/javascript">
//NOTE: Labels can be changed per your requirements. You can add/remove fields
//NOTE: Fill out the values for these fields with dynamic variables from your system; these are often platform specific

// Step 1: Build out the product payload for our function
var atcitem = {
Name: "Product Name", // Replace with dynamic product name
Price: "Product Price", // Replace with dynamic product price
ProductID: "Product ID", // Replace with dynamic product ID
Categories: "Product Categories", // Replace with dynamic product categories (optional)
ImageURL: "Product Image URL", // Replace with dynamic product image URL
URL: "Product Page URL", // Replace with dynamic product page URL
Brand: "Product Brand" // Replace with dynamic product brand (optional)
};

// Logging
if (window.location.href.includes('vge=true')) {
console.log('Add To Cart Item:', atcitem);
}

// Step 2: Trigger the addToCart event with the payload created above
if (typeof geq !== 'undefined' && typeof geq.addToCart === 'function') {
geq.addToCart(atcitem);
}
</script>

Notes:

  • Make sure all product details are dynamically populated for what the user selects or interacts with.

  • Only ProductID is mandatory. If you don't have one, you can use a placeholder.

  • You can rename the variables to match the payload expected by the platforms that will receive this data.

  • If you cannot locate the script or trigger than executes when someone adds an item to the cart, you can use JavaScript event listeners to implement our function. *Ask your implementation manager for more information*


Step 3: Track the Viewed Product Event

When a user views a product, you must capture the details of the product they are viewing and pass this as a parameter to the geq.event function.

  1. Find the code that runs when a product page is loaded.

  2. Add the geq.event function call within the product page code to execute when the page is viewed.

<script type="text/javascript">
//NOTE: Labels can be changed per your requirements. You can add /remove additional fields
//NOTE: Fill out the values for these fields with dynamic variables from your system; these are often server-side rendering or templates.

// Step 1: Build out the product payload for our function
var vpitem = {
Name: "Product Name", // Replace with dynamic product name
Price: "Product Price", // Replace with dynamic product price
ProductID: "Product ID", // Replace with dynamic product ID
Categories: "Product Categories", // Replace with dynamic product categories (optional)
ImageURL: "Product Image URL", // Replace with dynamic product image URL
URL: "Product Page URL", // Replace with dynamic product page URL
Brand: "Product Brand" // Replace with dynamic product brand (optional)
};

// Logging
if (window.location.href.includes('vge=true')) {
console.log('Viewed Product Reclaim', vpitem);
}

// Step 2: Trigger the Viewed Product event with the payload created above
if (typeof geq !== 'undefined' && typeof geq.event === 'function') {
geq.event('Viewed Product Reclaim', vpitem);
}
</script>

Notes

  • Make sure all product details are dynamically populated for what the user selects or interacts with.

  • Only ProductID is mandatory. If you don't have one, you can use a placeholder.

  • You can rename the variables to match the payload expected by the platforms that will receive this data.


Step 4: (Optional) Track the Viewed Category Event

This is an optional event.

Capture when a user views a category like Electronics, Clothing, or Home Decor. This may provide additional insights for retargeting purposes.

  1. Find the code that runs when a category page is loaded.

  2. Add the geq.event function call within the product page code to execute when the category is viewed.

<script type="text/javascript">
var categoryItem = {
name: "title of the category" //replace with dynamic category name
url: location.href //URL of the current page
};
geq.event('Viewed Category Reclaim', categoryItem);
</script>


Klaviyo and Platform Specific

Klaviyo Users Quick Guide: Easily Install Reclaim

For merchants already using Klaviyo to track customer interactions, installing Reclaim is even easier! While Klaviyo captures a subset of your traffic, Reclaim is designed to recognize a larger portion, making your retargeting campaigns even more powerful.

NOTE: If you have installed Klaviyo tracking through the use of a direct Klaviyo Integration (i.e. plugin) then this option is not available.

Only customers who can adjust/access their Klaviyo code can utilize the following scripts.

NOTE: You may still be able to use the var item that Klaviyo creates in your browser for Retention’s events. If the geq.event('Viewed Product Reclaim', item); & geq.addToCart(item); code appears/occurs AFTER Klaviyo’s var item is set up, then you can utilize this variable for our events.

🔔 Our Checkout Started scripts are independent of any Klaviyo variables or code. You can implement them directly without any dependencies.

Integrating Reclaim with Your Klaviyo Set-Up

Klaviyo uses a JavaScript API to track customer behavior on a website, which typically involves using a function called _learnq. If you already have installed Klaviyo tracking, then simply add the geq.addToCart & geq.event functions to the same part of your code!

The general pattern of adding our code to Klaviyo's code snippet requires identifying where you set up your Klaviyo _learnq script (i.e. _learnq.push(["track", "Viewed Product", item]);).

⚠️ If you are unable to locate your Klaviyo scripts, you can implement our Reclaim scripts by following the steps 1-4 from above.

Klaviyo X Retention.com Viewed Product

// Look for your Klaviyo implementation - which will look something like:
{% if product %}
<script type="text/javascript">
var _learnq = _learnq || [];
var item = {
"ProductName": "##{{ product.title }}",
"ProductID": "##{{ product.id }}",
"SKU": "##{{ product.sku }}",
"Categories": ##{{ product.categories | json }},
"ImageURL": "##{{ product.image.src }}",
"URL": "##{{ shop.url }}##{{ product.url }}",
"Brand": "##{{ product.vendor }}",
"Price": ##{{ product.price | money_without_currency }},
"CompareAtPrice": ##{{ product.compare_at_price | money_without_currency }}
};
_learnq.push(["track", "Viewed Product", item]);
// Add Retention's View Product Event call here
geq.event('Viewed Product Reclaim', item);
</script>
{% endif %}

Klaviyo X Retention.com Add To Cart

//An example of Klaviyo's add to cart script 
<script type="text/javascript"> document.querySelector('ProductForm__AddToCart').addEventListener('click',function (){
_learnq.push(['track', 'Added to Cart', item]);

// Add Retention's Add To Cart Event call here
// Method 1: (EASY) Use the same item as Klaviyo
geq.addToCart(item);
// Method 2: (ADVANCED) Customize the item
// NOTE: you can edit the payload if you need to

if (typeof geq !== 'undefined' && typeof geq.addToCart === 'function') { geq.addToCart({
name: item.ProductName,
price: item.Price,
productID: item.ProductID,
categories: item.Categories,
imageURL: item.ImageURL,
URL: item.URL,
brand: item.Brand,
CompareAtPrice: item.CompareAtPrice})
;}
});
</script>

Klaviyo X Retention.com - Checkout Started

// Step 1: Copy and Paste the function below - no modifications needed

function createCheckoutAbandonmentPayload(cartId, cartAmount, currency, lineItems, checkoutUrl) {
return {
cart_id: cartId || "",
cart_amount: cartAmount || "",
currency: currency || "",
extra: {
line_items: lineItems.map(function(item) {
var lineItem = {};

// Assign properties if they exist
if (item.Quantity) lineItem.quantity = item.Quantity;
if (item.RowTotal) lineItem.line_price = item.RowTotal;

var product = {};
if (item.ProductName) product.title = item.ProductName;
if (item.ProductID) product.id = item.ProductID;
if (item.ProductURL) product.url = item.ProductURL;

if (item.ItemPrice) product.price = { amount: item.ItemPrice, currencyCode: currency || "" };
if (item.SKU) product.sku = item.SKU;
if (item.ImageURL) product.image = { src: item.ImageURL };

// Add the product only if it has data
if (Object.keys(product).length > 0) lineItem.product = product;

return lineItem;
}),
checkout_url: checkoutUrl || ""
}
};
}

// Step 2: Build the necessary variables required for the payload
// *NOTE* You are required to assign the variable values to the appropriate dynamic data from your platform

var cartId = {{ cart_id_value }}; // Replace with actual cart ID
var cartAmount = {{ cart_amount_value }}; // Replace with actual cart amount
var currency = "USD"; // Replace with actual currency code if different
var checkoutUrl = {{ checkout_url_value }}; // Replace with actual checkout URL
var lineItems = {{ all_cart_items }}; // Replace with actual cart items

// The "lineItems" variable above will contain all the products in the users cart
// *NOTE* The formatting for this variable is very specific - please ensure its an array of objects with the following layout and values:

[
{
"ProductID": "string", // The unique identifier for the product (e.g., "24757")
"SKU": "string", // The stock keeping unit (e.g., "LUX-SAT-PNL-BURG")
"ProductName": "string", // The name of the product (e.g., "*FR* LUXE Satin Drape Panel by Eastern Mills")
"Quantity": number, // The quantity of the product (e.g., 1)
"ItemPrice": number, // The price per item (e.g., 21.99)
"RowTotal": "string", // The total price for the row (e.g., "21.99")
"ProductURL": "string", // The URL for the product (e.g., "https://www.eventdecordirect.com/catalog/...")
"ImageURL": "string", // The URL for the product image (e.g., "https://static.eventdecordirect.com/images/...")
"ProductCategories": ["string"] // An array of categories the product belongs to (e.g., ["Event Curtains", "Drapes"])
},
// Separate products by commas
]

// Step 3: Create the payload with the variables above and call the Retention function
var payload = createCheckoutAbandonmentPayload(cartId, cartAmount, currency, lineItems, checkoutUrl);

if (typeof geq !== 'undefined' && typeof geq.event === 'function') {
geq.event("Checkout Started Reclaim", payload);
}

Platform-Specific Templates for Setting Product Attributes

When integrating "Reclaim" products into your website, it's essential to accurately set product attributes. This ensures that the data sent through geq.event calls are precise and meaningful. Most e-commerce platforms provide a templating system that you can utilize to dynamically assign these values. Here's how you can do it for some common platforms:

Shopify

Please note that we have our own private Shopify app that will automatically add our products to your site - no action is required for Shopify customers!

var item = { 
"Name": "##{{ product.title }}",
"Price": ##{{ product.price | money_without_currency }},
"ProductID": "##{{ product.id }}",
"Categories": ##{{ product.categories | json }},
"ImageURL": "##{{ product.image.src }}",
"URL": "##{{ shop.url }}##{{ product.url }}",
"Brand": "##{{ product.vendor }}"
};

Magento

Magento uses PHP on the backend, but you can pass variables to the frontend via JSON:

<script type="text/javascript"> 
var item = {
"Name": "<?php echo $block->escapeJs($block->escapeHtml($_product->getName())) ?>",
"Price": <?php echo json_encode($_product->getFinalPrice()) ?>, "ProductID": "<?php echo $_product->getId() ?>",
"Categories": <?php echo json_encode($_product->getCategoryIds()) ?>, "ImageURL": "<?php echo $block->getImageUrl($_product, 'product_page_image_large') ?>",
"URL": "<?php echo $_product->getProductUrl() ?>",
"Brand": "<?php echo $_product->getAttributeText('manufacturer') ?>" }; </script>

WooCommerce (WordPress)

For WooCommerce on WordPress, you would typically use PHP to handle data on the server side. Please see our dedicated guide at:

BigCommerce

For BigCommerce on WordPress, you would typically use PHP to handle data on the server side. Please see our dedicated guides at:

Adobe Experience Manager

In Adobe Experience Manager (AEM), you can use the Satellite object _satellite.getVar to retrieve dynamic variables.The _satellite.getVar method requires you to have set up data elements within Adobe Experience Platform Launch to return the appropriate values.

var item = { 
"Name": _satellite.getVar('ProductName'),
"Price": _satellite.getVar('ProductPrice'),
"ProductID": _satellite.getVar('ProductID'),
"Categories": _satellite.getVar('ProductCategories'), // Assumes this is a JSON array
"ImageURL": _satellite.getVar('ProductImageURL'),
"URL": _satellite.getVar('ProductURL'),
"Brand": _satellite.getVar('ProductBrand')
}

Adobe Experience Manager With Klaviyo

NOTE: This may need to be adjusted based on your setup and is only intended as a guideline.

Fetch Product DetailsUses digital data; for more information, please refer to: https://experienceleague.adobe.com/docs/analytics/implementation/vars/page-vars/products.html?lang=en

//Fetch product details via data element var item = {}; 
var prod = digitalData.products;
if (prod.length > 0) {
item.Name = prod[0].productName;
item.ProductID = prod[0].productID;
item.ImageURL = prod[0].productImageURL;
item.URL = window.location.href;
item.Price = prod[0].productPrice; item.index = 0;
}
return item;

Viewed Product

<script type="text/javascript"> var item = _satellite.getVar('klaviyo_items'); //Ensure we have the required attributes (can be modifed) function isValidItem(item ) { return item !== undefined && item.hasOwnProperty('ImageURL') && item.ImageURL !== null && item.ImageURL !== undefined && item .hasOwnProperty('Price') && item.Price !== null && item.Price !== undefined;} if (isValidItem(item)) { geq.event('Viewed Product Reclaim', item); } </script>

Add to Cart

//Add to cart script - requires the Fetch Product Details Script above const primaryButtons = document.getElementsByClassName("btn btnPrimary"); 
const secondaryButtons = document.getElementsByClassName("btn btnSecondaryOne addToCartOrderBtn");

function isValidItem(atcItem) {
return atcItem !== undefined && atcItem.hasOwnProperty('ImageURL') && atcItem.ImageURL !== null && atcItem.ImageURL !== undefined && atcItem.hasOwnProperty('Price') && atcItem.Price !== null && atcItem.Price !== undefined;
}

function addToCartHandler(atcItem) {
if (isValidItem(atcItem)) { geq.addToCart(atcItem); }
}

function handleButtonClick() {
var atcItem = _satellite.getVar('klaviyo_items'); addToCartHandler(atcItem);
}

for (const button of primaryButtons) {
button.addEventListener("click", handleButtonClick);
}
for (const button of secondaryButtons) { button.addEventListener("click", handleButtonClick);
}
Did this answer your question?