@graphcommerce/googleanalytics 6.0.0-canary.50 → 6.0.0-canary.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Change Log
2
2
 
3
+ ## 6.0.0-canary.52
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1809](https://github.com/graphcommerce-org/graphcommerce/pull/1809) [`2da3c9214`](https://github.com/graphcommerce-org/graphcommerce/commit/2da3c92148aef08813b95e404a25796acf0eefd2) - Added useMemoObject and implement in GaViewItem, GoogleAnalyticsItemList and GaCartStartCheckoutLinkOrButton ([@mikekeehnen](https://github.com/mikekeehnen))
8
+
9
+ ## 6.0.0-canary.51
10
+
3
11
  ## 6.0.0-canary.50
4
12
 
5
13
  ## 6.0.0-canary.49
package/README.md CHANGED
@@ -12,6 +12,9 @@ Besides the GA4 integration it also tracks the following events:
12
12
  - begin_checkout
13
13
  - select_item
14
14
  - view_item_list
15
+ - view_item
16
+ - view_cart
17
+ - remove_from_cart
15
18
 
16
19
  ## Configuration
17
20
 
@@ -1,4 +1,4 @@
1
- import { nonNullable, useMemoDeep } from '@graphcommerce/next-ui'
1
+ import { nonNullable, useMemoObject } from '@graphcommerce/next-ui'
2
2
  import { useEventCallback } from '@mui/material'
3
3
  import React, { useContext, useEffect, useMemo } from 'react'
4
4
  import { ProductToGtagItemFragment } from '../events/productToGtagItem/ProductToGtagItem.gql'
@@ -39,15 +39,11 @@ export function GoogleAnalyticsItemList<
39
39
  >(props: UseGtagViewItemListProps<P> & { children: React.ReactNode }) {
40
40
  const { title, items, listId, children } = props
41
41
 
42
- const eventData: ViewItemList = useMemoDeep(
43
- () => ({
44
- item_list_id: listId ?? title?.toLowerCase().replace(/\s/g, '_'),
45
- item_list_name: title,
46
- items:
47
- items?.map((item) => (item ? productToGtagItem(item) : null)).filter(nonNullable) ?? [],
48
- }),
49
- [listId, items, title],
50
- )
42
+ const eventData: ViewItemList = useMemoObject({
43
+ item_list_id: listId ?? title?.toLowerCase().replace(/\s/g, '_'),
44
+ item_list_name: title,
45
+ items: items?.map((item) => (item ? productToGtagItem(item) : null)).filter(nonNullable) ?? [],
46
+ })
51
47
 
52
48
  useEffect(() => globalThis.gtag?.('event', 'view_item_list', eventData), [eventData])
53
49
 
@@ -0,0 +1,36 @@
1
+ fragment GtagRemoveFromCart on Cart @inject(into: ["CartItemCountChanged"]) {
2
+ __typename
3
+ prices {
4
+ grand_total {
5
+ currency
6
+ value
7
+ }
8
+ }
9
+ items {
10
+ __typename
11
+ uid
12
+ product {
13
+ uid
14
+ sku
15
+ name
16
+ }
17
+ prices {
18
+ price {
19
+ value
20
+ currency
21
+ }
22
+ discounts {
23
+ amount {
24
+ value
25
+ }
26
+ }
27
+ }
28
+ quantity
29
+ ... on ConfigurableCartItem {
30
+ configured_variant {
31
+ uid
32
+ sku
33
+ }
34
+ }
35
+ }
36
+ }
@@ -0,0 +1,22 @@
1
+ import { GtagRemoveFromCartFragment } from './GtagRemoveFromCart.gql'
2
+
3
+ export function gtagRemoveFromCart<C extends GtagRemoveFromCartFragment>(cart?: C | null) {
4
+ if (!cart) return
5
+
6
+ globalThis.gtag?.('event', 'remove_from_cart', {
7
+ currency: cart?.prices?.grand_total?.currency,
8
+ value: cart?.prices?.grand_total?.value,
9
+ items: cart?.items?.map((item) => ({
10
+ item_id: item?.product.sku,
11
+ item_name: item?.product.name,
12
+ currency: item?.prices?.price.currency,
13
+ discount: item?.prices?.discounts?.reduce(
14
+ (sum, discount) => sum + (discount?.amount?.value ?? 0),
15
+ 0,
16
+ ),
17
+ item_variant: item?.__typename === 'ConfigurableCartItem' ? item.configured_variant.sku : '',
18
+ price: item?.prices?.price.value,
19
+ quantity: item?.quantity,
20
+ })),
21
+ })
22
+ }
@@ -0,0 +1,35 @@
1
+ fragment GtagViewCart on Cart @inject(into: ["CartItemCountChanged"]) {
2
+ prices {
3
+ grand_total {
4
+ currency
5
+ value
6
+ }
7
+ }
8
+ items {
9
+ __typename
10
+ uid
11
+ product {
12
+ uid
13
+ sku
14
+ name
15
+ }
16
+ prices {
17
+ price {
18
+ value
19
+ currency
20
+ }
21
+ discounts {
22
+ amount {
23
+ value
24
+ }
25
+ }
26
+ }
27
+ quantity
28
+ ... on ConfigurableCartItem {
29
+ configured_variant {
30
+ uid
31
+ sku
32
+ }
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,22 @@
1
+ import { GtagViewCartFragment } from './GtagViewCart.gql'
2
+
3
+ export function gtagViewCart<C extends GtagViewCartFragment>(cart?: C | null) {
4
+ if (!cart) return
5
+
6
+ globalThis.gtag?.('event', 'view_cart', {
7
+ currency: cart?.prices?.grand_total?.currency,
8
+ value: cart?.prices?.grand_total?.value,
9
+ items: cart?.items?.map((item) => ({
10
+ item_id: item?.product.sku,
11
+ item_name: item?.product.name,
12
+ currency: item?.prices?.price.currency,
13
+ discount: item?.prices?.discounts?.reduce(
14
+ (sum, discount) => sum + (discount?.amount?.value ?? 0),
15
+ 0,
16
+ ),
17
+ item_variant: item?.__typename === 'ConfigurableCartItem' ? item.configured_variant.sku : '',
18
+ price: item?.prices?.price.value,
19
+ quantity: item?.quantity,
20
+ })),
21
+ })
22
+ }
@@ -24,8 +24,8 @@ export type GtagItem = {
24
24
 
25
25
  export function productToGtagItem<P extends ProductToGtagItemFragment>(item: P): GtagItem {
26
26
  return {
27
- item_name: item.name ?? '',
28
27
  item_id: item.sku ?? '',
28
+ item_name: item.name ?? '',
29
29
  price: item.price_range?.minimum_price.final_price.value ?? undefined,
30
30
  currency: item.price_range?.minimum_price.final_price.currency ?? undefined,
31
31
  discount: item.price_range?.minimum_price.discount?.amount_off ?? undefined,
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@graphcommerce/googleanalytics",
3
3
  "homepage": "https://www.graphcommerce.org/",
4
4
  "repository": "github:graphcommerce-org/graphcommerce",
5
- "version": "6.0.0-canary.50",
5
+ "version": "6.0.0-canary.52",
6
6
  "sideEffects": false,
7
7
  "prettier": "@graphcommerce/prettier-config-pwa",
8
8
  "eslintConfig": {
@@ -12,18 +12,18 @@
12
12
  }
13
13
  },
14
14
  "dependencies": {
15
- "@graphcommerce/graphql-mesh": "6.0.0-canary.50",
16
- "@graphcommerce/magento-cart": "6.0.0-canary.50",
17
- "@graphcommerce/magento-cart-payment-method": "6.0.0-canary.50",
18
- "@graphcommerce/magento-cart-shipping-method": "6.0.0-canary.50",
19
- "@graphcommerce/magento-product": "6.0.0-canary.50",
20
- "@graphcommerce/next-config": "6.0.0-canary.50",
21
- "@graphcommerce/next-ui": "6.0.0-canary.50"
15
+ "@graphcommerce/graphql-mesh": "6.0.0-canary.52",
16
+ "@graphcommerce/magento-cart": "6.0.0-canary.52",
17
+ "@graphcommerce/magento-cart-payment-method": "6.0.0-canary.52",
18
+ "@graphcommerce/magento-cart-shipping-method": "6.0.0-canary.52",
19
+ "@graphcommerce/magento-product": "6.0.0-canary.52",
20
+ "@graphcommerce/next-config": "6.0.0-canary.52",
21
+ "@graphcommerce/next-ui": "6.0.0-canary.52"
22
22
  },
23
23
  "devDependencies": {
24
- "@graphcommerce/eslint-config-pwa": "6.0.0-canary.50",
25
- "@graphcommerce/prettier-config-pwa": "6.0.0-canary.50",
26
- "@graphcommerce/typescript-config-pwa": "6.0.0-canary.50",
24
+ "@graphcommerce/eslint-config-pwa": "6.0.0-canary.52",
25
+ "@graphcommerce/prettier-config-pwa": "6.0.0-canary.52",
26
+ "@graphcommerce/typescript-config-pwa": "6.0.0-canary.52",
27
27
  "@types/gtag.js": "^0.0.12"
28
28
  },
29
29
  "peerDependencies": {
@@ -1,6 +1,9 @@
1
1
  import { CartStartCheckoutLinkOrButtonProps } from '@graphcommerce/magento-cart'
2
2
  import { IfConfig, PluginProps } from '@graphcommerce/next-config'
3
+ import { useMemoObject } from '@graphcommerce/next-ui'
4
+ import { useEffect } from 'react'
3
5
  import { gtagBeginCheckout } from '../events/gtagBeginCheckout/gtagBeginCheckout'
6
+ import { gtagViewCart } from '../events/gtagViewCart/gtagViewCart'
4
7
 
5
8
  export const component = 'CartStartCheckoutLinkOrButton'
6
9
  export const exported = '@graphcommerce/magento-cart'
@@ -10,6 +13,11 @@ export function GaCartStartCheckoutLinkOrButton(
10
13
  props: PluginProps<CartStartCheckoutLinkOrButtonProps>,
11
14
  ) {
12
15
  const { Prev, onStart, ...rest } = props
16
+
17
+ const cartObject = useMemoObject({ items: rest.items, prices: rest.prices })
18
+
19
+ useEffect(() => gtagViewCart(cartObject), [cartObject])
20
+
13
21
  return (
14
22
  <Prev
15
23
  {...rest}
@@ -0,0 +1,35 @@
1
+ import { RemoveItemFromCartProps } from '@graphcommerce/magento-cart-items'
2
+ import { IfConfig, PluginProps } from '@graphcommerce/next-config'
3
+ import { gtagRemoveFromCart } from '../events/gtagRemoveFromCart/gtagRemoveFromCart'
4
+
5
+ export const component = 'RemoveItemFromCartFab'
6
+ export const exported = '@graphcommerce/magento-cart-items'
7
+ export const ifConfig: IfConfig = 'googleAnalyticsId'
8
+
9
+ export function GaRemoveItemFromCart(props: PluginProps<RemoveItemFromCartProps>) {
10
+ const { Prev, uid, quantity, prices, product, onClick } = props
11
+
12
+ return (
13
+ <Prev
14
+ {...props}
15
+ product={product}
16
+ onClick={(e) => {
17
+ gtagRemoveFromCart({
18
+ __typename: 'Cart',
19
+ items: [
20
+ {
21
+ uid,
22
+ __typename: 'SimpleCartItem',
23
+ product,
24
+ quantity,
25
+ prices,
26
+ },
27
+ ],
28
+ })
29
+ onClick?.(e)
30
+ }}
31
+ />
32
+ )
33
+ }
34
+
35
+ export const Plugin = GaRemoveItemFromCart
@@ -0,0 +1,25 @@
1
+ import { ProductPageMetaFragment } from '@graphcommerce/magento-product/components/ProductPageMeta/ProductPageMeta.gql'
2
+ import { PluginProps } from '@graphcommerce/next-config'
3
+ import { useMemoObject } from '@graphcommerce/next-ui'
4
+ import { useEffect } from 'react'
5
+ import { productToGtagItem } from '../events/productToGtagItem/productToGtagItem'
6
+
7
+ export const component = 'ProductPageMeta'
8
+ export const exported = '@graphcommerce/magento-product'
9
+
10
+ /** When a product is added to the Cart, send a Google Analytics event */
11
+ function GaViewItem(props: PluginProps<ProductPageMetaFragment>) {
12
+ const { Prev, price_range } = props
13
+
14
+ const viewItem = useMemoObject({
15
+ currency: price_range.minimum_price.final_price.currency,
16
+ value: price_range.minimum_price.final_price.value,
17
+ items: [productToGtagItem(props)],
18
+ })
19
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
20
+ useEffect(() => globalThis.gtag?.('event', 'view_item', viewItem), [viewItem])
21
+
22
+ return <Prev {...props} />
23
+ }
24
+
25
+ export const Plugin = GaViewItem