@graphcommerce/googleanalytics 5.1.0-canary.4 → 5.1.0-canary.6

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,15 @@
1
1
  # Change Log
2
2
 
3
+ ## 5.1.0-canary.6
4
+
5
+ ### Minor Changes
6
+
7
+ - [#1754](https://github.com/graphcommerce-org/graphcommerce/pull/1754) [`f9cc9d45e`](https://github.com/graphcommerce-org/graphcommerce/commit/f9cc9d45ec500a719fd0b5f4c5673d23838ee77e) - Google analytics now supports configuration for multiple locales ([@FrankHarland](https://github.com/FrankHarland))
8
+
9
+ - [#1754](https://github.com/graphcommerce-org/graphcommerce/pull/1754) [`f9cc9d45e`](https://github.com/graphcommerce-org/graphcommerce/commit/f9cc9d45ec500a719fd0b5f4c5673d23838ee77e) - New events added to Google analytics: purchase and add_to_cart (when adding and updating items) ([@FrankHarland](https://github.com/FrankHarland))
10
+
11
+ ## 5.1.0-canary.5
12
+
3
13
  ## 5.1.0-canary.4
4
14
 
5
15
  ## 5.1.0-canary.3
package/README.md CHANGED
@@ -1,11 +1,31 @@
1
1
  # @graphcommerce/googleanalytics
2
2
 
3
- This package makes it easy to add Google Analytics to your GraphCommerce
3
+ This package makes it easy to add Google Analytics GA4 to your GraphCommerce
4
4
  webshop.
5
5
 
6
- ### Usage
6
+ Besides the GA4 integration it also tracks the following events:
7
7
 
8
- 1. Fill `NEXT_PUBLIC_GOOGLE_ANALYTICS` in your .env file
9
- [example](../../examples/magento-graphcms/.env.example)
10
- 2. Add `<GoogleAnalyticsScript/>` to your `pages/_app.tsx` file.
11
- [example](../../examples/magento-graphcms/pages/_app.tsx)
8
+ - add_payment_info
9
+ - purchase
10
+ - add_shipping_info
11
+ - add_to_cart (also triggered when updating quantity)
12
+ - begin_checkout
13
+ - select_item
14
+ - view_item_list
15
+
16
+ ### Configuration
17
+
18
+ Fill `NEXT_PUBLIC_GOOGLE_ANALYTICS` in your .env file. The value of
19
+ `NEXT_PUBLIC_GOOGLE_ANALYTICS` can be string or JSON stringified object:
20
+
21
+ ```
22
+ # your .env file
23
+
24
+ # Google Analytics v4 ID
25
+ NEXT_PUBLIC_GOOGLE_ANALYTICS="G-XXXXXXXX"
26
+
27
+ # or
28
+
29
+ # Google Analytics v4 ID per locale
30
+ NEXT_PUBLIC_GOOGLE_ANALYTICS='{"en-us": "G-XXXXXXXX", "nl-nl": "G-XXXXXXXX"}'
31
+ ```
@@ -1,9 +1,19 @@
1
+ import { useRouter } from 'next/router'
1
2
  import Script from 'next/script'
2
3
 
3
4
  export function GoogleAnalyticsScript() {
4
- const id = process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS
5
+ const gaEnv = process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS
6
+ const { locale } = useRouter()
7
+ let id = ''
5
8
 
6
- if (!id) return null
9
+ if (!gaEnv) return null
10
+
11
+ if (gaEnv.startsWith('{') && locale) {
12
+ const GAConfig = JSON.parse(gaEnv)
13
+ id = GAConfig[locale]
14
+ } else {
15
+ id = gaEnv
16
+ }
7
17
 
8
18
  return (
9
19
  <>
@@ -0,0 +1,29 @@
1
+ import { PaymentMethodContextFragment } from '@graphcommerce/magento-cart-payment-method/Api/PaymentMethodContext.gql'
2
+
3
+ export function gtagAddPurchaseInfo(
4
+ orderNumber: string,
5
+ cart: PaymentMethodContextFragment | null | undefined,
6
+ ) {
7
+ if (process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS) {
8
+ globalThis.gtag?.('event', 'purchase', {
9
+ transaction_id: orderNumber,
10
+ currency: cart?.prices?.grand_total?.currency,
11
+ value: cart?.prices?.grand_total?.value,
12
+ coupon: cart?.applied_coupons?.map((coupon) => coupon?.code),
13
+ payment_type: cart?.selected_payment_method?.code,
14
+ tax: cart?.prices?.applied_taxes?.reduce((sum, tax) => sum + (tax?.amount?.value ?? 0), 0),
15
+ items: cart?.items?.map((item) => ({
16
+ item_id: item?.product.sku,
17
+ item_name: item?.product.name,
18
+ currency: item?.prices?.price.currency,
19
+ discount: item?.prices?.discounts?.reduce(
20
+ // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
21
+ (sum, discount) => sum + (discount?.amount?.value ?? 0),
22
+ 0,
23
+ ),
24
+ price: item?.prices?.price.value,
25
+ quantity: item?.quantity,
26
+ })),
27
+ })
28
+ }
29
+ }
@@ -1,6 +1,8 @@
1
1
  import { GtagAddShippingInfoFragment } from './GtagAddShippingInfo.gql'
2
2
 
3
3
  export function gtagAddShippingInfo<C extends GtagAddShippingInfoFragment>(cart?: C | null) {
4
+ if (!cart) return
5
+
4
6
  globalThis.gtag?.('event', 'add_shipping_info', {
5
7
  currency: cart?.prices?.grand_total?.currency,
6
8
  value: cart?.prices?.grand_total?.value,
@@ -1,6 +1,16 @@
1
1
  fragment GtagAddToCart on Cart @inject(into: ["CartItemCountChanged"]) {
2
2
  items {
3
3
  prices {
4
+ discounts {
5
+ amount {
6
+ currency
7
+ value
8
+ }
9
+ }
10
+ row_total_including_tax {
11
+ currency
12
+ value
13
+ }
4
14
  price {
5
15
  currency
6
16
  value
@@ -1,25 +1,40 @@
1
- import { FetchResult } from '@graphcommerce/graphql'
1
+ import type { FetchResult } from '@graphcommerce/graphql'
2
2
  import {
3
3
  AddProductsToCartMutation,
4
4
  AddProductsToCartMutationVariables,
5
5
  } from '@graphcommerce/magento-product'
6
- import { GtagAddToCartFragment } from './GtagAddToCart.gql'
7
6
 
8
- // @todo add types
9
- // @todo some thing still needs to be done for configurables and bundles as you can have multiple items of the same SKU in your cart, but with different configurations/prices
10
- // F.E. 'sock-red' has 2 variants, 'sock-red:small' (€ 5) and 'sock-red:large' (€ 7,50). At this time we dont know the value of the item added if multiple variants are added
11
- export const gtagAddToCart = async (
7
+ export const gtagAddToCart = (
12
8
  result: FetchResult<AddProductsToCartMutation>,
13
9
  variables: AddProductsToCartMutationVariables,
14
10
  ) => {
15
11
  if (process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS) {
16
12
  const addedItem = result.data?.addProductsToCart?.cart.items?.slice(-1)[0]
17
13
 
18
- // console.log(result.data?.addProductsToCart, variables)
19
- // console.log({
20
- // currency,
21
- // value,
22
- // items,
23
- // })
14
+ if (addedItem && addedItem.prices && addedItem.prices.row_total_including_tax.value) {
15
+ // we need to manually calculate pricePerItemInclTax (https://github.com/magento/magento2/issues/33848)
16
+ const pricePerItemInclTax =
17
+ addedItem.prices.row_total_including_tax.value / addedItem.quantity
18
+ const addToCartValue = pricePerItemInclTax * variables.cartItems[0].quantity
19
+
20
+ globalThis.gtag?.('event', 'add_to_cart', {
21
+ currency: addedItem?.prices?.price.currency,
22
+ value: addToCartValue,
23
+ items: [
24
+ {
25
+ item_id: addedItem?.product.sku,
26
+ item_name: addedItem?.product.name,
27
+ currency: addedItem?.prices?.price.currency,
28
+ price: pricePerItemInclTax,
29
+ quantity: variables.cartItems[0].quantity,
30
+ discount: addedItem?.prices?.discounts?.reduce(
31
+ // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
32
+ (sum, discount) => sum + (discount?.amount?.value ?? 0),
33
+ 0,
34
+ ),
35
+ },
36
+ ],
37
+ })
38
+ }
24
39
  }
25
40
  }
package/index.ts CHANGED
@@ -2,6 +2,7 @@ export * from './components'
2
2
  export * from './events/useGtagViewItemList/useGtagViewItemList'
3
3
  export * from './events/gtagBeginCheckout/gtagBeginCheckout'
4
4
  export * from './events/gtagAddPaymentInfo/gtagAddPaymentInfo'
5
+ export * from './events/gtagAddPurchaseInfo/gtagAddPurchaseInfo'
5
6
  export * from './events/gtagAddShippingInfo/gtagAddShippingInfo'
6
7
  export * from './events/gtagSelectItem/gtagSelectItem'
7
8
  export * from './events/useGtagPurchase/useGtagPurchase'
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": "5.1.0-canary.4",
5
+ "version": "5.1.0-canary.6",
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": "5.1.0-canary.4",
16
- "@graphcommerce/magento-cart": "5.1.0-canary.4",
17
- "@graphcommerce/magento-cart-payment-method": "5.1.0-canary.4",
18
- "@graphcommerce/magento-cart-shipping-method": "5.1.0-canary.4",
19
- "@graphcommerce/magento-product": "5.1.0-canary.4",
20
- "@graphcommerce/next-config": "5.1.0-canary.4",
21
- "@graphcommerce/next-ui": "5.1.0-canary.4"
15
+ "@graphcommerce/graphql-mesh": "5.1.0-canary.6",
16
+ "@graphcommerce/magento-cart": "5.1.0-canary.6",
17
+ "@graphcommerce/magento-cart-payment-method": "5.1.0-canary.6",
18
+ "@graphcommerce/magento-cart-shipping-method": "5.1.0-canary.6",
19
+ "@graphcommerce/magento-product": "5.1.0-canary.6",
20
+ "@graphcommerce/next-config": "5.1.0-canary.6",
21
+ "@graphcommerce/next-ui": "5.1.0-canary.6"
22
22
  },
23
23
  "devDependencies": {
24
- "@graphcommerce/eslint-config-pwa": "5.1.0-canary.4",
25
- "@graphcommerce/prettier-config-pwa": "5.1.0-canary.4",
26
- "@graphcommerce/typescript-config-pwa": "5.1.0-canary.4",
24
+ "@graphcommerce/eslint-config-pwa": "5.1.0-canary.6",
25
+ "@graphcommerce/prettier-config-pwa": "5.1.0-canary.6",
26
+ "@graphcommerce/typescript-config-pwa": "5.1.0-canary.6",
27
27
  "@types/gtag.js": "^0.0.12"
28
28
  },
29
29
  "peerDependencies": {
@@ -12,8 +12,9 @@ function GaAddProductsToCartForm(props: PluginProps<AddProductsToCartFormProps>)
12
12
  return (
13
13
  <Prev
14
14
  {...rest}
15
- onComplete={async (data, variables) => {
16
- await Promise.all([gtagAddToCart(data, variables), onComplete?.(data, variables)])
15
+ onComplete={(data, variables) => {
16
+ gtagAddToCart(data, variables)
17
+ return onComplete?.(data, variables)
17
18
  }}
18
19
  />
19
20
  )
@@ -12,7 +12,7 @@ export function GaCartStartCheckout(props: PluginProps<CartStartCheckoutProps>)
12
12
  {...rest}
13
13
  onStart={(e, cart) => {
14
14
  gtagBeginCheckout(cart)
15
- onStart?.(e, cart)
15
+ return onStart?.(e, cart)
16
16
  }}
17
17
  />
18
18
  )
@@ -14,7 +14,7 @@ export function GaCartStartCheckoutLinkOrButton(
14
14
  {...rest}
15
15
  onStart={(e, cart) => {
16
16
  gtagBeginCheckout(cart)
17
- onStart?.(e, cart)
17
+ return onStart?.(e, cart)
18
18
  }}
19
19
  />
20
20
  )
@@ -7,6 +7,7 @@ import { gtagAddPaymentInfo } from '../events/gtagAddPaymentInfo/gtagAddPaymentI
7
7
  export const component = 'PaymentMethodButton'
8
8
  export const exported = '@graphcommerce/magento-cart-payment-method'
9
9
 
10
+ // @todo This plugin can probably be migrated to the actual form that is submitted.
10
11
  function GaPaymentMethodButton(props: PluginProps<PaymentMethodButtonProps>) {
11
12
  const { Prev, onSubmitSuccessful, ...rest } = props
12
13
  const methodContext = useCartQuery(GetPaymentMethodContextDocument)
@@ -16,7 +17,7 @@ function GaPaymentMethodButton(props: PluginProps<PaymentMethodButtonProps>) {
16
17
  {...rest}
17
18
  onSubmitSuccessful={() => {
18
19
  gtagAddPaymentInfo(methodContext.data?.cart)
19
- onSubmitSuccessful?.()
20
+ return onSubmitSuccessful?.()
20
21
  }}
21
22
  />
22
23
  )
@@ -1,5 +1,6 @@
1
1
  import type { PaymentMethodContextProviderProps } from '@graphcommerce/magento-cart-payment-method'
2
2
  import type { PluginProps } from '@graphcommerce/next-config'
3
+ import { gtagAddPurchaseInfo } from '../events/gtagAddPurchaseInfo/gtagAddPurchaseInfo'
3
4
 
4
5
  export const component = 'PaymentMethodContextProvider'
5
6
  export const exported = '@graphcommerce/magento-cart-payment-method'
@@ -9,9 +10,9 @@ function GaPaymentMethodContextProvider(props: PluginProps<PaymentMethodContextP
9
10
  return (
10
11
  <Prev
11
12
  {...rest}
12
- onSuccess={async (orderNumber, cart) => {
13
- // Todo - add GA event here
14
- await onSuccess?.(orderNumber, cart)
13
+ onSuccess={(orderNumber, cart) => {
14
+ gtagAddPurchaseInfo(orderNumber, cart)
15
+ return onSuccess?.(orderNumber, cart)
15
16
  }}
16
17
  />
17
18
  )
@@ -16,7 +16,7 @@ export function GaProductListItemsBase(props: PluginProps<ProductItemsGridProps>
16
16
  {...rest}
17
17
  onClick={(e, item) => {
18
18
  gtagSelectItem({ item })
19
- onClick?.(e, item)
19
+ return onClick?.(e, item)
20
20
  }}
21
21
  />
22
22
  )
@@ -11,10 +11,9 @@ export function GaShippingMethodForm(props: PluginProps<ShippingMethodFormProps>
11
11
  return (
12
12
  <Prev
13
13
  {...rest}
14
- onComplete={(result) => {
15
- const cart = result.data?.setShippingMethodsOnCart?.cart
16
- if (!cart) return
17
- gtagAddShippingInfo(cart)
14
+ onComplete={(result, variables) => {
15
+ gtagAddShippingInfo(result.data?.setShippingMethodsOnCart?.cart)
16
+ return onComplete?.(result, variables)
18
17
  }}
19
18
  />
20
19
  )
@@ -0,0 +1,61 @@
1
+ import { UpdateItemQuantityProps } from '@graphcommerce/magento-cart-items'
2
+ import { PluginProps } from '@graphcommerce/next-config'
3
+
4
+ export const component = 'UpdateItemQuantity'
5
+ export const exported = '@graphcommerce/magento-cart-items/UpdateItemQuantity/UpdateItemQuantity'
6
+ export const ifEnv = 'NEXT_PUBLIC_GOOGLE_ANALYTICS' // @frank: chekcen of dit werr
7
+
8
+ /**
9
+ * When a product is added to the Cart, by using the + button on cart page, send a Google Analytics
10
+ * event
11
+ */
12
+ function GaUpdateItemQuantity(props: PluginProps<UpdateItemQuantityProps>) {
13
+ const { Prev, onComplete, quantity, ...rest } = props
14
+
15
+ return (
16
+ <Prev
17
+ {...rest}
18
+ quantity={quantity}
19
+ onComplete={(data, variables) => {
20
+ const original = onComplete?.(data, variables)
21
+ const diffQuantity = variables.quantity - quantity
22
+ if (diffQuantity === 0) return original
23
+
24
+ const itemId = variables.uid
25
+ const addedItem = data.data?.updateCartItems?.cart.items?.find(
26
+ (item) => item?.uid === itemId,
27
+ )
28
+
29
+ if (addedItem && addedItem.prices && addedItem.prices.row_total_including_tax.value) {
30
+ // we need to manually calculate pricePerItemInclTax (https://github.com/magento/magento2/issues/33848)
31
+ const pricePerItemInclTax =
32
+ addedItem.prices.row_total_including_tax.value / addedItem.quantity
33
+ const addToCartValue = pricePerItemInclTax * diffQuantity
34
+
35
+ globalThis.gtag?.('event', 'add_to_cart', {
36
+ currency: addedItem?.prices?.price.currency,
37
+ value: addToCartValue,
38
+ items: [
39
+ {
40
+ item_id: addedItem?.product.sku,
41
+ item_name: addedItem?.product.name,
42
+ currency: addedItem?.prices?.price.currency,
43
+ price: pricePerItemInclTax,
44
+ quantity: variables.quantity,
45
+ discount: addedItem?.prices?.discounts?.reduce(
46
+ // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
47
+ (sum, discount) => sum + (discount?.amount?.value ?? 0),
48
+ 0,
49
+ ),
50
+ },
51
+ ],
52
+ })
53
+ }
54
+
55
+ return original
56
+ }}
57
+ />
58
+ )
59
+ }
60
+
61
+ export const Plugin = GaUpdateItemQuantity
@@ -1,28 +0,0 @@
1
- export const useGtagPurchase = () => {
2
- // const bla = useCartQuery(CartItemSummaryDocument)
3
-
4
- if (process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS) {
5
- // console.log(cart, 'trigger gtagPurchase')
6
- // globalThis.gtag?.('event', 'purchase', {
7
- // currency: cart?.prices?.grand_total?.currency,
8
- // // transaction_id:,
9
- // // shipping:,
10
- // // tax:,
11
- // value: cart?.prices?.grand_total?.value,
12
- // coupon: cart?.applied_coupons?.map((coupon) => coupon?.code),
13
- // payment_type: cart?.selected_payment_method?.code,
14
- // items: cart?.items?.map((item) => ({
15
- // item_id: item?.product.sku,
16
- // item_name: item?.product.name,
17
- // currency: item?.prices?.price.currency,
18
- // discount: item?.prices?.discounts?.reduce(
19
- // // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
20
- // (sum, discount) => sum + (discount?.amount?.value ?? 0),
21
- // 0,
22
- // ),
23
- // price: item?.prices?.price.value,
24
- // quantity: item?.quantity,
25
- // })),
26
- // })
27
- }
28
- }