建立 Google Tag Manager 自訂像素
您可以將 Google Tag Manager (GTM) 當作自訂像素,用來管理第三方像素。
準備好測試 GTM 自訂像素時,請使用 Shopify Pixel Helper,確認您想追蹤的所有事件已正確加入沙箱且沒有錯誤。
您也可以使用 Google Tag Assistant 頁面擴充功能,測試頁面上載入了哪些 Google 標籤。不過,Google Tag Assistant 的 Troubleshoot tag 功能與自訂像素不相容,無法偵測自訂像素中的任何 Google 標籤,或由 GTM 載入的其他像素。
準備建立自訂像素
在使用 Google Tag Manager 建立自訂像素之前,請先閱讀以下資訊,以確保您瞭解如何設定像素:
- 建立或開啟 Google Tag Manager 帳戶,並取得 GTM 容器 ID。
- 為確保安全性,載入於我們沙箱中的標籤管理工具具有與其他像素相同的限制。瞭解詳情:像素沙箱限制。
建立 Google Tag Manager 自訂像素
您可以建立 Google Tag Manager 自訂像素來管理第三方像素。
步驟:
- 開啟您的 Google Tag Manager 帳戶,並選取要設定自訂像素的帳戶。
- 按一下 Admin,然後按一下 Install Google Tag Manager,以開啟安裝程式碼。
- 複製屬於頁面
head區段的程式碼區塊。 - 從程式碼區塊移除 HTML 標籤。例如,
<script></script>。 - 將其餘程式碼插入新的 Shopify Custom Pixel。
- Subscribe to customer events and push to GTM’s dataLayer.
- 若要檢視程式碼應如何顯示,請參考 example Google Tag Manager custom pixel。
- Configure Google Tag Manager to accept events from your Custom Pixel.
- 選用:如果您的
checkout.liquid檔案中已有dataLayer.push(event) 呼叫,則 replace it with analytics.publish()。
訂閱顧客事件,並推送至 GTM 的資料層
您可以在自訂像素程式碼中使用 GTM 的 dataLayer 訂閱顧客事件。
系統預設提供一組可供訂閱的 standard events。不過,如果您想追蹤不屬於這些標準事件的顧客事件,您可以 publish your own custom events from Liquid template files。
以下示範如何訂閱標準事件「product_viewed」,此事件代表有人檢視商品。當事件觸發時,會將事件推送到 dataLayer。
analytics.subscribe("product_viewed", (event) => {
window.dataLayer.push({
event: "product_viewed",
product_title: event.data?.productVariant?.title,
});
});在此範例中,會在事件承載資料中傳遞產品名稱。您可以使用 Google Tag Manager variable,從事件承載資料擷取產品名稱,並在您選用的標籤中使用。
Google Tag Manager 自訂像素範例
以下範例是精簡版的 Google Tag Manager 自訂像素,示範如何將資料傳送到 Google Tag Manager。若要將更多事件推送到您的 dataLayer,您可以訂閱更多標準事件與自訂事件。
// Define dataLayer and the gtag function.
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
//Initialize GTM tag
(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer', 'GTM-XXXXXXX');
//Google Consent Mode v2
gtag('consent', 'update', {
'ad_storage': 'granted',
'analytics_storage': 'granted',
'ad_user_data': 'granted',
'ad_personalization': 'granted',
});
//subscribe to events
analytics.subscribe("checkout_completed", (event) => {
window.dataLayer.push({
event: "checkout_completed",
timestamp: event.timestamp,
id: event.id,
token: event.data?.checkout?.token,
url: event.context.document.location.href,
client_id: event.clientId,
email: event.data?.checkout?.email,
phone: event.data?.checkout?.phone,
first_name: event.data?.checkout?.shippingAddress?.firstName,
last_name: event.data?.checkout?.shippingAddress?.lastName,
address1: event.data?.checkout?.shippingAddress?.address1,
address2: event.data?.checkout?.shippingAddress?.address2,
city: event.data?.checkout?.shippingAddress?.city,
country: event.data?.checkout?.shippingAddress?.country,
countryCode: event.data?.checkout?.shippingAddress?.countryCode,
province: event.data?.checkout?.shippingAddress?.province,
provinceCode: event.data?.checkout?.shippingAddress?.provinceCode,
zip: event.data?.checkout?.shippingAddress?.zip,
orderId: event.data?.checkout?.order?.id,
currency: event.data?.checkout?.currencyCode,
subtotal: event.data?.checkout?.subtotalPrice?.amount,
shipping: event.data?.checkout?.shippingLine?.price?.amount,
value: event.data?.checkout?.totalPrice?.amount,
tax: event.data?.checkout?.totalTax?.amount,
});
});
analytics.subscribe("payment_info_submitted", (event) => {
window.dataLayer.push({
event: "payment_info_submitted",
timestamp: event.timestamp,
id: event.id,
token: event.data?.checkout?.token,
url: event.context.document.location.href,
client_id: event.clientId,
email: event.data?.checkout?.email,
phone: event.data?.checkout?.phone,
first_name: event.data?.checkout?.shippingAddress?.firstName,
last_name: event.data?.checkout?.shippingAddress?.lastName,
address1: event.data?.checkout?.shippingAddress?.address1,
address2: event.data?.checkout?.shippingAddress?.address2,
city: event.data?.checkout?.shippingAddress?.city,
country: event.data?.checkout?.shippingAddress?.country,
countryCode: event.data?.checkout?.shippingAddress?.countryCode,
province: event.data?.checkout?.shippingAddress?.province,
provinceCode: event.data?.checkout?.shippingAddress?.provinceCode,
zip: event.data?.checkout?.shippingAddress?.zip,
orderId: event.data?.checkout?.order?.id,
currency: event.data?.checkout?.currencyCode,
subtotal: event.data?.checkout?.subtotalPrice?.amount,
shipping: event.data?.checkout?.shippingLine?.price?.amount,
value: event.data?.checkout?.totalPrice?.amount,
tax: event.data?.checkout?.totalTax?.amount,
});
});
analytics.subscribe("checkout_shipping_info_submitted", (event) => {
window.dataLayer.push({
event: "checkout_shipping_info_submitted",
timestamp: event.timestamp,
id: event.id,
token: event.data?.checkout?.token,
url: event.context.document.location.href,
client_id: event.clientId,
email: event.data?.checkout?.email,
phone: event.data?.checkout?.phone,
first_name: event.data?.checkout?.shippingAddress?.firstName,
last_name: event.data?.checkout?.shippingAddress?.lastName,
address1: event.data?.checkout?.shippingAddress?.address1,
address2: event.data?.checkout?.shippingAddress?.address2,
city: event.data?.checkout?.shippingAddress?.city,
country: event.data?.checkout?.shippingAddress?.country,
countryCode: event.data?.checkout?.shippingAddress?.countryCode,
province: event.data?.checkout?.shippingAddress?.province,
provinceCode: event.data?.checkout?.shippingAddress?.provinceCode,
zip: event.data?.checkout?.shippingAddress?.zip,
orderId: event.data?.checkout?.order?.id,
currency: event.data?.checkout?.currencyCode,
subtotal: event.data?.checkout?.subtotalPrice?.amount,
shipping: event.data?.checkout?.shippingLine?.price?.amount,
value: event.data?.checkout?.totalPrice?.amount,
tax: event.data?.checkout?.totalTax?.amount,
});
});
analytics.subscribe("checkout_address_info_submitted", (event) => {
window.dataLayer.push({
event: "checkout_address_info_submitted",
timestamp: event.timestamp,
id: event.id,
token: event.data?.checkout?.token,
url: event.context.document.location.href,
client_id: event.clientId,
email: event.data?.checkout?.email,
phone: event.data?.checkout?.phone,
first_name: event.data?.checkout?.shippingAddress?.firstName,
last_name: event.data?.checkout?.shippingAddress?.lastName,
address1: event.data?.checkout?.shippingAddress?.address1,
address2: event.data?.checkout?.shippingAddress?.address2,
city: event.data?.checkout?.shippingAddress?.city,
country: event.data?.checkout?.shippingAddress?.country,
countryCode: event.data?.checkout?.shippingAddress?.countryCode,
province: event.data?.checkout?.shippingAddress?.province,
provinceCode: event.data?.checkout?.shippingAddress?.provinceCode,
zip: event.data?.checkout?.shippingAddress?.zip,
orderId: event.data?.checkout?.order?.id,
currency: event.data?.checkout?.currencyCode,
subtotal: event.data?.checkout?.subtotalPrice?.amount,
shipping: event.data?.checkout?.shippingLine?.price?.amount,
value: event.data?.checkout?.totalPrice?.amount,
tax: event.data?.checkout?.totalTax?.amount,
});
});
analytics.subscribe("checkout_contact_info_submitted", (event) => {
window.dataLayer.push({
event: "checkout_contact_info_submitted",
timestamp: event.timestamp,
id: event.id,
token: event.data?.checkout?.token,
url: event.context.document.location.href,
client_id: event.clientId,
email: event.data?.checkout?.email,
phone: event.data?.checkout?.phone,
first_name: event.data?.checkout?.shippingAddress?.firstName,
last_name: event.data?.checkout?.shippingAddress?.lastName,
address1: event.data?.checkout?.shippingAddress?.address1,
address2: event.data?.checkout?.shippingAddress?.address2,
city: event.data?.checkout?.shippingAddress?.city,
country: event.data?.checkout?.shippingAddress?.country,
countryCode: event.data?.checkout?.shippingAddress?.countryCode,
province: event.data?.checkout?.shippingAddress?.province,
provinceCode: event.data?.checkout?.shippingAddress?.provinceCode,
zip: event.data?.checkout?.shippingAddress?.zip,
orderId: event.data?.checkout?.order?.id,
currency: event.data?.checkout?.currencyCode,
subtotal: event.data?.checkout?.subtotalPrice?.amount,
shipping: event.data?.checkout?.shippingLine?.price?.amount,
value: event.data?.checkout?.totalPrice?.amount,
tax: event.data?.checkout?.totalTax?.amount,
});
});
analytics.subscribe("checkout_started", (event) => {
window.dataLayer.push({
event: "checkout_started",
timestamp: event.timestamp,
id: event.id,
token: event.data?.checkout?.token,
url: event.context.document.location.href,
client_id: event.clientId,
email: event.data?.checkout?.email,
phone: event.data?.checkout?.phone,
first_name: event.data?.checkout?.shippingAddress?.firstName,
last_name: event.data?.checkout?.shippingAddress?.lastName,
address1: event.data?.checkout?.shippingAddress?.address1,
address2: event.data?.checkout?.shippingAddress?.address2,
city: event.data?.checkout?.shippingAddress?.city,
country: event.data?.checkout?.shippingAddress?.country,
countryCode: event.data?.checkout?.shippingAddress?.countryCode,
province: event.data?.checkout?.shippingAddress?.province,
provinceCode: event.data?.checkout?.shippingAddress?.provinceCode,
zip: event.data?.checkout?.shippingAddress?.zip,
orderId: event.data?.checkout?.order?.id,
currency: event.data?.checkout?.currencyCode,
subtotal: event.data?.checkout?.subtotalPrice?.amount,
shipping: event.data?.checkout?.shippingLine?.price?.amount,
value: event.data?.checkout?.totalPrice?.amount,
tax: event.data?.checkout?.totalTax?.amount,
});
});
analytics.subscribe("product_added_to_cart", (event) => {
window.dataLayer.push({
event: "product_added_to_cart",
timestamp: event.timestamp,
id: event.id,
client_id: event.clientId,
url: event.context.document.location.href,
price: event.data?.cartLine?.merchandise?.price?.amount,
currency: event.data?.cartLine?.merchandise?.id,
product_title: event.data?.cartLine?.merchandise?.product?.title,
quantity: event.data?.cartLine?.quantity,
total_cost: event.data?.cartLine?.cost?.totalAmount?.amount,
});
});
analytics.subscribe("cart_viewed", (event) => {
window.dataLayer.push({
event: "cart_viewed",
timestamp: event.timestamp,
id: event.id,
client_id: event.clientId,
url: event.context.document.location.href,
total_cost: event.data?.cart?.cost?.totalAmount?.amount,
quantity: event.data?.cart?.totalQuantity,
cart_id: event.data?.cart?.id,
});
});
analytics.subscribe("page_viewed", (event) => {
window.dataLayer.push({
event: "page_viewed",
timestamp: event.timestamp,
id: event.id,
client_id: event.clientId,
url: event.context.document.location.href,
page_title: event.context.document.title,
});
});
analytics.subscribe("product_viewed", (event) => {
window.dataLayer.push({
event: "product_viewed",
timestamp: event.timestamp,
id: event.id,
client_id: event.clientId,
url: event.context.document.location.href,
product_id: event.data?.productVariant?.product?.id,
product_title: event.data?.productVariant?.title,
product_sku: event.data?.productVariant?.sku,
});
});
analytics.subscribe("search_submitted", (event) => {
window.dataLayer.push({
event: "search_submitted",
timestamp: event.timestamp,
id: event.id,
client_id: event.clientId,
url: event.context.document.location.href,
query: event.data?.searchResult?.query,
});
});
analytics.subscribe("collection_viewed", (event) => {
window.dataLayer.push({
event: "collection_viewed",
timestamp: event.timestamp,
id: event.id,
client_id: event.clientId,
url: event.context.document.location.href,
collection_id: event.data?.collection?.id,
collection_title: event.data?.collection?.title,
});
});設定 Google Tag Manager 以接受自訂像素傳送的事件
建立自訂像素後,您需要設定 Google Tag Manager 以接受自訂像素傳送的事件。為此,您需要在 Google Tag Manager 中建立標籤、觸發條件,以及 dataLayer 變數。
下表列出部分標準顧客事件及其在 Google Tag Manager 中的對應事件:
| Shopify 事件 | 觸發條件 | GTM 事件 |
|---|---|---|
| payment_info_submitted | 提交付款資訊 | add_payment_info |
| checkout_address_info_submitted | 提交運送資訊 | add_shipping_info |
| product_added_to_cart | 將品項加入購物車 | add_to_cart |
| checkout_started | 開始結帳 | begin_checkout |
| checkout_completed | 完成結帳 | purchase |
| product_removed_from_cart | 從購物車移除品項 | remove_from_cart |
| cart_viewed | 檢視購物車 | view_cart |
| product_viewed | 檢視商品詳情頁面 | view_item |
| collection_viewed | 檢視品項清單 | view_item_list |
為了讓系統處理您的自訂像素 dataLayer 事件,GTM 標籤的事件參數必須符合 expected naming conventions。
以下是部分自訂像素 dataLayer 事件屬性及其在 Google Analytics 4 (GA4) 中對應事件參數的範例:
自訂像素 dataLayer 事件 | GA4 事件參數 |
|---|---|
| event.data?.checkout?.currencyCode | currency |
| event.data?.checkout?.totalPrice?.amount | value |
| event.data?.checkout?.order?.id | transaction_id |
| event.data?.checkout?.discountAllocations | coupon |
| event.data?.checkout?.shippingLine?.price?.amount | shipping |
| event.data?.checkout?.totalTax | tax |
| event.data?.checkout?.lineItems | items |
以下是使用 checkout_completed 事件的範例:
analytics.subscribe("checkout_completed", (event) => {
window.dataLayer.push({
event: "checkout_completed",
orderId: event.data?.checkout?.order?.id,
currency: event.data?.checkout?.currencyCode,
price: event.data.checkout.totalPrice.amount,
shippingLine: event.data.checkout.shippingLine.price.amount,
totalTax: event.data.checkout.totalTax,
});
});Google Tag Manager 的觸發條件是自訂事件類型,事件名稱為 checkout_completed。觸發條件中的 Event name 欄位必須與您的自訂像素中的 event 鍵相符。
orderId 與 currency 是您在 Google Tag Manager 中用來擷取事件資料的變數。您可以將它們對應到 Google Tag Manager 中的 dataLayer 變數。每個事件變數都需要各自的 dataLayer 變數。將觸發條件設定為在所有自訂事件上觸發。
建立一個使用您剛剛建立的觸發條件的標籤。在事件參數中,加入您要擷取的變數。以上述範例而言,orderId、currency、price、shippingLine 和 totalTax 會設定為 dataLayer 變數。每次標籤觸發時,會連同事件一併擷取這些 dataLayer 變數。
請注意,必須先在 Google Tag Manager 設定至少一個標籤與觸發條件,才會進行資料傳輸。
以 analytics.publish() 取代舊的 dataLayer.push(event) 呼叫
如果您先前已設定 Google Tag Manager,則必須將 dataLayer.push 呼叫改成 Shopify.analytics.publish() 呼叫。您可以在 theme.liquid 檔案中,以及佈景主題編輯器的 Layout 區段找到您的 dataLayer.push 呼叫。
您也必須替換 checkout.liquid 中的 dataLayer.push 呼叫。不過,由於 checkout.liquid 與 Shopify Extensions 不相容,您需要使用 UI 擴充功能將資料推送到網頁像素。
以下是使用 dataLayer 在 theme.liquid 檔案中追蹤自訂電子郵件註冊事件的簡化範例:
<script>
dataLayer.push({ event: 'email_signup', email: customer.email });
</script>Shopify 的對應作法如下,會將資料推送至您的自訂像素:
<script>
Shopify.analytics.publish('email_signup', {email: customer.email });
</script>接著,請在您的 自訂像素程式碼 中加入類似以下內容:
analytics.subscribe("email_signup", (event) => {
window.dataLayer.push({
'event': 'email_signup',
'email': event.customData.email,
});
});取代舊的 dataLayer.push(data)
Google Tag Manager 具備一項功能,允許您在每個事件上推送具狀態的 dataLayer 物件。雖然 Shopify 的像素沙箱不包含等同的功能,但您可以建立自己的資料物件並傳入自訂事件,以達成相同效果。
例如,請先在發布任何自訂事件之前定義「customData」物件:
<script>
const customData = {email: customer.email}
</script>之後,每當您要包含自訂資料時,都將它傳入您的發布方法:
<script>
Shopify.analytics.publish('email_signup', customData);
</script>設定 Google Analytics 4 的提示
當您使用 Google Tag Manager 作為自訂像素時,請參考以下設定 Google Analytics 4 (GA4) 的提示。
更乾淨的頁面網址
在沙箱中執行 GA4 時,您可能會注意到頁面網址包含它所執行的沙箱相關資訊。若您想移除這些網址中的沙箱資訊,可以 turn off GA4’s automatic pages tracking,改用標準的 page_viewed 事件自行實作。
analytics.subscribe('page_viewed', (event) => {
window.dataLayer.push({
'event': 'page_viewed',
'page_location': event.context.window.location.href,
'page_title': event.context.document.title,
});
});將您自己的事件發布到 dataLayer 之後,您可以建立一個在 page_viewed 事件上觸發的 GA4 page_view 標籤。通常您可以使用 Google Analytics: GA4 Event 標籤類型,並將 Event Name 設為 page_view。設定好標籤類型與事件名稱後,請新增 page_location 參數,並將其值設為您從自訂像素傳入 dataLayer 的相同值。
加強型衡量
在 Shopify 的像素沙箱中載入 GA4 時,原本會自動推斷的部分事件需要手動設定。舉例來說,外部連結點擊屬於 GA4 的加強型衡量設定,使用自訂像素時,基於安全性考量無法自動觸發。不過,您可以自行將 GA4 的 enhanced measurement events 以自訂事件方式實作。
以下程式碼提供一個追蹤外部連結點擊的簡化範例:
<script>
function detectOutboundLink() {
// add your logic for determining if a link click is outbound
// if the link click is outbound then publish it
if (isOutboundLink) {
Shopify.analytics.publish('outbound_link', { link_url: link_url });
}
}
</script>最後,在 GTM 中建立一個 GA4 標籤,將連結點擊送至 GA4,並確保事件名稱為 click,以符合 GA4’s enhanced event naming。
上述做法同樣適用於所有 Google 的加強型衡量指標。
測試與除錯您的自訂像素
準備好測試 GTM 自訂像素時,請使用 Shopify Pixel Helper,確認您想追蹤的所有事件已正確加入沙箱且沒有錯誤。
您也可以使用 Google Tag Assistant 頁面擴充功能,測試頁面上載入了哪些 Google 標籤。不過,Google Tag Assistant 的 Troubleshoot tag 功能與自訂像素不相容,無法偵測自訂像素中的任何 Google 標籤,或由 GTM 載入的其他像素。