From 769c7759ab1ae68955a6919a15620882506ce99d Mon Sep 17 00:00:00 2001 From: igorbrasileiro Date: Fri, 19 May 2023 16:18:21 -0300 Subject: [PATCH 01/10] Work for pdp --- .../VTEXPortalDataLayerCompatibility.tsx | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 components/VTEXPortalDataLayerCompatibility.tsx diff --git a/components/VTEXPortalDataLayerCompatibility.tsx b/components/VTEXPortalDataLayerCompatibility.tsx new file mode 100644 index 00000000..e9768ab7 --- /dev/null +++ b/components/VTEXPortalDataLayerCompatibility.tsx @@ -0,0 +1,149 @@ +import { Product } from "deco-sites/std/commerce/types.ts"; +import { Head } from "$fresh/runtime.ts"; + +// deno-lint-ignore no-explicit-any +function addVTEXPortalDataSnippet(accountName: any) { + const structuredDataScripts = + document.querySelectorAll('script[type="application/ld+json"]') || []; + // deno-lint-ignore no-explicit-any + const structuredDatas: Record[] = []; + // deno-lint-ignore no-explicit-any + structuredDataScripts.forEach((v: any) => { + structuredDatas.push(JSON.parse(v.text)); + }); + const isProductPage = structuredDatas.some((s) => s["@type"] === "Product"); + + // deno-lint-ignore no-explicit-any + const props: Record = { + pageCategory: "Home", + pageDepartment: null, + pageUrl: window.location.href, + pageTitle: document.title, + skuStockOutFromShelf: [], + skuStockOutFromProductDetail: [], + accountName: `${accountName}`, + pageFacets: [], + shelfProductIds: [], + }; + // categoryName: "", + // categoryId: "", + + if (isProductPage) { + props.pageCategory = "Product"; + // const productSD = structuredDatas.find(( + // s, + // ) => (s["@type"] === "Product")) || {}; + // + // props.pageDepartment = productSD.additionalProperty.find((p) => + // p.name === "category" + // ).value; + // props["productId"] = productSD.productID; + // props["productReferenceId"] = new URL(window.location.href).pathname.split( + // "/", + // )[1].split("-").pop(); // Isso não é verdade exemplo: https://fashion.deco.site/camisa-masculina-rock/p?skuId=92 + // props["productEans"] = [ + // productSD.gtin, + // ]; + // props["skuStocks"] = { + // [productSD.sku]: productSD.offers?.offers?.[0]?.inventoryLevel.value, + // }; + // + // props["productName"] = productSD.name; + // props["productBrandName"] = productSD.brand; + // props["productDepartmentName"] = props.pageDepartment; + // props["productCategoryName"] = props.additionalProperty.findLast((v) => + // v.name === "category" + // )?.value; + // + // const offer = productSD.offers; + // props["productListPriceFrom"] = offer.lowPrice; + // props["productListPriceTo"] = offer.highPrice; + // props["productPriceFrom"] = offer.lowPrice; + // props["productPriceTo"] = offer.highPrice; + // + // props["productBrandId"] = 930833574; + // props["productDepartmentId"] = 4010494; + // props["productCategoryId"] = 4010502; + // props["sellerId"] = "1"; + // props["sellerIds"] = "1"; + const scriptEl: HTMLScriptElement | null = document.querySelector( + 'script[data-id="vtex-portal-compat"]', + ); + console.log("scruot", scriptEl?.dataset); + if (scriptEl) { + Object.assign(props, JSON.parse(scriptEl.dataset.datalayer || "{}")); + } + } + + if (!isProductPage) { + const breadcrumbSD = structuredDatas.find(( + s, + ) => (s["@type"] === "BreadcrumbList")); + props.pageDepartment = breadcrumbSD?.itemListElement?.[0]?.name || ""; // what to do here?; + if (props.pageDepartment) { + props.pageCategory = "Category"; + } + } + + window.dataLayer = window.dataLayer || []; + window.dataLayer.push(props); +} + +export function AddVTEXPortalData({ accountName }: { accountName: string }) { + return ( + + + ); +} From 32ba0ad549297d1259300e8d750dbb9d64b5a843 Mon Sep 17 00:00:00 2001 From: igorbrasileiro Date: Fri, 19 May 2023 16:30:54 -0300 Subject: [PATCH 02/10] Deal with home, category pages and landing --- .../VTEXPortalDataLayerCompatibility.tsx | 60 +++++-------------- 1 file changed, 16 insertions(+), 44 deletions(-) diff --git a/components/VTEXPortalDataLayerCompatibility.tsx b/components/VTEXPortalDataLayerCompatibility.tsx index e9768ab7..5b09be3b 100644 --- a/components/VTEXPortalDataLayerCompatibility.tsx +++ b/components/VTEXPortalDataLayerCompatibility.tsx @@ -25,63 +25,31 @@ function addVTEXPortalDataSnippet(accountName: any) { pageFacets: [], shelfProductIds: [], }; - // categoryName: "", - // categoryId: "", if (isProductPage) { props.pageCategory = "Product"; - // const productSD = structuredDatas.find(( - // s, - // ) => (s["@type"] === "Product")) || {}; - // - // props.pageDepartment = productSD.additionalProperty.find((p) => - // p.name === "category" - // ).value; - // props["productId"] = productSD.productID; - // props["productReferenceId"] = new URL(window.location.href).pathname.split( - // "/", - // )[1].split("-").pop(); // Isso não é verdade exemplo: https://fashion.deco.site/camisa-masculina-rock/p?skuId=92 - // props["productEans"] = [ - // productSD.gtin, - // ]; - // props["skuStocks"] = { - // [productSD.sku]: productSD.offers?.offers?.[0]?.inventoryLevel.value, - // }; - // - // props["productName"] = productSD.name; - // props["productBrandName"] = productSD.brand; - // props["productDepartmentName"] = props.pageDepartment; - // props["productCategoryName"] = props.additionalProperty.findLast((v) => - // v.name === "category" - // )?.value; - // - // const offer = productSD.offers; - // props["productListPriceFrom"] = offer.lowPrice; - // props["productListPriceTo"] = offer.highPrice; - // props["productPriceFrom"] = offer.lowPrice; - // props["productPriceTo"] = offer.highPrice; - // - // props["productBrandId"] = 930833574; - // props["productDepartmentId"] = 4010494; - // props["productCategoryId"] = 4010502; - // props["sellerId"] = "1"; - // props["sellerIds"] = "1"; const scriptEl: HTMLScriptElement | null = document.querySelector( 'script[data-id="vtex-portal-compat"]', ); - console.log("scruot", scriptEl?.dataset); if (scriptEl) { Object.assign(props, JSON.parse(scriptEl.dataset.datalayer || "{}")); } } - if (!isProductPage) { - const breadcrumbSD = structuredDatas.find(( - s, - ) => (s["@type"] === "BreadcrumbList")); - props.pageDepartment = breadcrumbSD?.itemListElement?.[0]?.name || ""; // what to do here?; + const breadcrumbSD = structuredDatas.find(( + s, + ) => (s["@type"] === "BreadcrumbList")); + if (breadcrumbSD) { + const department = breadcrumbSD?.itemListElement?.[0]; + props.pageDepartment = department?.name || null; if (props.pageDepartment) { props.pageCategory = "Category"; + const category = breadcrumbSD?.itemListElement + ?.[breadcrumbSD?.itemListElement.length - 1]; + props.categoryName = category?.name; + } else { + props.pageCategory = new URL(window.location.href).pathname.split("/") + .filter(Boolean).join(" "); } } @@ -147,3 +115,7 @@ export function ProductDetailsTemplate({ product }: { product: Product }) { ); } + +// How to use: +// 1. add the AddVTEXPortalData at routes/_app.tsx before +// 2. add the ProductDetailsTemplate at ProductDetails.tsx for routes /:slug/p From 18fe3506adb365b85fbc8d480a0216a0d1cae69e Mon Sep 17 00:00:00 2001 From: igorbrasileiro Date: Fri, 19 May 2023 16:59:30 -0300 Subject: [PATCH 03/10] Add product shelf ids --- .../VTEXPortalDataLayerCompatibility.tsx | 37 ++++++++++++++----- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/components/VTEXPortalDataLayerCompatibility.tsx b/components/VTEXPortalDataLayerCompatibility.tsx index 5b09be3b..553921c5 100644 --- a/components/VTEXPortalDataLayerCompatibility.tsx +++ b/components/VTEXPortalDataLayerCompatibility.tsx @@ -1,5 +1,4 @@ -import { Product } from "deco-sites/std/commerce/types.ts"; -import { Head } from "$fresh/runtime.ts"; +import { Product, ProductGroup } from "deco-sites/std/commerce/types.ts"; // deno-lint-ignore no-explicit-any function addVTEXPortalDataSnippet(accountName: any) { @@ -53,6 +52,12 @@ function addVTEXPortalDataSnippet(accountName: any) { } } + document.querySelectorAll("[data-product-id]").forEach( + (el) => { + props.shelfProductIds.push((el as HTMLDivElement).dataset.productId); + }, + ); + window.dataLayer = window.dataLayer || []; window.dataLayer.push(props); } @@ -106,16 +111,28 @@ export function ProductDetailsTemplate({ product }: { product: Product }) { }; return ( - - - + + ); +} + +interface ProductShelfIdsProps { + product: Product; +} +export function ProductCardId({ product }: ProductShelfIdsProps) { + if (!product.isVariantOf?.productGroupID) return null; + return ( +
); } // How to use: -// 1. add the AddVTEXPortalData at routes/_app.tsx before +// 1. add the AddVTEXPortalData at routes/_app.tsx after // 2. add the ProductDetailsTemplate at ProductDetails.tsx for routes /:slug/p +// 3. add ProductShelfIds at product shelves From f1630b2f660df782ee1ebb4d9bf6c4e768c975a0 Mon Sep 17 00:00:00 2001 From: igorbrasileiro Date: Fri, 19 May 2023 18:24:32 -0300 Subject: [PATCH 04/10] Add skuJson section --- .../VTEXPortalDataLayerCompatibility.tsx | 16 +++++++- sections/VTEXPortalDataLayerCompatibility.tsx | 38 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 sections/VTEXPortalDataLayerCompatibility.tsx diff --git a/components/VTEXPortalDataLayerCompatibility.tsx b/components/VTEXPortalDataLayerCompatibility.tsx index 553921c5..6e33c975 100644 --- a/components/VTEXPortalDataLayerCompatibility.tsx +++ b/components/VTEXPortalDataLayerCompatibility.tsx @@ -1,4 +1,4 @@ -import { Product, ProductGroup } from "deco-sites/std/commerce/types.ts"; +import { Product } from "deco-sites/std/commerce/types.ts"; // deno-lint-ignore no-explicit-any function addVTEXPortalDataSnippet(accountName: any) { @@ -132,7 +132,21 @@ export function ProductCardId({ product }: ProductShelfIdsProps) { ); } +export interface ProductSKUJsonProps { + product: unknown; +} +export function ProductSKUJson({ product }: ProductSKUJsonProps) { + return ( + + dangerouslySetInnerHTML={{ + __html: + `window.dataLayer = window.dataLayer || []; window.dataLayer.push({ event: "productView" })`, + }} + /> ); } From 4e044cfab1f0f038ba0bac27e8e0fe8adf7d2329 Mon Sep 17 00:00:00 2001 From: igorbrasileiro Date: Mon, 22 May 2023 14:00:24 -0300 Subject: [PATCH 09/10] Add custom events --- components/VTEXPortalDataLayerCompatibility.tsx | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/components/VTEXPortalDataLayerCompatibility.tsx b/components/VTEXPortalDataLayerCompatibility.tsx index 0025a86c..c8ad71ef 100644 --- a/components/VTEXPortalDataLayerCompatibility.tsx +++ b/components/VTEXPortalDataLayerCompatibility.tsx @@ -2,6 +2,7 @@ import { Product } from "deco-sites/std/commerce/types.ts"; // deno-lint-ignore no-explicit-any function addVTEXPortalDataSnippet(accountName: any) { + const url = new URL(window.location.href); const structuredDataScripts = document.querySelectorAll('script[type="application/ld+json"]') || []; // deno-lint-ignore no-explicit-any @@ -61,6 +62,16 @@ function addVTEXPortalDataSnippet(accountName: any) { window.dataLayer = window.dataLayer || []; window.dataLayer.unshift(props); + + if (url.pathname === "/") { + window.dataLayer.push({ event: "homeView" }); + } else if (props.pageCategory === "Product") { + window.dataLayer.push({ event: "productView" }); + } else if (props.pageCategory === "Category") { + window.dataLayer.push({ event: "categoryView" }); + } else { + window.dataLayer.push({ event: "otherView" }); + } } export function AddVTEXPortalData({ accountName }: { accountName: string }) { @@ -115,10 +126,6 @@ export function ProductDetailsTemplate({ product }: { product: Product }) {