diff --git a/examples/nextjs/components/Cart/Cart.js b/examples/nextjs/components/Cart/Cart.js
index 4b9ee60d..107a09d7 100644
--- a/examples/nextjs/components/Cart/Cart.js
+++ b/examples/nextjs/components/Cart/Cart.js
@@ -1,4 +1,4 @@
-import React, { useState, useEffect } from 'react';
+import React, { useState, useEffect, useContext } from 'react';
import Link from 'next/link';
import Image from 'next/image';
import { useCheckout, useCart } from '@nacelle/react-hooks';
@@ -8,6 +8,7 @@ import { formatCurrency } from '@nacelle/react-dev-utils';
import ItemQuantity from 'components/ItemQuantity';
import useDetectDevice from 'hooks/useDetectDevice';
import * as styles from './Cart.styles';
+import { EventLogContext } from 'providers/EventDispatcher';
const checkoutCredentials = {
nacelleSpaceId: process.env.NACELLE_SPACE_ID,
@@ -21,9 +22,10 @@ const Cart = () => {
checkoutCredentials,
cart
);
-
+ const { dispatchEvent } = useContext(EventLogContext);
useEffect(() => {
if (checkoutData) {
+ dispatchEvent({ type: 'CHECKOUT_INIT', payload: checkoutData });
const { processCheckout } = checkoutData.data;
window.location = processCheckout.url;
}
@@ -75,6 +77,7 @@ const Cart = () => {
const CartItem = ({ item, cartActions, isMobile }) => {
const [itemQuantity, updateQuantity] = useState(item.quantity || 0);
+ const { dispatchEvent } = useContext(EventLogContext);
const formatPrice = formatCurrency(item.locale, item.priceCurrency);
@@ -96,7 +99,10 @@ const CartItem = ({ item, cartActions, isMobile }) => {
return updateQuantity(qty);
};
- const removeItemFromCart = () => cartActions.removeFromCart(item);
+ const removeItemFromCart = () => {
+ dispatchEvent({ type: 'REMOVE_FROM_CART', payload: item });
+ return cartActions.removeFromCart(item);
+ };
return (
diff --git a/examples/nextjs/components/ProductCard/ProductCard.js b/examples/nextjs/components/ProductCard/ProductCard.js
index bb616eb0..7cede00e 100644
--- a/examples/nextjs/components/ProductCard/ProductCard.js
+++ b/examples/nextjs/components/ProductCard/ProductCard.js
@@ -1,4 +1,4 @@
-import React, { useState } from 'react';
+import React, { useState, useContext } from 'react';
import Link from 'next/link';
import Image from 'next/image';
import { useCart } from '@nacelle/react-hooks';
@@ -8,6 +8,7 @@ import { formatCurrency } from '@nacelle/react-dev-utils';
import ItemQuantity from 'components/ItemQuantity';
import useDetectDevice from 'hooks/useDetectDevice';
import * as styles from './ProductCard.styles';
+import { EventLogContext } from 'providers/EventDispatcher';
const LinkPDP = ({ pdpLink, children }) => {
if (!pdpLink) {
@@ -34,6 +35,7 @@ const ProductCard = ({
const [quantity, setQuantity] = useState(0);
const [, { addToCart, toggleCart }] = useCart();
const device = useDetectDevice();
+ const { dispatchEvent } = useContext(EventLogContext);
const productLink = `/products/${product.handle}`;
const productVariant = product.variants[0];
@@ -44,8 +46,8 @@ const ProductCard = ({
const addItemToCart = () => {
const item = { ...product, variant: productVariant, quantity };
-
addToCart(item);
+ dispatchEvent({ type: 'ADD_TO_CART', payload: item });
return toggleCart();
};
diff --git a/examples/nextjs/pages/_app.js b/examples/nextjs/pages/_app.js
index f24e65ea..9ace67cc 100644
--- a/examples/nextjs/pages/_app.js
+++ b/examples/nextjs/pages/_app.js
@@ -6,17 +6,20 @@ import { CartProvider } from '@nacelle/react-hooks';
import Layout from 'components/Layout';
import $nacelle from 'services/nacelle.js';
import { ProductSearchProvider } from 'providers/ProductSearch';
+import { EventDispatcherProvider } from 'providers/EventDispatcher';
import * as styles from 'styles/global.styles';
function MyApp({ Component, pageProps, space, products }) {
return (
-
-
-
-
-
+
+
+
+
+
+
+
);
}
diff --git a/examples/nextjs/pages/pages/[handle].js b/examples/nextjs/pages/pages/[handle].js
index df01eee9..db8895b7 100644
--- a/examples/nextjs/pages/pages/[handle].js
+++ b/examples/nextjs/pages/pages/[handle].js
@@ -1,11 +1,17 @@
-import React from 'react';
+import React, { useEffect, useContext } from 'react';
import { useRouter } from 'next/router';
import $nacelle from 'services/nacelle.js';
import { dataToPaths } from 'utils';
+import { EventLogContext } from 'providers/EventDispatcher';
const Page = ({ page }) => {
const router = useRouter();
+ const { dispatchEvent } = useContext(EventLogContext);
+ useEffect(() => {
+ dispatchEvent({ type: 'PAGE_VIEW' });
+ }, []);
+
// If the page is not yet generated, this will be displayed
// initially until getStaticProps() finishes running
if (router.isFallback) {
diff --git a/examples/nextjs/pages/products/[handle].js b/examples/nextjs/pages/products/[handle].js
index 7c9dbd23..7c2e3094 100644
--- a/examples/nextjs/pages/products/[handle].js
+++ b/examples/nextjs/pages/products/[handle].js
@@ -1,14 +1,20 @@
-import React from 'react';
+import React, { useEffect, useContext } from 'react';
import { useRouter } from 'next/router';
import $nacelle from 'services/nacelle';
import { dataToPaths } from 'utils';
import ProductCard from 'components/ProductCard';
import * as styles from 'styles/pages.styles';
+import { EventLogContext } from 'providers/EventDispatcher';
const ProductDetail = ({ product }) => {
const router = useRouter();
+ const { dispatchEvent } = useContext(EventLogContext);
+ useEffect(() => {
+ dispatchEvent({ type: 'PRODUCT_VIEW', payload: product });
+ }, []);
+
// If the page is not yet generated, this will be displayed
// initially until getStaticProps() finishes running
if (router.isFallback) {
diff --git a/examples/nextjs/providers/EventDispatcher.js b/examples/nextjs/providers/EventDispatcher.js
new file mode 100644
index 00000000..3a650a52
--- /dev/null
+++ b/examples/nextjs/providers/EventDispatcher.js
@@ -0,0 +1,63 @@
+import React, { useEffect, useReducer } from 'react';
+
+export const EventLogContext = React.createContext();
+
+const eventReducer = (state, event) => {
+ if (
+ event.type === 'PAGE_VIEW' ||
+ event.type === 'PRODUCT_VIEW' ||
+ event.type === 'ADD_TO_CART' ||
+ event.type === 'REMOVE_FROM_CART' ||
+ event.type === 'CHECKOUT_INIT'
+ ) {
+ return [...state, event];
+ }
+ return state;
+};
+
+export const EventDispatcherProvider = ({ children }) => {
+ const [eventLog, dispatchEvent] = useReducer(eventReducer, []);
+
+ useEffect(() => {
+ if (eventLog.length > 0 && typeof window !== 'undefined') {
+ const event = eventLog.pop();
+ switch (event.type) {
+ case 'PAGE_VIEW':
+ console.log('PAGE VIEW EVENT FIRED');
+ break;
+ case 'PRODUCT_VIEW':
+ console.log(
+ 'PRODUCT_VIEW EVENT FIRED',
+ JSON.stringify(event.payload, null, 2)
+ );
+ break;
+ case 'ADD_TO_CART':
+ console.log(
+ 'ADD_TO_CART EVENT FIRED',
+ JSON.stringify(event.payload, null, 2)
+ );
+ break;
+ case 'REMOVE_FROM_CART':
+ console.log(
+ 'REMOVE_FROM_CART EVENT FIRED',
+ JSON.stringify(event.payload, null, 2)
+ );
+ break;
+ case 'CHECKOUT_INIT':
+ console.log(
+ 'CHECKOUT_INIT EVENT FIRED',
+ JSON.stringify(event.payload, null, 2)
+ );
+ break;
+ default:
+ break;
+ }
+ }
+ }, [eventLog]);
+
+ return (
+
+ {children}
+
+ );
+};