Link Replacement

Link Replacement enables the Tipser Script/Tipser Elements to automatically replace affiliate link outs and product links into native commerce experience, handled by Bolt 1-click checkout and payment.

📘

Experimental

This feature is in the beta version and publicly available form the v.4.2.1 version onwards.

Getting started

Tipser Script and Tipser Elements require a configuration object to be specified at initialization, which typically looks as follows:

const config = { lang: "en-US" };

//Tipser Elements


<TipserElementsProvider
    posId="POS_ID"
    config={config}
  ></TipserElementsProvider>

// Tipser Script usage

tipserScript.initialize("POS_ID", config);

Enabling link replacement

Add a new entry to the config, called linkReplacement with proper contents in order to activate the link replacement behavior.

const config = {
   linkReplacement: {
      enabled: true,
      urls: ['bcgb.com', 'awin.com'],
      market: 'us',
      withObserver: true
   }
};

And pass the following object to the initialisation, for example:

const config = {
   linkReplacement: {
      enabled: true,
      urls: ['bcgb.com', 'awin.com'],
      market: 'us',
      withObserver: true
   }
};

tipserScript.initialize("POS_ID", config);

Voilà, you're set up! 🎉 Now, the script will activate itself and detect all the links from the specified urls and support native 1-click Bolt checkout for all products matched in our product catalog. any link within the allowlisted range of urls array will open a native dialog checkout.

Configuration reference

All parameters must be nested in the top-level linkReplacement config object.

Parameter nameTypeDescription
enabledbooleanRequired - Flag indicating that link replacement should be enabled; default: false
urlsstring[]Required - An allow-list of all URL fragments that the script will scan across and attempt to look-up in Bolt catalog. The URLs do not need schema and the scan is done by matching all URLs found on the enclosed website via “case-insensitive string contains” strategy.

If empty or not specified, no links will be matched.
marketstring - "US" | "UK"Required parameter specifying the inventory market. Needs to be set for the proper URL matching.
withObserverbooleanIf set to true, the script will listen to all HTML changes and reactively attach native checkout action to new looked up links (needed for dynamically loaded content).
onClick(target: LinkMetadata, resume: (boolean) => void) => voidIf set, will be called whenever the user clicks on the link that has been matched.

Useful to handle custom analytics, cleanup actions or override the onClick behavior (continue with rendering native dialog or pass-through - allow the link out).

Last argument is a resume token callback that has to be called with a boolean argument. If the argument is true, the native checkout will be rendered. If false, the link will not open the checkout but will preserve its original behavior.
customClassstringIf set, every anchor that has the native checkout attached to it via link replacement, will also have the customClass attached to the class list. Can be used to alter the styling/display of the element.

onClick usages

Detailed reference of how to use onClick and how it may be used to implement A/B tests or attach custom conditional pre/post-render actions.

LinkMetadata schema

interface LinkMetadata {
	url: string,
	element: HTMLElement,
	scanned: boolean,
	product: ProductModel
}

ProductModel follows the schema of the API response as documented in our API docs.

Simple randomized traffic split

Show native checkout for randomly selected 50% of actions globally.

const config = {
   linkReplacement: {
      enabled: true,
	    onClick: (target, resume) => {
		     resume(Math.random() < 0.5);
	    }
   }
};

Simple 50-50 traffic split

Simple local storage-based implementation of the A/B version persistence and behavior differentiation based on that (to ie. implement a 50-50 A/B test of native vs affiliate). This one however stays with the used during this single and every next session on the same device, given no incognito mode is on.

// simple persistence so a shopper has a consistent
// experience when clicking on any recognized link

const key = 'bolt__native_checkout_experiement';
let renderNativeCheckout;
if (localStorage.getItem(key) !== null) {
   renderNativeCheckout = localStorage.getItem(key);
} else {
   renderNativeCheckout = Math.random() < 0.5;
   localStorage.setItem(key);
}
const config = {
   linkReplacement: {
      enabled: true,
	    onClick: (target, resume) => {
         resume(renderNativeCheckout);
	    }
   }
};

Pre- and post-render hook

Below example showcases how the developer can hook in custom analytics before and after the product native checkout is rendered. Notice also how the product data can be extracted from the event payload and passed to the analytics.event handler.

const config = {
   linkReplacement: {
     enabled: true,
     onClick: (target, resume) => {
       analytics.event('link-click-pre-render', { data: target.product } );
       resume(true);
       analytics.event('link-click-post-render', { data: target.product } );
     }
   }
};

Show native checkout only for specific brand

const config = {
  linkReplacement: {
     enabled: true,
     onClick: (target, resume) => {
       resume(target.product.merchantName === 'Nike x Supreme');
     }
  }
};

Show native checkout only for in stock products

Another example - overriding the default behaviour of opening the native checkout regardless of the stock count - trigger native checkout dialog only if the product that was matched is in stock.

const config = {
  linkReplacement: {
     enabled: true,
     onClick: (target, resume) => resume(target.product.isInStock)
  }
};