This blog post is mainly aimed at Magento agencies building a mono-repo around PWA Studio and having a need to make an easy yet extensible way to add Enhanced eCommerce.
Note that if you don't have a mono repo setup like PWA Studio you won't need the React Context
Overview:
- Adding Google Tag Manager
- Creating a React Context
- Setting up a basic data layer file
- Implementing the data layer methods
Adding Google Tag Manager
Add the code below, make sure to add your own GTM code.
I'd advice you to make the GTM code variable so you can connect to multiple containers based on your build/pipeline etc.
//template.html (the inside your storefront)
<script>
dataLayer = [];
</script>
<!-- Google Tag Manager -->
<script>
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXX');
</script>
<!-- End Google Tag Manager -->
Creating a React Context
Since we are working inside a mono-repo we want to be able to customise what data we send to the data layer per customer that's build upon the mono-repo.
So firstly locate the position where you'd normally would create context's inside your project.
Add the following files:
context/dataLayer/index.js
context/dataLayer/dataLayer.js
context/dataLayer/data.js
//context/dataLayer/index.js
export { DataLayerProvider, useDataLayerConfig } from './dataLayer';
//context/dataLayer/dataLayer.js
import React, { useContext } from 'react';
import { node, object } from 'prop-types';
import { merge } from 'lodash-es';
import { dataLayerConfig } from './data';
export const DataLayer = React.createContext(null);
const defaultDataLayer = dataLayerConfig;
export const DataLayerProvider = ({ children, additionalDataLayer = {} }) => {
return (
<DataLayer.Provider
value={merge({}, defaultDataLayer, additionalDataLayer)}
>
{children}
</DataLayer.Provider>
);
};
export const useDataLayerConfig = () => useContext(DataLayer);
DataLayerProvider.propTypes = {
children: node.isRequired,
query: object,
additionalDataLayer: object,
};
//context/dataLayer/data.js
export const dataLayerConfig = {
reset: {
product: () => ({
ecommerce: undefined,
items: undefined,
}),
category: () => ({
ecommerce: undefined,
items: undefined,
}),
},
product: data => ({
event: 'virtualPageview',
pagePath: window.location.href,
pageTitle: `${data.name} - ${STORE_NAME}`,
pageType: 'product',
items: [
{
id: data.sku,
},
],
ecommerce: {
detail: {
products: [
{
name: data.name,
id: data.sku,
},
],
},
},
}),
cms: data => ({
event: 'virtualPageview',
pagePath: window.location.href,
pageTitle: `${data.title} - ${STORE_NAME}`,
pageType: 'cms',
}),
category: data => ({
event: 'virtualPageview',
pagePath: window.location.href,
pageTitle: `${data.category.name} - ${STORE_NAME}`,
pageType: 'category',
}),
removeFromCart: data => ({
event: 'removeFromCart',
ecommerce: {
remove: {
products: [
{
name: data.product.name,
id: data.product.sku,
quantity: data.quantity,
},
],
},
},
}),
addToCart: data => ({
event: 'addToCart',
items: [
{
id: data.sku,
},
],
ecommerce: {
add: {
products: [
{
name: data.name,
id: data.sku,
quantity: data.quantity,
},
],
},
},
}),
};
Note that this a really small example file, you should add more methods like submitOrder, checkoutSuccess, checkout, notFound etc etc
Make sure to import the Context into the storefront and add it to the provider tree.
//index.js (the on in your storefront)
<AppContextProvider>
<DataLayerProvider>
...
</DataLayerProvider>
</AppContextProvider>
Implementing the data layer methods
So we've set up the basic of this solution
Top comments (3)
@jordaneisenburg thanks for sharing your knowledge. can this be implemented with node GTM module github.com/alinemorelli/react-gtm
I am very new to Pwa studio and working on applying google analytics in my pwa project and now kind of stuck and rely hoping to get some help!!!!
@jordaneisenburg thank you so much for your blog. I'm stuck at at which place to put all the "//context/" files in PWA repo?