Skip to end of metadata
Go to start of metadata

The Evergage Beacon can be integrated with web apps utilizing React for rendering views.

In general, when integrating third party libraries with React, the things you need to consider involve React maintaining an internal DOM representation. This also applies to Evergage and the JavaScript beacon source code.  For most sites, you won't need changes other than the Single Page Application tracking changes. 

For sites that have fairly dynamic rendered content that might change frequently or non-traditional page navigation techniques, the following tips and code snippets outline multiple approaches to ensuring a successful integration with the Evergage Beacon.


This Article Explains

This article details tips on how to integrate Evergage with React-based web apps.

Sections in this Article

Expose window level boolean returned by shouldComponentUpdate

React Docs on shouldComponentUpdate

When React determines if it needs to update components, it runs the shouldComponentUpdate hook. Returning false prevents the component from re-rendering.

By attaching the function lockForEvergage to the DOM Element we can effectively set the return value of shouldComponentUpdate from the window, which can be manipulated in any Evergage Campaign.

This allows Evergage messages to be present in any part of the page without unique code per message target.

NOTE

Parent elements utilizing the props.children method of defining children may rerender due to changes to the parent's model. There may be cases where this is desired (navigation), and other's where it is not (close an icon in one child removes it from the parent's props.children, causing a re-render for all children of the parent).

This method should not be used on route dependent elements.

Locking Component
shouldComponentUpdate() {
    return !this.state.doNotUpdate;
}

componentDidMount() {
    ReactDOM.findDOMNode(this).lockForEvergage = this.lockForEvergage.bind(this);
}

lockForEvergage() {
    this.state.doNotUpdate = true;
}
Window Level Usage
// Find and select dom element (jQuery, getElementById, etc)
element.lockForEvergage();
// DOM manipulating code.

Expose window level accessible setter for component state

This method allows Evergage to modify stores, so that existing components render with data provided by Evergage.

The rendering is thus handled by React, and there are no concerns of re-rendering unless the application updates the same stores.

NOTE

This method strictly limits possible targets for Evergage campaigns. The implementation can vary greatly between different libraries for handling stores/actions. Also, Evergage campaign stats handling (impressions, clickthroughs, and dismissals) must be coded into every campaign.
Component With State
constructor(props) {
    super(props);
    this.state = {
        recommendations: RecStore.getRecommendations()
    };
    this._onChange = this._onChange.bind(this);
}

_onChange() {
    this.setState({
        recommendations: RecStore.getRecommendations(),
        hasItems: true
    });
}

componentWillMount() {
    RecStore.addChangeListener(this._onChange);
}

componentDidMount() {
    ReactDOM.findDOMNode(this).updateForEvergage = RecActions.setRecommendations;
}

componentWillUnmount() {
    RecStore.removeChangeListener(this._onChange);
}
Store
const CHANGE = "CHANGE";
const FALLBACK_RECOMMENDATIONS = [
    {id: "1", name: "Product 1", price: "$1", imageUrl: "img/product1.jpg", url: "#"},
    {id: "2", name: "Product 2", price: "$2", imageUrl: "img/product2.jpg", url: "#"}
];
// Will need a standard, unchanging format for items
// such as {id, name, price, imageUrl} from this example
let _recState = {
    recommendations: FALLBACK_RECOMMENDATIONS
};

class RecStore extends EventEmitter {

    constructor(props) {
        super(props);
        Dispatcher.register(this._registerToActions.bind(this));
    }

    _registerToActions(action) {
        switch(action.actionType) {
            case ActionTypes.SET_RECOMMENDATIONS:
                this._setRecommendations(action.payload);
                break;
        }
    }

    _setRecommendations(products) {
        _recState.recommendations = products;
        this.emit(CHANGE);
    }

    getRecommendations() {
        return _recState.recommendations;
    }

    addChangeListener(callback) {
        this.on(CHANGE, callback);
    }

    removeChangeListener(callback) {
        this.removeListener(CHANGE, callback);
    }

}

export default new RecStore();
Action
class RecActions {
    setRecommendations(recommendations) {
        Dispatcher.dispatch({
            actionType: ActionTypes.SET_RECOMMENDATIONS,
            payload: recommendations
        });
    }
}

export default new RecActions();
Usage
var newProducts = [
    {id: "3", name: "Product", price: "$2.00", imageUrl: "img/product3.jpg", url:"#"},
    {id: "4", name: "Another Product", price: "$4.00", imageUrl: "img/product4.jpg", url:"#"}
]
element.updateForEvergage(newProducts);

Placeholder Components

Provides predefined empty space that will not rerender for Evergage to place a message.

Evergage functionality will work out of the box when targeting these elements specifically.

NOTE

This method strictly limits possible targets for Evergage campaigns. Testing control vs existing content requires placeholders next to content and non-ideal CSS to hide existing content.
Placeholder Component
class EvergagePlaceholder extends React.Component {

    shouldComponentUpdate() {
        return false;
    }

    render() {
        return (
            <div id={this.props.placeholderId}></div>
        )
    }
}

export default EvergagePlaceholder;
Placeholder Component Usage within Parent
<EvergagePlaceholder placeholderId='evergage-bottom-banner' />

Single Page Applications

For single page applications, Evergage needs to know when it should track a page navigation event.  Most modern browsers support a combination of these mechanisms for tracking page navigation with Single Page Applications:

  1. HTML5 History API
  2. hashchange Event
  3. URL Changes

You'll need to update the Evergage configuration for your site with the following settings to take advantage of this integration:

  1. From the Evergage Web App, navigate to Settings > General Setup > Advanced Options
  2. In the section Treat Hash Changes in Location as New Page load, select the option

Evergage Component Integration and Server Side Rendering

Evergage also provides Custom Component Integrations for the following campaign message types:

  • Recommendations
  • In-Line Messages

The current libraries are in preview.  Please contact your Account representative for more detailed information and access to this option.

With Item Templates Via The Evergage Web App

This option utilizes the item template that you create via the Visual Editor or the Evergage Web App. The configuration options that you set on the targetted element will apply to the Recommendations component target element.

With Custom Rendering Based Upon Evergage Promoted Items Response

This option uses the list of promotedItems in the Evergage Campaign response, to which you can style with your own templates or settings in your web application. This option will ignore any style or item template configuration configured in the Evergage Web App.

Personalize React Installation
npm install --save @evergage/personalize-react
Inline Message From Item Templates Component Usage
import { Recommendations } from "@evergage/personalize-react";

...

<Recommendations target="div#evg-recommendations" />
Promoted Items Component Usage
import { Recommendations } from "@evergage/personalize-react";

...

<Recommendations target="div#evg-recommendations" render={ (campaign, promotedItems) => {
  return (
    <div className="columns is-multiline is-mobile products">
      {
        promotedItems.map((item, index) => {
          return (
            <div key={item.name + index} className="column is-6-mobile is-4-tablet is-3-desktop is-3-widescreen is-3-fullhd available">
              <a
                data-evg-item-id={item.id}
                data-evg-item-type={item.type}
                data-evg-campaign={campaign.campaignId}
                data-evg-experience={campaign.experienceId}
                data-evg-group={campaign.userGroup}
                aria-current="false"
                href={item.url}
              >
                <figure className="image" style={{ height: "220px" }}>
                    <img src={item.imageUrl} alt={item.name} title={item.name}/>
                </figure>
                <div className="content product-caption">
                  <div className="product-name">{item.name}</div>
                  <div className="product-price">${item.price}</div>
                </div>
              </a>
            </div>
          )
        })
      }
    </div>
  )
}}/>

Dataset Configuration

You'll need to configure your Evergage dataset with Single Page Application configuration options.

Access these configuration options via the Evergage Web App:

  1. From the Evergage Platform, navigate to Settings > General Setup > Advanced Options
  2. Select Treat Hash Changes in Location as New Page Load

Campaign Configuration

Create a Web Recommendations Campaign that is set up for recommendations in the Evergage Platform.

Pay close attention to the selector you specify in SETUP > Experiences > Messages, as you will need to use this as the target of your Recommendations component.

This will be the value you pass into your Recommendations component in Message Settings.

  • No labels