Installation to React or NextJS applications

For React and NextJS applications, it's best to use use our React package. This package provides a React component that can be easily used. NextJS integration has a slightly different procedure, see below.

Please note: the projectCode property always refers to the workspace code that you can find in the Product Fruits administration.

React component setup

1. Install the React NPM package

npm install react-product-fruits --save

2. Find the right place where to put the component

This is very important. The <ProductFruits /> component must be inserted to the top-most place in your application tree that is possible. For example, if you use React Router, do not put it to every route. Put it to the <Routes> component directly (not to <Route />) or completely outside of it.

3. Import the package

For React applications, use standard import

import ProductFruits from 'react-product-fruits';

For NextJS applications, use dynamic import. This is needed because NextJS uses server-side rendering, but Product Fruits is only a frontend component.

const ProductFruits = dynamic(
    () => import('react-product-fruits'),
    { ssr: false }
)

4. Use the component

The component requires a few props. You have to provide the ID of your workspace, current language code, and current user information.

  • projectCode - code of your workspace, you will find it in the Installation section in the Product Fruits administration
  • language - 2 letter ISO language code, it has to match values you specified before in Product Fruits administration (see Workspace settings -> Supported Languages)
  • username - a unique identifier of the currently logged-in user
  • ... other user properties

For React applications, use the component as usual:

<ProductFruits projectCode="YOUR_PROJECT_CODE" language="ISO-2 CODE OF LOCALIZATION LANGUAGE" { ...userInfo } />

For NextJS applications, check if the window global variable exists.

{global.window && <ProductFruits projectCode="YOUR_PROJECT_CODE" language="ISO-2 CODE OF LOCALIZATION LANGUAGE" { ...userInfo } />}

TypeScript note

The Product Fruits React component currently doesn't include complete TypeScript types. If you use TypeScript and it complains about missing properties, please use the TypeScript special comment // @ts-ignore for the particular line.

Routing in NextJS

Product Fruits can randomly fail to detect URL changes in NextJS. You can see multipage tours randomly stopping. The solution is to turn off the default URL detection and notify Product Fruits about the page change. 

In your _app.tsx file, outside of the App component, add this snippet:

import Router from 'next/router'

if (global.window) {
    window.pfDisableUrlChangeDetection = true;
}

Router.events.on('routeChangeComplete', () => {
    window.productFruits.pageChanged();
});

// Here comes the App component function
//function App({ Component, pageProps }: AppProps) {

User data and custom attributes

Product Fruits can show different content based on different user attributes. These attributes can hold any primitive value (number, string). It is not required to provide any other identification than the user's unique identifier, but often it is needed. To help you get started, there are some built-in attributes that you can provide as props on the ProductFruits component:

  • email - optional
  • firstname - optional
  • lastname - optional
  • signUpAt - optional (can be any format but we recommend the ISO 8601 JSON DateTime format)
  • role - optional (can be any format)

You can also include other custom attributes. These have to be provided through props subobject. See the full working example below.

If you don't want to transfer real usernames to Product Fruits, you can hash them (i.e. MD5, SHA1).

Working with Product Fruits JS API

If you want to use Product Fruits API in your React application, it's best to use our useProductFruits hook.

useProductFruits(api => {
        if (your_dep == "something") {
            api.tours.tryStartTour(tourId);
        }
}, [your_dep]);

Dynamic CSS generation

If your project uses a library for CSS scoping (like Emotion), it probably generates dynamic CSS classes like css-a9fp3q. This will make issues with tours and hints as they use CSS selectors for targeting.

If there are no other stable attributes, consider this.

Full working example

You can check out a simple example of a React application using Product Fruits. The example uses React Context and React Router, so it simulates typical use cases.

See the GitHub repository

Here is a short showcase of working integration:

import React from 'react';
import ProductFruits from 'react-product-fruits';

export class App extends React.Component {
  render () {
    const { appUser } = this.props; // you have to provide user information from your store
    
    const userInfo = {
      username: appUser.username,
      email: appUser.email,
      firstname: appUser.firstname,
      lastname: appUser.lastname,
      signUpAt: appUser.signUpAt,
      role: appUser.role,
      props: { customProperty1: 123 }
    };

    return (
      <div>
        <ProductFruits projectCode="YOUR_PROJECT_CODE" language="ISO-2 CODE OF LOCALIZATION LANGUAGE" { ...userInfo } />
      </div>
    );
  }
}