Refer a Friend with Mention Me and React

Recently, onefinestay teamed up with Mention Me to incorporate refer-a-friend functionality into our React web app.

A day-long boardroom session proved fruitful in accomplishing the task, which was not without caveats given its greenfield nature.

We hit an obstacle early on in the process: Mention Me’s turnkey solution, and onefinestay’s React front-end appear — from the outside, at least — to be inherently incompatible. Close communication and creative solution design enabled us to surmount the barrier, and, because our use case is by no means unique, provide advice for anyone facing similar integration gotchas.

The challenges here are twofold: Mention Me’s widget script needs to be loaded into the document after the element that will house its widget exists in the DOM. In addition, Mention Me is designed to fill out a text field with a coupon code, after the user has completed the referral journey. While the approach proves elegant for the majority of websites, ours — being a single-page app — does not necessarily render the DOM before JavaScripts are loaded. And React, with its virtual DOM approach, doesn’t accommodate the latter scenario easily as it discourages support for two-way binding with the rendered DOM by design.

Workarounds do exist, however — chiefly in React’s ability to reference rendered DOM elements, and the manner in which its internal component state is handled. Equally importantly, we found a way to insert third-party scripts into the document within React’s component lifecycle.

Here’s an in-depth account of how we accomplished the task of integrating Mention Me into onefinestay’s checkout flow, replete with fully-commented code samples to expedite your own implementation.

Step 1

Firstly, we used react-helmet to insert the Mention Me script tag dynamically, as our component loads.

This ensures that the script is invoked immediately after the widget’s container element has rendered, and that the <script> tag is removed from the <head> when the component is unmounted.

Step 2

Next, we added an invisible input to our render function, that stores a self-reference within the React component. Its name parameter corresponds with the input selector provided to Mention Me, so that the third-party script can update its value dynamically. We’ll be checking this input periodically for changes.

Step 3

We then added handler logic to our component. Ten times per second, the handler checks the value of the hidden input field in the rendered DOM against the inputValue stored in the component’s state.

If the two are out-of-sync, it updates the value in the component’s state, and performs some functions related to the updated data received from Mention Me. This is known as dirty checking, a once-popular practice largely frowned upon these days, but inevitable in this case.

Once we’ve updated the promoCode value in our Redux store using a Redux action creator named changePromoCodeInput, we’re able to feed that value back into our rendered component. The resultant value will be visible to the user in a Redux-connected text field.

In our application, the handleSubmit function automatically submits the form when the value has been filled in from Mention Me.

While we’re using Redux, the same general idea applies to most Flux-influenced React state libraries.

Step 4

Finally, we clear our dirty-checking interval and any reference to it when the component unmounts, preventing memory leaks that arise from unterminated loops.

Putting it all together

Several days after implementing this solution, we released our refer-a-friend functionality into the wild. It can be found on the checkout pages of onefinestay.com, which can be accessed when booking with us — a cheeky incentive!

We’re pleased to have spearheaded the introduction of the excellent Mention Me platform into one of the world’s most popular JavaScript app frameworks, and we hope this information will be a valuable resource to anyone coming up against a similar challenge.

Think you have what it takes to build creative solutions at onefinestay? We’re hiring!