@segment/analytics-browser-actions-google-analytics-4 1.0.0

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.
Files changed (64) hide show
  1. package/package.json +20 -0
  2. package/src/__tests__/addPaymentInfo.test.ts +101 -0
  3. package/src/__tests__/addToCart.test.ts +95 -0
  4. package/src/__tests__/addToWishlist.test.ts +95 -0
  5. package/src/__tests__/beginCheckout.test.ts +101 -0
  6. package/src/__tests__/customEvent.test.ts +70 -0
  7. package/src/__tests__/generateLead.test.ts +68 -0
  8. package/src/__tests__/login.test.ts +63 -0
  9. package/src/__tests__/purchase.test.ts +103 -0
  10. package/src/__tests__/refund.test.ts +103 -0
  11. package/src/__tests__/removeFromCart.test.ts +99 -0
  12. package/src/__tests__/search.test.ts +64 -0
  13. package/src/__tests__/selectItem.test.ts +96 -0
  14. package/src/__tests__/selectPromotion.test.ts +111 -0
  15. package/src/__tests__/signUp.test.ts +62 -0
  16. package/src/__tests__/viewCart.test.ts +96 -0
  17. package/src/__tests__/viewItem.test.ts +96 -0
  18. package/src/__tests__/viewItemList.test.ts +96 -0
  19. package/src/__tests__/viewPromotion.test.ts +111 -0
  20. package/src/addPaymentInfo/generated-types.ts +117 -0
  21. package/src/addPaymentInfo/index.ts +48 -0
  22. package/src/addToCart/generated-types.ts +109 -0
  23. package/src/addToCart/index.ts +36 -0
  24. package/src/addToWishlist/generated-types.ts +109 -0
  25. package/src/addToWishlist/index.ts +38 -0
  26. package/src/beginCheckout/generated-types.ts +113 -0
  27. package/src/beginCheckout/index.ts +38 -0
  28. package/src/customEvent/generated-types.ts +28 -0
  29. package/src/customEvent/index.ts +52 -0
  30. package/src/ga4-functions.ts +8 -0
  31. package/src/ga4-properties.ts +368 -0
  32. package/src/ga4-types.ts +28 -0
  33. package/src/generateLead/generated-types.ts +28 -0
  34. package/src/generateLead/index.ts +32 -0
  35. package/src/generated-types.ts +56 -0
  36. package/src/index.ts +194 -0
  37. package/src/login/generated-types.ts +24 -0
  38. package/src/login/index.ts +31 -0
  39. package/src/purchase/generated-types.ts +125 -0
  40. package/src/purchase/index.ts +54 -0
  41. package/src/refund/generated-types.ts +129 -0
  42. package/src/refund/index.ts +57 -0
  43. package/src/removeFromCart/generated-types.ts +109 -0
  44. package/src/removeFromCart/index.ts +37 -0
  45. package/src/search/generated-types.ts +24 -0
  46. package/src/search/index.ts +30 -0
  47. package/src/selectItem/generated-types.ts +109 -0
  48. package/src/selectItem/index.ts +43 -0
  49. package/src/selectPromotion/generated-types.ts +137 -0
  50. package/src/selectPromotion/index.ts +67 -0
  51. package/src/setConfigurationFields/generated-types.ts +70 -0
  52. package/src/setConfigurationFields/index.ts +143 -0
  53. package/src/signUp/generated-types.ts +24 -0
  54. package/src/signUp/index.ts +29 -0
  55. package/src/types.ts +3 -0
  56. package/src/viewCart/generated-types.ts +109 -0
  57. package/src/viewCart/index.ts +36 -0
  58. package/src/viewItem/generated-types.ts +109 -0
  59. package/src/viewItem/index.ts +37 -0
  60. package/src/viewItemList/generated-types.ts +109 -0
  61. package/src/viewItemList/index.ts +36 -0
  62. package/src/viewPromotion/generated-types.ts +137 -0
  63. package/src/viewPromotion/index.ts +67 -0
  64. package/tsconfig.json +9 -0
@@ -0,0 +1,96 @@
1
+ import { Subscription } from '@segment/browser-destination-runtime/types'
2
+ import { Analytics, Context } from '@segment/analytics-next'
3
+ import googleAnalytics4Web, { destination } from '../index'
4
+ import { GA } from '../types'
5
+
6
+ const subscriptions: Subscription[] = [
7
+ {
8
+ partnerAction: 'viewCart',
9
+ name: 'View Cart',
10
+ enabled: true,
11
+ subscribe: 'type = "track"',
12
+ mapping: {
13
+ currency: {
14
+ '@path': '$.properties.currency'
15
+ },
16
+ value: {
17
+ '@path': '$.properties.value'
18
+ },
19
+ items: [
20
+ {
21
+ item_name: {
22
+ '@path': `$.properties.products.0.name`
23
+ },
24
+ item_id: {
25
+ '@path': `$.properties.products.0.product_id`
26
+ },
27
+ currency: {
28
+ '@path': `$.properties.products.0.currency`
29
+ },
30
+ price: {
31
+ '@path': `$.properties.products.0.price`
32
+ },
33
+ quantity: {
34
+ '@path': `$.properties.products.0.quantity`
35
+ }
36
+ }
37
+ ]
38
+ }
39
+ }
40
+ ]
41
+
42
+ describe('GoogleAnalytics4Web.viewCart', () => {
43
+ const settings = {
44
+ measurementID: 'test123'
45
+ }
46
+
47
+ let mockGA4: GA
48
+ let viewCartEvent: any
49
+ beforeEach(async () => {
50
+ jest.restoreAllMocks()
51
+
52
+ const [trackEventPlugin] = await googleAnalytics4Web({
53
+ ...settings,
54
+ subscriptions
55
+ })
56
+ viewCartEvent = trackEventPlugin
57
+
58
+ jest.spyOn(destination, 'initialize').mockImplementation(() => {
59
+ mockGA4 = {
60
+ gtag: jest.fn()
61
+ }
62
+ return Promise.resolve(mockGA4.gtag)
63
+ })
64
+ await trackEventPlugin.load(Context.system(), {} as Analytics)
65
+ })
66
+
67
+ test('GA4 viewCart Event', async () => {
68
+ const context = new Context({
69
+ event: 'View Cart',
70
+ type: 'track',
71
+ properties: {
72
+ currency: 'USD',
73
+ value: 10,
74
+ products: [
75
+ {
76
+ product_id: '12345',
77
+ name: 'Monopoly: 3rd Edition',
78
+ currency: 'USD'
79
+ }
80
+ ]
81
+ }
82
+ })
83
+
84
+ await viewCartEvent.track?.(context)
85
+
86
+ expect(mockGA4.gtag).toHaveBeenCalledWith(
87
+ expect.anything(),
88
+ expect.stringContaining('view_cart'),
89
+ expect.objectContaining({
90
+ currency: 'USD',
91
+ items: [{ currency: 'USD', item_id: '12345', item_name: 'Monopoly: 3rd Edition' }],
92
+ value: 10
93
+ })
94
+ )
95
+ })
96
+ })
@@ -0,0 +1,96 @@
1
+ import { Subscription } from '@segment/browser-destination-runtime/types'
2
+ import { Analytics, Context } from '@segment/analytics-next'
3
+ import googleAnalytics4Web, { destination } from '../index'
4
+ import { GA } from '../types'
5
+
6
+ const subscriptions: Subscription[] = [
7
+ {
8
+ partnerAction: 'viewItem',
9
+ name: 'View Item',
10
+ enabled: true,
11
+ subscribe: 'type = "track"',
12
+ mapping: {
13
+ currency: {
14
+ '@path': '$.properties.currency'
15
+ },
16
+ value: {
17
+ '@path': '$.properties.value'
18
+ },
19
+ items: [
20
+ {
21
+ item_name: {
22
+ '@path': `$.properties.products.0.name`
23
+ },
24
+ item_id: {
25
+ '@path': `$.properties.products.0.product_id`
26
+ },
27
+ currency: {
28
+ '@path': `$.properties.products.0.currency`
29
+ },
30
+ price: {
31
+ '@path': `$.properties.products.0.price`
32
+ },
33
+ quantity: {
34
+ '@path': `$.properties.products.0.quantity`
35
+ }
36
+ }
37
+ ]
38
+ }
39
+ }
40
+ ]
41
+
42
+ describe('GoogleAnalytics4Web.viewItem', () => {
43
+ const settings = {
44
+ measurementID: 'test123'
45
+ }
46
+
47
+ let mockGA4: GA
48
+ let viewItemEvent: any
49
+ beforeEach(async () => {
50
+ jest.restoreAllMocks()
51
+
52
+ const [trackEventPlugin] = await googleAnalytics4Web({
53
+ ...settings,
54
+ subscriptions
55
+ })
56
+ viewItemEvent = trackEventPlugin
57
+
58
+ jest.spyOn(destination, 'initialize').mockImplementation(() => {
59
+ mockGA4 = {
60
+ gtag: jest.fn()
61
+ }
62
+ return Promise.resolve(mockGA4.gtag)
63
+ })
64
+ await trackEventPlugin.load(Context.system(), {} as Analytics)
65
+ })
66
+
67
+ test('GA4 viewItem Event', async () => {
68
+ const context = new Context({
69
+ event: 'View Item',
70
+ type: 'track',
71
+ properties: {
72
+ currency: 'USD',
73
+ value: 10,
74
+ products: [
75
+ {
76
+ product_id: '12345',
77
+ name: 'Monopoly: 3rd Edition',
78
+ currency: 'USD'
79
+ }
80
+ ]
81
+ }
82
+ })
83
+
84
+ await viewItemEvent.track?.(context)
85
+
86
+ expect(mockGA4.gtag).toHaveBeenCalledWith(
87
+ expect.anything(),
88
+ expect.stringContaining('view_item'),
89
+ expect.objectContaining({
90
+ currency: 'USD',
91
+ items: [{ currency: 'USD', item_id: '12345', item_name: 'Monopoly: 3rd Edition' }],
92
+ value: 10
93
+ })
94
+ )
95
+ })
96
+ })
@@ -0,0 +1,96 @@
1
+ import { Subscription } from '@segment/browser-destination-runtime/types'
2
+ import { Analytics, Context } from '@segment/analytics-next'
3
+ import googleAnalytics4Web, { destination } from '../index'
4
+ import { GA } from '../types'
5
+
6
+ const subscriptions: Subscription[] = [
7
+ {
8
+ partnerAction: 'viewItemList',
9
+ name: 'View Item List',
10
+ enabled: true,
11
+ subscribe: 'type = "track"',
12
+ mapping: {
13
+ item_list_id: {
14
+ '@path': '$.properties.item_list_id'
15
+ },
16
+ item_list_name: {
17
+ '@path': '$.properties.item_list_name'
18
+ },
19
+ items: [
20
+ {
21
+ item_name: {
22
+ '@path': `$.properties.products.0.name`
23
+ },
24
+ item_id: {
25
+ '@path': `$.properties.products.0.product_id`
26
+ },
27
+ currency: {
28
+ '@path': `$.properties.products.0.currency`
29
+ },
30
+ price: {
31
+ '@path': `$.properties.products.0.price`
32
+ },
33
+ quantity: {
34
+ '@path': `$.properties.products.0.quantity`
35
+ }
36
+ }
37
+ ]
38
+ }
39
+ }
40
+ ]
41
+
42
+ describe('GoogleAnalytics4Web.viewItemList', () => {
43
+ const settings = {
44
+ measurementID: 'test123'
45
+ }
46
+
47
+ let mockGA4: GA
48
+ let viewItemListEvent: any
49
+ beforeEach(async () => {
50
+ jest.restoreAllMocks()
51
+
52
+ const [trackEventPlugin] = await googleAnalytics4Web({
53
+ ...settings,
54
+ subscriptions
55
+ })
56
+ viewItemListEvent = trackEventPlugin
57
+
58
+ jest.spyOn(destination, 'initialize').mockImplementation(() => {
59
+ mockGA4 = {
60
+ gtag: jest.fn()
61
+ }
62
+ return Promise.resolve(mockGA4.gtag)
63
+ })
64
+ await trackEventPlugin.load(Context.system(), {} as Analytics)
65
+ })
66
+
67
+ test('GA4 viewItemList Event', async () => {
68
+ const context = new Context({
69
+ event: 'View Item List',
70
+ type: 'track',
71
+ properties: {
72
+ item_list_id: 12321,
73
+ item_list_name: 'Monopoly: 3rd Edition',
74
+ products: [
75
+ {
76
+ product_id: '12345',
77
+ name: 'Monopoly: 3rd Edition',
78
+ currency: 'USD'
79
+ }
80
+ ]
81
+ }
82
+ })
83
+
84
+ await viewItemListEvent.track?.(context)
85
+
86
+ expect(mockGA4.gtag).toHaveBeenCalledWith(
87
+ expect.anything(),
88
+ expect.stringContaining('view_item_list'),
89
+ expect.objectContaining({
90
+ item_list_id: 12321,
91
+ item_list_name: 'Monopoly: 3rd Edition',
92
+ items: [{ currency: 'USD', item_id: '12345', item_name: 'Monopoly: 3rd Edition' }]
93
+ })
94
+ )
95
+ })
96
+ })
@@ -0,0 +1,111 @@
1
+ import { Subscription } from '@segment/browser-destination-runtime/types'
2
+ import { Analytics, Context } from '@segment/analytics-next'
3
+ import googleAnalytics4Web, { destination } from '../index'
4
+ import { GA } from '../types'
5
+
6
+ const subscriptions: Subscription[] = [
7
+ {
8
+ partnerAction: 'viewPromotion',
9
+ name: 'Select Promotion',
10
+ enabled: true,
11
+ subscribe: 'type = "track"',
12
+ mapping: {
13
+ creative_name: {
14
+ '@path': '$.properties.creative_name'
15
+ },
16
+ creative_slot: {
17
+ '@path': '$.properties.creative_slot'
18
+ },
19
+ location_id: {
20
+ '@path': '$.properties.location_id'
21
+ },
22
+ promotion_id: {
23
+ '@path': '$.properties.promotion_id'
24
+ },
25
+ promotion_name: {
26
+ '@path': '$.properties.promotion_name'
27
+ },
28
+ items: [
29
+ {
30
+ item_name: {
31
+ '@path': `$.properties.products.0.name`
32
+ },
33
+ item_id: {
34
+ '@path': `$.properties.products.0.product_id`
35
+ },
36
+ currency: {
37
+ '@path': `$.properties.products.0.currency`
38
+ },
39
+ price: {
40
+ '@path': `$.properties.products.0.price`
41
+ },
42
+ quantity: {
43
+ '@path': `$.properties.products.0.quantity`
44
+ }
45
+ }
46
+ ]
47
+ }
48
+ }
49
+ ]
50
+
51
+ describe('GoogleAnalytics4Web.viewPromotion', () => {
52
+ const settings = {
53
+ measurementID: 'test123'
54
+ }
55
+
56
+ let mockGA4: GA
57
+ let viewPromotionEvent: any
58
+ beforeEach(async () => {
59
+ jest.restoreAllMocks()
60
+
61
+ const [trackEventPlugin] = await googleAnalytics4Web({
62
+ ...settings,
63
+ subscriptions
64
+ })
65
+ viewPromotionEvent = trackEventPlugin
66
+
67
+ jest.spyOn(destination, 'initialize').mockImplementation(() => {
68
+ mockGA4 = {
69
+ gtag: jest.fn()
70
+ }
71
+ return Promise.resolve(mockGA4.gtag)
72
+ })
73
+ await trackEventPlugin.load(Context.system(), {} as Analytics)
74
+ })
75
+
76
+ test('GA4 viewPromotion Event', async () => {
77
+ const context = new Context({
78
+ event: 'Select Promotion',
79
+ type: 'track',
80
+ properties: {
81
+ creative_name: 'summer_banner2',
82
+ creative_slot: 'featured_app_1',
83
+ location_id: 'ChIJIQBpAG2ahYAR_6128GcTUEo',
84
+ promotion_id: 'P_12345',
85
+ promotion_name: 'Summer Sale',
86
+ products: [
87
+ {
88
+ product_id: '12345',
89
+ name: 'Monopoly: 3rd Edition',
90
+ currency: 'USD'
91
+ }
92
+ ]
93
+ }
94
+ })
95
+
96
+ await viewPromotionEvent.track?.(context)
97
+
98
+ expect(mockGA4.gtag).toHaveBeenCalledWith(
99
+ expect.anything(),
100
+ expect.stringContaining('view_promotion'),
101
+ expect.objectContaining({
102
+ creative_name: 'summer_banner2',
103
+ creative_slot: 'featured_app_1',
104
+ location_id: 'ChIJIQBpAG2ahYAR_6128GcTUEo',
105
+ promotion_id: 'P_12345',
106
+ promotion_name: 'Summer Sale',
107
+ items: [{ currency: 'USD', item_id: '12345', item_name: 'Monopoly: 3rd Edition' }]
108
+ })
109
+ )
110
+ })
111
+ })
@@ -0,0 +1,117 @@
1
+ // Generated file. DO NOT MODIFY IT BY HAND.
2
+
3
+ export interface Payload {
4
+ /**
5
+ * A unique identifier for a user. See Google's [User-ID for cross-platform analysis](https://support.google.com/analytics/answer/9213390) and [Reporting: deduplicate user counts](https://support.google.com/analytics/answer/9355949?hl=en) documentation for more information on this identifier.
6
+ */
7
+ user_id?: string
8
+ /**
9
+ * Currency of the items associated with the event, in 3-letter ISO 4217 format.
10
+ */
11
+ currency?: string
12
+ /**
13
+ * The monetary value of the event.
14
+ */
15
+ value?: number
16
+ /**
17
+ * Coupon code used for a purchase.
18
+ */
19
+ coupon?: string
20
+ /**
21
+ * The chosen method of payment.
22
+ */
23
+ payment_type?: string
24
+ /**
25
+ * The list of products purchased.
26
+ */
27
+ items: {
28
+ /**
29
+ * Identifier for the product being purchased.
30
+ */
31
+ item_id?: string
32
+ /**
33
+ * Name of the product being purchased.
34
+ */
35
+ item_name?: string
36
+ /**
37
+ * A product affiliation to designate a supplying company or brick and mortar store location.
38
+ */
39
+ affiliation?: string
40
+ /**
41
+ * Coupon code used for a purchase.
42
+ */
43
+ coupon?: string
44
+ /**
45
+ * Currency of the purchase or items associated with the event, in 3-letter ISO 4217 format.
46
+ */
47
+ currency?: string
48
+ /**
49
+ * Monetary value of discount associated with a purchase.
50
+ */
51
+ discount?: number
52
+ /**
53
+ * The index/position of the item in a list.
54
+ */
55
+ index?: number
56
+ /**
57
+ * Brand associated with the product.
58
+ */
59
+ item_brand?: string
60
+ /**
61
+ * Product category.
62
+ */
63
+ item_category?: string
64
+ /**
65
+ * Product category 2.
66
+ */
67
+ item_category2?: string
68
+ /**
69
+ * Product category 3.
70
+ */
71
+ item_category3?: string
72
+ /**
73
+ * Product category 4.
74
+ */
75
+ item_category4?: string
76
+ /**
77
+ * Product category 5.
78
+ */
79
+ item_category5?: string
80
+ /**
81
+ * The ID of the list in which the item was presented to the user.
82
+ */
83
+ item_list_id?: string
84
+ /**
85
+ * The name of the list in which the item was presented to the user.
86
+ */
87
+ item_list_name?: string
88
+ /**
89
+ * Variant of the product (e.g. Black).
90
+ */
91
+ item_variant?: string
92
+ /**
93
+ * The location associated with the item.
94
+ */
95
+ location_id?: string
96
+ /**
97
+ * Price of the product being purchased, in units of the specified currency parameter.
98
+ */
99
+ price?: number
100
+ /**
101
+ * Item quantity.
102
+ */
103
+ quantity?: number
104
+ }[]
105
+ /**
106
+ * The user properties to send to Google Analytics 4. You must create user-scoped dimensions to ensure custom properties are picked up by Google. See Google’s [Custom user properties](https://support.google.com/analytics/answer/9269570) to learn how to set and register user properties.
107
+ */
108
+ user_properties?: {
109
+ [k: string]: unknown
110
+ }
111
+ /**
112
+ * The event parameters to send to Google Analytics 4.
113
+ */
114
+ params?: {
115
+ [k: string]: unknown
116
+ }
117
+ }
@@ -0,0 +1,48 @@
1
+ import type { BrowserActionDefinition } from '@segment/browser-destination-runtime/types'
2
+ import type { Settings } from '../generated-types'
3
+ import type { Payload } from './generated-types'
4
+ import { updateUser } from '../ga4-functions'
5
+ import {
6
+ user_id,
7
+ user_properties,
8
+ currency,
9
+ value,
10
+ coupon,
11
+ payment_type,
12
+ items_multi_products,
13
+ params
14
+ } from '../ga4-properties'
15
+
16
+ // Change from unknown to the partner SDK types
17
+ const action: BrowserActionDefinition<Settings, Function, Payload> = {
18
+ title: 'Add Payment Info',
19
+ description: 'Send event when a user submits their payment information',
20
+ defaultSubscription: 'type = "track" and event = "Payment Info Entered"',
21
+ platform: 'web',
22
+ fields: {
23
+ user_id: { ...user_id },
24
+ currency: { ...currency },
25
+ value: { ...value },
26
+ coupon: { ...coupon },
27
+ payment_type: { ...payment_type },
28
+ items: {
29
+ ...items_multi_products,
30
+ required: true
31
+ },
32
+ user_properties: user_properties,
33
+ params: params
34
+ },
35
+ perform: (gtag, { payload }) => {
36
+ updateUser(payload.user_id, payload.user_properties, gtag)
37
+ gtag('event', 'add_payment_info', {
38
+ currency: payload.currency,
39
+ value: payload.value,
40
+ coupon: payload.coupon,
41
+ payment_type: payload.payment_type,
42
+ items: payload.items,
43
+ ...payload.params
44
+ })
45
+ }
46
+ }
47
+
48
+ export default action
@@ -0,0 +1,109 @@
1
+ // Generated file. DO NOT MODIFY IT BY HAND.
2
+
3
+ export interface Payload {
4
+ /**
5
+ * A unique identifier for a user. See Google's [User-ID for cross-platform analysis](https://support.google.com/analytics/answer/9213390) and [Reporting: deduplicate user counts](https://support.google.com/analytics/answer/9355949?hl=en) documentation for more information on this identifier.
6
+ */
7
+ user_id?: string
8
+ /**
9
+ * Currency of the items associated with the event, in 3-letter ISO 4217 format.
10
+ */
11
+ currency?: string
12
+ /**
13
+ * The list of products purchased.
14
+ */
15
+ items: {
16
+ /**
17
+ * Identifier for the product being purchased.
18
+ */
19
+ item_id?: string
20
+ /**
21
+ * Name of the product being purchased.
22
+ */
23
+ item_name?: string
24
+ /**
25
+ * A product affiliation to designate a supplying company or brick and mortar store location.
26
+ */
27
+ affiliation?: string
28
+ /**
29
+ * Coupon code used for a purchase.
30
+ */
31
+ coupon?: string
32
+ /**
33
+ * Currency of the purchase or items associated with the event, in 3-letter ISO 4217 format.
34
+ */
35
+ currency?: string
36
+ /**
37
+ * Monetary value of discount associated with a purchase.
38
+ */
39
+ discount?: number
40
+ /**
41
+ * The index/position of the item in a list.
42
+ */
43
+ index?: number
44
+ /**
45
+ * Brand associated with the product.
46
+ */
47
+ item_brand?: string
48
+ /**
49
+ * Product category.
50
+ */
51
+ item_category?: string
52
+ /**
53
+ * Product category 2.
54
+ */
55
+ item_category2?: string
56
+ /**
57
+ * Product category 3.
58
+ */
59
+ item_category3?: string
60
+ /**
61
+ * Product category 4.
62
+ */
63
+ item_category4?: string
64
+ /**
65
+ * Product category 5.
66
+ */
67
+ item_category5?: string
68
+ /**
69
+ * The ID of the list in which the item was presented to the user.
70
+ */
71
+ item_list_id?: string
72
+ /**
73
+ * The name of the list in which the item was presented to the user.
74
+ */
75
+ item_list_name?: string
76
+ /**
77
+ * Variant of the product (e.g. Black).
78
+ */
79
+ item_variant?: string
80
+ /**
81
+ * The location associated with the item.
82
+ */
83
+ location_id?: string
84
+ /**
85
+ * Price of the product being purchased, in units of the specified currency parameter.
86
+ */
87
+ price?: number
88
+ /**
89
+ * Item quantity.
90
+ */
91
+ quantity?: number
92
+ }[]
93
+ /**
94
+ * The monetary value of the event.
95
+ */
96
+ value?: number
97
+ /**
98
+ * The user properties to send to Google Analytics 4. You must create user-scoped dimensions to ensure custom properties are picked up by Google. See Google’s [Custom user properties](https://support.google.com/analytics/answer/9269570) to learn how to set and register user properties.
99
+ */
100
+ user_properties?: {
101
+ [k: string]: unknown
102
+ }
103
+ /**
104
+ * The event parameters to send to Google Analytics 4.
105
+ */
106
+ params?: {
107
+ [k: string]: unknown
108
+ }
109
+ }
@@ -0,0 +1,36 @@
1
+ import type { BrowserActionDefinition } from '@segment/browser-destination-runtime/types'
2
+ import type { Settings } from '../generated-types'
3
+ import type { Payload } from './generated-types'
4
+ import { updateUser } from '../ga4-functions'
5
+
6
+ import { user_properties, params, value, currency, items_single_products, user_id } from '../ga4-properties'
7
+
8
+ const action: BrowserActionDefinition<Settings, Function, Payload> = {
9
+ title: 'Add to Cart',
10
+ description: 'This event signifies that an item was added to a cart for purchase.',
11
+ defaultSubscription: 'type = "track" and event = "Product Added"',
12
+ platform: 'web',
13
+ fields: {
14
+ user_id: user_id,
15
+ currency: currency,
16
+ items: {
17
+ ...items_single_products,
18
+ required: true
19
+ },
20
+ value: value,
21
+ user_properties: user_properties,
22
+ params: params
23
+ },
24
+ perform: (gtag, { payload }) => {
25
+ updateUser(payload.user_id, payload.user_properties, gtag)
26
+
27
+ gtag('event', 'add_to_cart', {
28
+ currency: payload.currency,
29
+ value: payload.value,
30
+ items: payload.items,
31
+ ...payload.params
32
+ })
33
+ }
34
+ }
35
+
36
+ export default action