Google タグマネージャーのカスタムピクセルを作成する

Google タグマネージャー (GTM) をカスタムピクセルとして使用して、外部サービスのピクセルを管理できます。

GTM カスタムピクセルをテストする準備ができたら、Shopify Pixel Helper を使用して、追跡するすべてのイベントがエラーなくサンドボックスに追加されていることを確認してください。

また、Google Tag Assistant のページ拡張機能を使用して、ページに読み込まれている Google タグをテストすることもできます。ただし、Google Tag Assistant の「Troubleshoot tag」機能はカスタムピクセルと互換性がなく、カスタムピクセル内の Google タグや、GTM によって読み込まれるその他のピクセルを検出しません。

カスタムピクセル作成の準備

Google タグマネージャーを使用してカスタムピクセルを作成する前に、ピクセルの設定方法を確実に理解するため、以下の情報を確認してください。

Google タグマネージャーのカスタムピクセルを作成する

Google タグマネージャーのカスタムピクセルを作成して、外部サービスのピクセルを管理できます。

手順:

  1. Google タグマネージャーアカウントを開き、カスタムピクセルを設定するアカウントを選択します。
  2. [管理] をクリックし、次に [Google タグマネージャーをインストール] をクリックしてインストールコードを開きます。
  3. ページの head セクションに属するコードブロックをコピーします。
  4. コードブロックから HTML タグを削除します。たとえば、<script></script> です。
  5. 残りのコードを新しいShopify カスタムピクセルに挿入します。
  6. 顧客イベントをサブスクライブして GTM の dataLayer にプッシュする
  7. コードがどのように表示されるかを確認するには、Google タグマネージャーのカスタムピクセルの例を参照してください。
  8. カスタムピクセルからのイベントを受け入れるように Google タグマネージャーを設定する
  9. オプション:checkout.liquid ファイルに既存の dataLayer.push(event) 呼び出しがある場合は、analytics.publish() に置き換えてください。

顧客イベントをサブスクライブして GTM のデータレイヤーにプッシュする

カスタムピクセルコードで GTM の dataLayer を使用して、顧客イベントをサブスクライブできます。

デフォルトでは、サブスクライブできる一連の標準イベントがあります。ただし、標準イベントとして提供されていない顧客イベントを追跡したい場合は、Liquid テンプレートファイルから独自のカスタムイベントを公開することができます。

以下は、誰かが商品を表示したことを示す、標準の「product_viewed」イベントをサブスクライブする例です。イベントがトリガーされると、イベントが dataLayer にプッシュされます。

analytics.subscribe("product_viewed", (event) => {
  window.dataLayer.push({
    event: "product_viewed",
    product_title: event.data?.productVariant?.title,
  });
});

この例では、イベントペイロードで商品名が渡されています。任意のタグでGoogle タグマネージャー変数を使用して、イベントペイロードから商品名をキャプチャーできます。

Google タグマネージャーのカスタムピクセルの例

以下の例は、Google タグマネージャーにデータを送信する方法を示す、Google タグマネージャーのカスタムピクセルの簡略版です。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 タグマネージャーを設定する

カスタムピクセルを作成した後、カスタムピクセルからのイベントを受け入れるように Google タグマネージャーを設定する必要があります。これを行うには、Google タグマネージャーでタグ、トリガー、および dataLayer 変数が必要です。

一部の標準顧客イベントと、それに相当する Google タグマネージャーのイベントの例を、次の表に記載しています。

ピクセルで使用する標準 Shopify 顧客イベント、それに対応する Google タグマネージャーの顧客イベント、およびイベントの発火に必要なトリガーの一覧。
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 タグイベントのパラメーターが想定される命名規則と一致している必要があります。

一部のカスタムピクセル dataLayer イベントプロパティと、それに対応する Google アナリティクス 4 (GA4) のイベントパラメーターの例は、以下のとおりです。

GA4 の命名規則を使用する、カスタムピクセルの dataLayer イベントの一覧
カスタムピクセルの dataLayer イベントGA4 イベントパラメーター
event.data?.checkout?.currencyCodecurrency
event.data?.checkout?.totalPrice?.amountvalue
event.data?.checkout?.order?.idtransaction_id
event.data?.checkout?.discountAllocationscoupon
event.data?.checkout?.shippingLine?.price?.amountshipping
event.data?.checkout?.totalTaxtax
event.data?.checkout?.lineItemsitems

次の 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 タグマネージャのトリガーは、イベント名が checkout_completed のカスタムイベントタイプです。トリガーの [イベント名] フィールドは、カスタムピクセル内の event キーと一致している必要があります。

orderIdcurrency は、イベントからデータを取得するために Google タグマネージャで使用する変数です。これらは、Google タグマネージャの dataLayer 変数にマッピングできます。各イベント変数には、それぞれに dataLayer 変数が必要です。すべてのカスタムイベントで発火するようにトリガーを設定します。

先ほど作成したトリガーを使用するタグを作成します。イベントパラメータで、取得する変数を追加します。上記の例では、orderIdcurrencypriceshippingLinetotalTaxdataLayer 変数として設定されます。タグが発火するたびに、イベントとともにこれらの dataLayer 変数が取得されます。

データ移行を行うには、Google タグマネージャで少なくとも 1 つのタグとトリガーを設定する必要があることに注意してください。

古い dataLayer.push(event) の呼び出しを analytics.publish() に置き換える

以前に Google タグマネージャを設定したことがある場合は、dataLayer.push の呼び出しを Shopify.analytics.publish() の呼び出しに置き換える必要があります。dataLayer.push の呼び出しは、テーマエディタの [レイアウト] セクションにある theme.liquid ファイル内で確認できます。

また、checkout.liquid 内の dataLayer.push の呼び出しを置き換える必要もあります。しかし、checkout.liquid は Shopify Extensions と互換性がないため、ウェブピクセルにデータをプッシュするには、UI 拡張機能を使用する必要があります。

以下は、theme.liquid ファイルで dataLayer を使用してカスタムメールのサインアップイベントを追跡する簡単な例です。

<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 タグマネージャには、すべてのイベントでステートフルな dataLayer オブジェクトをプッシュできる機能があります。Shopify のピクセルサンドボックスには同等の機能は含まれていませんが、独自のデータオブジェクトを作成してカスタムイベントに渡すことで、同じ結果を得ることができます。

たとえば、カスタムイベントを公開する前に、「customData」オブジェクトを次のように定義します。

<script>
  const customData = {email: customer.email}
</script>

次に、カスタムデータを含めたい場合はいつでも、それを publish メソッドに渡します。

<script>
  Shopify.analytics.publish('email_signup', customData);
</script>

Googleアナリティクス 4 を設定するためのヒント

Google タグマネージャをカスタムピクセルとして使用する場合に Googleアナリティクス 4 (GA4) を設定するには、以下のヒントを参考にしてください。

ページ URL を整理する

GA4 がサンドボックスで実行されている場合、ページ URL に、それが動作しているサンドボックスに関する情報が含まれていることに気づくかもしれません。これらの URL からサンドボックス情報を削除したい場合は、GA4 の自動ページ追跡をオフにし、代わりに標準の 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 アナリティクス: GA4 イベントのタグタイプを使用し、イベント名を page_view に設定できます。タグタイプとイベント名を設定した後、page_location のパラメータを追加し、その値をカスタムピクセルから dataLayer に渡した値と同じ値に設定する必要があります。

拡張計測機能

Shopify のピクセルサンドボックス内で GA4 を読み込む場合、通常は自動で推測される一部のイベントは手動で設定する必要があります。たとえば、GA4 の拡張計測機能の設定の一部である外部へのリンクのクリックは、カスタムピクセルを使用する場合、セキュリティ上の理由から自動的にトリガーされません。しかし、GA4 の拡張計測機能イベントを、カスタムイベントとして自分で実装することが可能です。

以下に示すコードは、外部へのリンクのクリックを追跡する簡単な例です。

<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 の拡張イベントの命名規則に合わせてイベント名が click になるようにし、リンクのクリックを GA4 に送信する GA4 タグを作成します。

Google の拡張計測機能のどの指標でも、同様の追跡を実現できます。

カスタムピクセルのテストとデバッグ

GTM カスタムピクセルをテストする準備ができたら、Shopify Pixel Helper を使用して、追跡するすべてのイベントがエラーなくサンドボックスに追加されていることを確認してください。

また、Google Tag Assistant のページ拡張機能を使用して、ページに読み込まれている Google タグをテストすることもできます。ただし、Google Tag Assistant の「Troubleshoot tag」機能はカスタムピクセルと互換性がなく、カスタムピクセル内の Google タグや、GTM によって読み込まれるその他のピクセルを検出しません。