From b6d27a2df0224a6eadebb3a6b1ab4336b0641a84 Mon Sep 17 00:00:00 2001 From: "Filipe W. Lima" <381395+filipewl@users.noreply.github.com> Date: Tue, 2 May 2023 18:16:41 -0300 Subject: [PATCH] Let a product's ID or name to be sent in the promo Analytics events (#76) #### What problem is this solving? In the newest version of Google Analytics, GA4, the [`view_promotion`](https://developers.google.com/analytics/devguides/collection/ga4/reference/events?hl=en&client_type=gtag#view_promotion) event requires that either the product's ID or name is sent. In this PR, we allow this information to be provided via the props `productId` and `productName` that can be set via the Site Editor, just like other existing analytics props. Differently from current Universal Analytics [`promoView`](https://developers.google.com/analytics/devguides/collection/ua/gtm/enhanced-ecommerce?hl=en#promo-impressions) event, we didn't need to send any product information. #### How to test it? You can set these new fields via Site Editor by choosing any image that uses our `vtex.store-image` app, e.g.: 1. Visit https://filipelimaxga4viewpromo--storecomponents.myvtex.com/admin/cms/site-editor 2. Select the **Image List** section. 3. Select one of the images in the list. 4. Ensure the **Analytics event** radio is set to **Yes**. 5. Fill in the **Product ID** and **Product Name** text fields. ![Site Editor](https://user-images.githubusercontent.com/381395/221234860-4135d047-38b8-408b-aa6c-5f10b7bc65ac.png) 6. Click the in **Apply** button. 7. Click in the **Save** button. 8. Visit https://filipelimaxga4viewpromo--storecomponents.myvtex.com/ and open the web console. 9. Ensure the image with the promotion analytics data has been viewed. 10. Check the `dataLayer` window variable to ensure the `promoView` event contains the provided product data. ![dataLayer](https://user-images.githubusercontent.com/381395/221237733-5936731e-e39c-46ad-afad-7bb1cec5ae8f.png) #### Related to / Depends on - https://github.com/vtex-apps/store-image/pull/29 was used to understand how the existing analytics props work. - https://github.com/vtex-apps/google-tag-manager/pull/105 is where we're adding support to the GA4 `view_promotion` event. --------- Co-authored-by: Sheila Gomes --- CHANGELOG.md | 8 ++++++-- docs/README.md | 22 ++++++++++++++-------- messages/context.json | 6 ++++-- messages/en.json | 4 +++- messages/es.json | 4 +++- messages/pt.json | 4 +++- react/Image.tsx | 8 ++++++++ react/ImageTypes.ts | 4 ++++ react/modules/schema.ts | 6 ++++++ store/contentSchemas.json | 20 ++++++++++++++++++++ 10 files changed, 71 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8dd4fd5..4a02efb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +### Added + +- `promotionProductId` and `promotionProductName` props for `Image` and `ImageList` to be used by promotion analytics events. GA4's [view_promotion](https://developers.google.com/analytics/devguides/collection/ga4/reference/events?client_type=gtag#view_promotion) event now requires the product's ID or name. + ## [0.18.0] - 2023-04-25 ### Added @@ -109,7 +113,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - `list-context.image-list` has been refactored to use the `image-list` with a `list-context` ### Added -- `image-list` a new block that renders a simple list of images that can be editable via the Site Editor +- `image-list` a new block that renders a simple list of images that can be editable via the Site Editor ## [0.5.3] - 2020-10-07 ### Removed @@ -155,7 +159,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [0.4.2] - 2020-04-14 ### Fixed -- README.md documentation +- README.md documentation ## [0.4.1] - 2020-03-04 ### Fixed diff --git a/docs/README.md b/docs/README.md index 209f376..49cd2b5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -79,14 +79,20 @@ Note that the `slider-layout` block, exported from the Slider Layout app, is giv - **`images` array:** -| Prop name | Type | Description | Default value | -|---------------|---------------------|----------------------------------------------------------------------------------------------------|---------------| -| `image` | `string` | Image URL. | `undefined` | -| `mobileImage` | `string` | Mobile image URL. | `undefined` | -| `description` | `string` | Image description. | `undefined` | -| `link` | `object` | Links an URL to the image being rendered. | `undefined` | -| `width` | `string` / `number` | Image width (in `%` or `px`). | `100%` | -| `loading` | `string` | Loading strategy, either when the page loads (`'eager'`) or when closer to the viewport (`'lazy'`) | `'eager'` | +| Prop name | Type | Description | Default value | +|------------------------|---------------------|----------------------------------------------------------------------------------------------------|---------------| +| `image` | `string` | Image URL. | `undefined` | +| `mobileImage` | `string` | Mobile image URL. | `undefined` | +| `description` | `string` | Image description. | `undefined` | +| `link` | `object` | Links an URL to the image being rendered. | `undefined` | +| `width` | `string` / `number` | Image width (in `%` or `px`). | `100%` | +| `loading` | `string` | Loading strategy, either when the page loads (`'eager'`) or when closer to the viewport (`'lazy'`) | `'eager'` | +| `analyticsProperties` | `string` | Whether analytics props should be set (`'provided'`) or not (`'none'`) | `'none'` | +| `promotionId` | `string` | The ID of the promotion associated with the event. | `undefined` | +| `promotionName` | `string` | The name of the promotion associated with the event. | `undefined` | +| `promotionPosition` | `string` | The name of the promotional creative slot associated with the event. | `undefined` | +| `promotionProductId` | `string` | The ID of the product associated with the event. | `undefined` | +| `promotionProductName` | `string` | The name of the product associated with the event. | `undefined` | - **`link` object:** diff --git a/messages/context.json b/messages/context.json index e2c9a14..aed2df8 100644 --- a/messages/context.json +++ b/messages/context.json @@ -33,5 +33,7 @@ "admin/editor.image.analytics.provide": "Yes", "admin/editor.image.analytics.promotionId": "Promotion ID", "admin/editor.image.analytics.promotionName": "Promotion Name", - "admin/editor.image.analytics.promotionPosition": "Creative position" -} \ No newline at end of file + "admin/editor.image.analytics.promotionPosition": "Creative position", + "admin/editor.image.analytics.promotionProductId": "Product ID", + "admin/editor.image.analytics.promotionProductName": "Product Name" +} diff --git a/messages/en.json b/messages/en.json index 9363e40..aed2df8 100644 --- a/messages/en.json +++ b/messages/en.json @@ -33,5 +33,7 @@ "admin/editor.image.analytics.provide": "Yes", "admin/editor.image.analytics.promotionId": "Promotion ID", "admin/editor.image.analytics.promotionName": "Promotion Name", - "admin/editor.image.analytics.promotionPosition": "Creative position" + "admin/editor.image.analytics.promotionPosition": "Creative position", + "admin/editor.image.analytics.promotionProductId": "Product ID", + "admin/editor.image.analytics.promotionProductName": "Product Name" } diff --git a/messages/es.json b/messages/es.json index 206634a..c14cab3 100644 --- a/messages/es.json +++ b/messages/es.json @@ -33,5 +33,7 @@ "admin/editor.image.analytics.provide": "Sí", "admin/editor.image.analytics.promotionId": "ID de la promoción", "admin/editor.image.analytics.promotionName": "Nombre de la promoción", - "admin/editor.image.analytics.promotionPosition": "Posición creativa" + "admin/editor.image.analytics.promotionPosition": "Posición creativa", + "admin/editor.image.analytics.promotionProductId": "ID de producto", + "admin/editor.image.analytics.promotionProductName": "Nombre de producto" } diff --git a/messages/pt.json b/messages/pt.json index db23e84..f442632 100644 --- a/messages/pt.json +++ b/messages/pt.json @@ -33,5 +33,7 @@ "admin/editor.image.analytics.provide": "Sim", "admin/editor.image.analytics.promotionId": "Id da promoção", "admin/editor.image.analytics.promotionName": "Nome da promoção", - "admin/editor.image.analytics.promotionPosition": "Posição do criativo" + "admin/editor.image.analytics.promotionPosition": "Posição do criativo", + "admin/editor.image.analytics.promotionProductId": "Id do produto", + "admin/editor.image.analytics.promotionProductName": "Nome do produto" } diff --git a/react/Image.tsx b/react/Image.tsx index 606c336..b500e35 100644 --- a/react/Image.tsx +++ b/react/Image.tsx @@ -90,6 +90,8 @@ function Image(props: ImageProps) { promotionId, promotionName, promotionPosition, + promotionProductId, + promotionProductName, classes, preload, loading = 'eager', @@ -172,6 +174,12 @@ function Image(props: ImageProps) { name: promotionName, creative: formattedSrc, position: promotionPosition, + products: [ + { + productId: promotionProductId, + productName: promotionProductName, + }, + ], } : undefined diff --git a/react/ImageTypes.ts b/react/ImageTypes.ts index 9fea02a..d2df4c5 100644 --- a/react/ImageTypes.ts +++ b/react/ImageTypes.ts @@ -13,6 +13,8 @@ export interface ImageSchema { promotionId?: string promotionName?: string promotionPosition?: string + promotionProductId?: string + promotionProductName?: string } export type ImagesSchema = Array<{ @@ -29,6 +31,8 @@ export type ImagesSchema = Array<{ promotionId?: string promotionName?: string promotionPosition?: string + promotionProductId?: string + promotionProductName?: string }> interface Link { diff --git a/react/modules/schema.ts b/react/modules/schema.ts index 56955e8..2aa3d64 100644 --- a/react/modules/schema.ts +++ b/react/modules/schema.ts @@ -59,6 +59,12 @@ const IMAGE_LIST_MESSAGES = defineMessages({ analyticsPromotionPosition: { id: 'admin/editor.image.analytics.promotionPosition', }, + analyticspromotionProductId: { + id: 'admin/editor.image.analytics.promotionProductId', + }, + analyticspromotionProductName: { + id: 'admin/editor.image.analytics.promotionProductName', + }, }) export const IMAGE_LIST_SCHEMA = { diff --git a/store/contentSchemas.json b/store/contentSchemas.json index 9cc9f26..7c9841d 100644 --- a/store/contentSchemas.json +++ b/store/contentSchemas.json @@ -74,6 +74,16 @@ "title": "admin/editor.image.analytics.promotionPosition", "type": "string", "default": "" + }, + "promotionProductId": { + "title": "admin/editor.image.analytics.promotionProductId", + "type": "string", + "default": "" + }, + "promotionProductName": { + "title": "admin/editor.image.analytics.promotionProductName", + "type": "string", + "default": "" } } }, @@ -178,6 +188,16 @@ "title": "admin/editor.image.analytics.promotionPosition", "type": "string", "default": "" + }, + "promotionProductId": { + "title": "admin/editor.image.analytics.promotionProductId", + "type": "string", + "default": "" + }, + "promotionProductName": { + "title": "admin/editor.image.analytics.promotionProductName", + "type": "string", + "default": "" } } },