# Eko Gallery React

A library for integrating the [eko](https://eko.com) gallery into your react based site.

## Installation

```bash
npm install @ekolabs/eko-gallery-react
```

OR

```bash
yarn add @ekolabs/eko-gallery-react
```

## Usage

### EkoGallery Component

The `EkoGallery` component is used to render the eko gallery on your site. It should replace your existing product gallery component.

```jsx
import { EkoGallery } from '@ekolabs/eko-gallery-react';

<EkoGallery 
    className="mb-4"
    config={config}
    variantId={variantId}
    onEvent={onEkoGalleryEvent}>
    {/* Your existing product gallery component that will serve as a fallback */}
    <CustomerGalley />
</EkoGallery>
```

This component accepts the following props:

| Prop | Type | Description |
| ---- | ---- | ----------- |
| className | String | _Optional._ class names to add to the `EkoGallery` component, for styling purposes for example |
| config | Object | The eko gallery configuration. This object will be published via the eko platform and exposed via an api endpoint (see below) |
| variantId | String | _Optional._ The selected variant (if applicable). It is used to switch to the relevant variant gallery assets when the product variant changes |
| onEvent | Function | _Optional._ Handler for events occurred in the eko gallery, for third party tools tracking for example |

> When passing the `onEvent` prop, make sure to use the `useCallback()` hook to avoid unnecessary re-renders.

### Config data fetching

To get the eko product configs, you should use the `getEkoProductConfigUrl()` function to get the url, fetch the data and pass it to the `EkoGallery` component.

The `getEkoProductConfigUrl()` receives the eko sales channel id and returns the url to fetch the eko product configs from.

```js
import { getEkoProductConfigUrl } from '@ekolabs/eko-gallery-react';

const EKO_SALES_CHANNEL_ID = process.env.EKO_SALES_CHANNEL_ID;

const ekoProductConfigUrl = getEkoProductConfigUrl(EKO_SALES_CHANNEL_ID);
const ekoProductResponse = await fetch(ekoProductConfigUrl).then(res => res.json());
const ekoProductConfigs = ekoProductResponse.data;
```

### Analytics setup

Our 1st party tracking tool should be added in order to track events on the site.

#### The eko analytics snippet

The eko analytics snippet should be added to the site's head tag, here is an example in `Next.js`:

```jsx
// _document.tsx

import Script from 'next/script';
import { getEkoAnalyticsSnippet } from '@ekolabs/eko-gallery-react';

const IS_PRODUCTION = process.env.NODE_ENV === 'production';

render() {
    return (
        <Html lang="en">
            <Head>
                <Script id="eko-analytics-snippet" strategy="beforeInteractive">
                    {getEkoAnalyticsSnippet(IS_PRODUCTION)}
                </Script>
            </Head>
            <body>
                <Main />
                <NextScript />
            </body>
        </Html>
    );
}
```
### Events

The eko gallery exposes every user `interaction` event through the `onEvent` handler.
The event's payload object has the following structure:

| Property | Type | Description |
| ---- | ---- | ----------- |
| elementid | String | A unique identifier of the element that was interacted with |
| elementtype | String | The type of element. This usually describes the action or function the element serves |
| elementname | String | A textual representation of the element |

#### Example

```jsx
const onEkoGalleryEvent = useCallback((event, data) => {
    console.log(`*** Received Eko Event: ${event}
*** Payload: ${JSON.stringify(data)}`);
}, []);
```

Console:
```
*** Received Eko Event: interaction
*** Payload: {"elementid":"introB-loop-button","elementtype":"start","elementname":"Explore Product"}
*** Received Eko Event: interaction
*** Payload: {"elementid":"KoWmOq-next","elementtype":"next button"}
*** Received Eko Event: interaction
*** Payload: {"elementid":"sequence-button-2","elementtype":"choice button","elementname":"Dimensions"}
```

#### ekoWebPixel

The `ekoWebPixel` API is used to track the events on your site.

Init once via the `init()` method:

```jsx
import { ekoWebPixel } from '@ekolabs/eko-gallery-react';

const IS_PRODUCTION = process.env.NODE_ENV === 'production';

useEffect(() => {
    ekoWebPixel.init(IS_PRODUCTION);
}, []);
```

Track events via the `track()` method:

```jsx
import { ekoWebPixel } from '@ekolabs/eko-gallery-react';

ekoWebPixel.track('pixel.page_viewed');
ekoWebPixel.track('pixel.product_viewed', { ... });
ekoWebPixel.track('pixel.cart.add', { ... });
ekoWebPixel.track('pixel.cart.remove', { ... });

// For traffic allocation:
ekoWebPixel.track('trafficallocation.decision', { ... });

// For non shopify backend stores:
ekoWebPixel.track('pixel.checkout', { ... });
ekoWebPixel.track('pixel.order', { ... });
```

Report on route changes:

```jsx
import { ekoWebPixel } from '@ekolabs/eko-gallery-react';

ekoWebPixel.onRouteChanged();
```
