WordPress.org

Plugin Directory

GTM4WP-適用於 WordPress 的 Google Tag Manager(GTM)外掛

GTM4WP-適用於 WordPress 的 Google Tag Manager(GTM)外掛

外掛說明

Google Tag Manager(GTM)是 Google 提供的免費工具,讓任何人都能使用直覺的網頁使用者介面管理及部署分析與行銷代碼,以及其他程式碼片段。
如需進一步瞭解這項工具,請造訪官方網站。

此外掛會將 GTM 容器程式碼片段放置到您的 WordPress 網站上,因此您不必手動加入。
也支援多個容器,每個容器都可以有自己的環境參數、自訂網域與自訂路徑。

外掛會將頁面中繼資料與使用者資訊推送至所謂的資料層,藉此補充您的 GTM 設定。
Google 的官方說明頁面提供資料層的更多詳細資訊。

PHP 8.0 和 WordPress 6.3 是使用此外掛的必要條件。

GTM 容器程式碼放置位置

原始 GTM 容器程式碼分為兩個部分:

第一部分是加入網站每個頁面 <head> 區段的 JavaScript 程式碼片段。
這部分對啟用 GTM 的所有功能至關重要,而此外掛可協助將這部分內容
正確放置在您的網站上。

第二部分是 iframe 程式碼片段,在使用者停用 JavaScript 時可作為容錯/備援。
Google 建議為了獲得最佳效能,將這段程式碼片段直接放在每個頁面開頭 <body> 標籤之後。

雖然放在程式碼較後方並不理想,但仍可運作。此外掛提供第二段程式碼片段的放置位置選項。

如果您的 WordPress 佈景主題與 WordPress 5.2 新增的功能相容,此外掛便會將第二段程式碼片段放置在正確位置。
Genesis、GeneratePress、Elementor、Oxygen Builder 與 Beaver Builder Theme 的使用者也會正確放置該程式碼。
若要使用這項功能,請在外掛選項中將相容性模式設為關閉。

其他使用者可以使用自訂 PHP 程式碼(「手動撰寫」選項)放置第二段程式碼片段,或選取所謂的「頁尾」選項
將程式碼加入頁面較下方的位置(這不是建議的方式,但仍可運作)。

包含基本資料

  • 文章/頁面標題
  • 文章/頁面日期
  • 文章/頁面分類代稱
  • 文章/頁面標籤代稱
  • 文章/頁面作者 ID 與名稱
  • 文章/頁面 ID
  • 文章類型
  • 文章格式
  • 目前頁面及目前分類/標籤/分類法中的文章數量
  • 與任何文章類型相關的自訂分類法詞彙
  • logged in status
  • logged in user role
  • 已登入使用者 ID(用於在 Google Analytics 中追蹤跨裝置行為)
  • 已登入使用者的電子郵件地址(提供未雜湊與 SHA256 雜湊值供追蹤使用)
  • 已登入使用者的建立日期
  • 網站搜尋資料
  • 網站名稱與 ID(適用於 WordPress 多站台執行個體)
  • 訪客的 IP 位址(使用前請先取得訪客的明確同意)
  • 來自 PublishPress Authors 的文章作者資料,包括共同作者與客座作者

內容與互動資料

可選的頁面變數,可協助進行行為追蹤與 Google Analytics 4 內容分組:

  • 內容字數與預估閱讀時間
  • 最後修改日期與內容年齡(天數)
  • 留言數量與留言狀態
  • 頁面範本、是否有特色圖片、頁面階層與置頂旗標
  • 主要分類(從 Yoast SEO 或 Rank Math 偵測)
  • 頁面語言(從 WPML 或 Polylang 偵測)

瀏覽器/作業系統/裝置資料

  • 瀏覽器資料(名稱、版本、引擎)
  • 作業系統資料(名稱、版本)
  • 裝置資料(類型、製造商、型號)

資料會在瀏覽器中使用 User-Agent Client Hints 收集,並以 gtm4wp.deviceData 事件推送。
請注意,Safari 和 Firefox 提供的詳細資訊少於以 Chromium 為基礎的瀏覽器。

Media player events

追蹤使用者與任何嵌入媒體的互動:

  • YouTube
  • Vimeo
  • Soundcloud
  • HTML5 音訊與視訊
  • Dailymotion
  • Mixcloud
  • Cloudflare Stream
  • Wistia
  • JW Player
  • VideoPress
  • Spotify
  • Twitch

您可以選擇在媒體播放器載入、媒體播放、暫停或停止時觸發資料層事件,
也可以選擇在使用者觀看進度達到媒體播放時間的 10、20、30、…、90、100% 時觸發。每個事件也會填入 Google Tag
Manager 內建的影片變數(影片狀態、影片網址、影片標題、影片提供者、影片時間長度、影片目前時間、
影片百分比、影片是否可見)。

支援使用 WordPress 內建 oEmbed 功能嵌入的媒體,以及大多數其他媒體外掛與複製/貼上的嵌入程式碼進行追蹤。
頁面載入後插入的播放器(例如在快顯視窗、燈箱或透過 AJAX 插入)也可以透過開啟選用的「追蹤動態插入的播放器」設定來追蹤。

代碼限制:使用允許清單與封鎖清單限制 Tag Manager 的代碼、觸發條件與變數

為提高網站安全性,您可以使用允許清單或封鎖清單限制代碼、觸發條件和變數。
無論您的 GTM 設定為何,您都可以禁止特定代碼觸發,或禁止使用特定類型的變數。

如果與您的 GTM 帳戶關聯的 Google 帳戶遭到入侵,攻擊者便可能在不存取主機伺服器上的網站程式碼的情況下,輕易在您的網站上執行惡意軟體。透過封鎖自訂 HTML 代碼、自訂 JavaScript 變數與沙箱化指令碼(自訂代碼與變數範本),您可以保護 Tag Manager 容器。

Integration

適用於 WordPress 的 Google Tag Manager 可與多個熱門外掛整合。未來還會加入更多整合功能!

  • Contact Form 7:無論表單提交結果為何(郵件已傳送、郵件傳送失敗、偵測到垃圾郵件、輸入內容無效、提交中止或未接受條款),都會觸發事件。
    也可以選擇推送 Google Analytics 4 建議的表單事件(form_start、form_submit、generate_lead)
  • WooCommerce:
    • GA4 電子商務的實作
    • 支援購物車、結帳、迷你購物車、商品集合與交叉銷售區塊,而不僅限於以傳統簡碼為基礎的頁面
    • Google Ads 購買事件中的 Enhanced Conversions 使用者資料
    • 與高效能訂單儲存(HPOS)相容
    • 不支援促銷活動,因為 WooCommerce 目前尚未提供這項功能
    • 不支援退款
  • CheckoutWC:可選擇支援其多步驟結帳範本
  • PublishPress Authors:頁面變數中的共同作者與客座作者資料
  • AMP:在頁面的 AMP 版本載入 AMP 容器
  • Google Consent Mode v2:執行帶有特定同意旗標的「default」指令,以便與未經認證的同意管理平台(CMP)及外掛整合
  • Cookiebot:必要時使用自動 Cookie 封鎖模式
  • Axeptio:載入 Axeptio SDK,並將每次同意狀態變更推送至資料層
  • CookieYes:訪客的同意狀態變更時推送資料層事件

伺服器端容器

如果您使用伺服器端容器,
您可以輸入自訂網域名稱與自訂路徑,從該處載入 gtm.js。兩者都可以個別套用到每個容器,因此您可以在同一個網站上混用
伺服器端容器與標準容器。

快取安全資料層

(實驗性功能,預設為關閉)

在使用整頁快取的網站上(LiteSpeed、WP Rocket、Varnish、Cloudflare APO),為一名訪客產生的 HTML 也會提供給其他所有人。
如此一來,任何寫入資料層的訪客專屬值都可能洩漏給其他訪客——典型例子是編輯登入時產生的頁面遭到快取,之後傳送給匿名訪客,而該編輯的電子郵件地址與角色仍留在資料層中。

啟用此選項後,完全不會將訪客或工作階段資料寫入可快取的 HTML。
這些值會改在瀏覽器中傳送,並使用相同的資料層變數名稱,因此您現有的 Google Tag Manager 設定仍可運作。

匯出與匯入設定

您可以將所有外掛設定匯出為 JSON 檔案,並在另一個網站上匯入,方便在多個網站套用相同設定。
匯入的檔案會視為不受信任的資料,且每個值在儲存前都會經過驗證。

排除特定使用者角色的追蹤

您可以設定當具有特定角色的使用者造訪前端時,哪些使用者角色需要排除追蹤。
對該使用者而言,這會完全停用容器程式碼。

暫存與開發網站

容器可以限制為僅在正式環境中運作,因此網站的複製版或預備版不會將資料傳送至正式環境的 Google Tag Manager 容器。
這依賴 WordPress 的 WP_ENVIRONMENT_TYPE 設定。

開發人員專用

2.0 版本是完整的物件導向重寫。每項功能都是一個模組,第三方外掛可以透過 gtm4wp_register_modules 動作註冊自己的模組。
1.x 版本的所有公開範本函式、篩選器與動作名稱、wp-config 常數及選項儲存鍵都保持不變,因此現有整合仍可正常運作。

螢幕擷圖

安裝方式

  1. 將 duracelltomi-google-tag-manager-for-wordpress 上傳至 /wp-content/plugins/ 目錄
  2. 透過 WordPress 中的「外掛」選單啟用外掛
  3. 前往設定/Google Tag Manager,輸入您的 Google Tag Manager 容器 ID,並設定其他選項

常見問題集

如何…

Google Tag Manager 各種設定與實作方式的教學,請參閱外掛網站:
https://gtm4wp.com/setup-gtm4wp-features

WooCommerce 中 PayPal/第三方付款閘道交易未在 Google Analytics 中追蹤

PayPal 和其他一些第三方付款閘道預設不會在交易成功後將使用者重新導向回您的網站。
這些付款閘道會提供返回您網站的路徑,但使用者可能在抵達感謝頁面前關閉瀏覽器
(感謝頁面也稱為「已收到訂單」頁面)。這表示 Google Analytics 代碼及其他任何代碼都沒有機會觸發。

在付款閘道設定中啟用自動返回。這會指示付款閘道在付款後顯示簡短的資訊頁面,
並將使用者重新導向回您的網站。這會提高交易追蹤的準確度與頻率。

WooCommerce 未追蹤購買事件

如果您使用的第三方外掛以不使用 WooCommerce 整合掛鉤的方式修改預設的已收到訂單頁面,就可能發生這種情況。
您可以停止使用該外掛,或請其作者透過支援 woocommerce is_order_received_page 函式與 woocommerce_thankyou 動作,更貼近預設已收到訂單頁面的行為。

自 2.0 版本起,此外掛也提供兩個設定,能在不變更第三方外掛的情況下處理這個問題:「自訂已收到訂單(感謝)頁面」會在自訂確認頁面上觸發購買事件,而「可靠的購買追蹤」會在同一瀏覽器工作階段中,於客戶檢視的下一個頁面傳送遺漏的購買事件。兩者都會去重,因此一筆訂單絕不會重複計算。

為什麼沒有封鎖代碼/變數類別的選項

雖然 Google 建議使用類別封鎖代碼與變數,但人們很難知道哪些代碼與變數會受到影響。因此,我在代碼限制分頁中採用個別代碼與變數,而不是類別。

關於變數:請確保它們不屬於任何關鍵代碼,因為封鎖這類變數會使那些代碼失效。

如何在 Google Tag Manager 中追蹤捲動事件?

Google Tag Manager 原生支援以百分比或像素為基礎的基本捲動深度追蹤。在您的容器中新增「Scroll Depth」觸發條件,並用它觸發 Google Analytics 4 及/或 Google Ads 再行銷/轉換代碼。
(此外掛原本的捲動追蹤功能已在 2.0 中移除,改用 GTM 內建功能。)

我使用頁面快取。訪客資料會在不同訪客之間洩漏嗎?

是的,任何整頁快取都確實存在這項風險,這並非此外掛特有:為一名訪客產生的 HTML 會儲存起來並提供給其他所有人。
如果將訪客專屬值(電子郵件地址、使用者角色、IP 位址)寫入資料層,快取副本就會包含觸發快取的那名訪客的值。

開啟「快取安全資料層」選項即可避免此問題。啟用後,不會將任何訪客或工作階段資料寫入可快取的 HTML;這些值會改在瀏覽器中傳送,並使用相同的資料層變數名稱。

為什麼此外掛要載入多個獨立的 JavaScript 檔案,而不是一個檔案?

每項追蹤功能(WooCommerce、每個媒體播放器、Contact Form 7、裝置資料等)都是獨立的小型
JavaScript 檔案,外掛只會載入頁面實際需要的檔案——例如 YouTube 追蹤器
只會在嵌入 YouTube 影片的頁面上載入,而且使用「defer」策略,因此不會阻擋畫面轉譯。
這些檔案已由外掛的建置流程完成最小化。

將多個檔案合併為一個檔案的工作,刻意交由快取/效能外掛(WP Rocket、Autoptimize、
LiteSpeed Cache 等)處理;這些外掛可以依據您的主機與 HTTP 設定,以適合整個網站的方式合併指令碼。
在現代 HTTP/2 主機上,許多個有條件載入的小型檔案通常與一個合併檔案的效能相當。
(1.x 會合併自己的指令碼;2.0 則委派給其他外掛。)

使用者評論

2025 年 10 月 29 日
We've been using GTM4WP for all of our clients websites and it's been super reliable. The eCommerce tracking integration has been a huge time saver for us. Huge thank you for this plugin Thomas Geiger!
2025 年 8 月 13 日 1 則留言
I am writing this review to save other developers and site owners the immense amount of time I have just lost. I needed to implement standard GA4 e-commerce tracking on a professional WordPress/WooCommerce site. Based on its popularity and countless recommendations, I chose GTM4WP as the solution to generate the required dataLayer. Unfortunately, after days of intensive, professional-level debugging, I discovered that the plugin was completely non-functional in my specific—yet very common—environment. The plugin failed at its two most essential tasks: GTM Snippet Injection: The plugin's most basic feature—injecting the GTM container script into the website's <head> and <body>—did not work at all. The script was simply not present. I had to bypass this functionality entirely and inject the code manually using another method (Code Snippets) just to get our GTM container to load. E-commerce dataLayer Generation (The Deal-Breaker): This is the primary reason anyone uses this plugin. After successfully loading our GTM container manually, I ran a full test purchase. By analyzing the GTM debug mode and the site's dataLayer object, I can confirm that GTM4WP completely failed to generate the purchase event and its corresponding ecommerce object on the WooCommerce order confirmation page. It produced absolutely nothing. My Technical Environment (Please read this before you install):To help others, here is the stack where the plugin failed. This is likely the source of the conflict: CMS: WordPress E-commerce: WooCommerce Theme: Hello Elementor (using a child theme) Page Builder: Elementor Pro Key Detail: I am using Elementor Pro to customize the WooCommerce page templates, including the "Thank You" / "Order Received" page. Conclusion: My conclusion is that GTM4WP is fundamentally incompatible with themes or page builders that override default WooCommerce templates—a standard practice for virtually any custom-designed website today. Because it cannot handle this common scenario, the plugin proved to be entirely useless for my project. While it may work on simple sites with basic, unmodified themes, it is not a reliable solution for professional, customized builds. The time and effort wasted diagnosing this incompatibility were substantial. I cannot recommend this plugin and strongly advise users with a similar tech stack to seek a manual implementation from the start.
2025 年 3 月 10 日
Em vários sites que o plugin está instalado, após alguma atualização, o menu mobile de alguns sites não abre.
2024 年 12 月 2 日
I’m disappointed with the support for this plugin. I submitted a question over a week ago, but I have yet to receive any response from the support team. While the plugin itself may work fine, having reliable support is critical, especially when issues arise. Unfortunately, the lack of responsiveness has made it difficult to trust this plugin for long-term use. I hope the team improves their support response time in the future.
閱讀全部 155 則使用者評論

參與者及開發者

以下人員參與了開源軟體〈GTM4WP-適用於 WordPress 的 Google Tag Manager(GTM)外掛〉的開發相關工作。

參與者

〈GTM4WP-適用於 WordPress 的 Google Tag Manager(GTM)外掛〉外掛目前已有 15 個本地化語言版本。 感謝全部譯者為這個外掛做出的貢獻。

將〈GTM4WP-適用於 WordPress 的 Google Tag Manager(GTM)外掛〉外掛本地化為台灣繁體中文版

對開發相關資訊感興趣?

任何人均可瀏覽程式碼、查看 SVN 存放庫,或透過 RSS 訂閱開發記錄。

變更記錄

2.0.5

  • Fixed: the data layer initialisation block no longer contains the word gtag. Since 2.0.3, a JavaScript delay plugin with gtag on its keyword list, such as Flying Scripts, delayed the whole block and the browser console showed dataLayer is not defined. The Google tag developer ID is still set.
  • Fixed: a page with no data layer variables to report no longer pushes an empty array into the data layer; dataLayer_content is then an empty object and is not pushed. Content that is pushed is always an object, never an array, which GTM would read as a command.

2.0.4

  • Fixed: on the classic WooCommerce checkout, an error in the plugin’s checkout step tracking could stop the order from being submitted the normal way, so a gateway that adds card details in the browser, such as Stripe, rejected it. Tracking errors can no longer interrupt the checkout or a variation selection, and still show in the browser console. (#472)

2.0.3

  • Fixed: on a store that displays prices including tax, every cart line in view_cart, begin_checkout and the cart content carried a discount equal to the line’s tax, with no coupon or sale involved, so GA4 reported a share of the revenue as a discount on every order. The total side of the discount calculation read a key WooCommerce never writes on a cart item, so only the subtotal side gained the tax. An undiscounted line carries no discount again. Stores displaying prices excluding tax were never affected, and neither was the purchase event.
  • Fixed: on a store whose product page runs the newer WooCommerce blocks (built on the WordPress Interactivity API), an add to cart the store refused could still be reported when a related-products or grid add was clicked within the next ten seconds, so add_to_cart fired twice for a single item. A list add now supersedes whatever the product form still had waiting.
  • Fixed: on the same stores, a cart read over the Store API that came back with something other than a cart could report every item as removed; it is now treated as no reading at all.
  • Fixed: a purchase was never reported when the customer reached the order received page while the order was still Pending payment, and “Reliable purchase tracking” did not recover it. This happens with a payment provider that confirms the payment through a webhook, such as the WooCommerce Stripe Gateway with webhooks enabled: the customer is redirected back a moment before the confirmation arrives, so the plugin sees a status that is not in “Order statuses that trigger the purchase event” and withholds the event, and the later change to Processing happens in a request the plugin cannot connect to the customer’s browser. With “Reliable purchase tracking” on, such an order is now remembered in the customer’s session and checked again on the pages they view next; the purchase is reported once, as soon as the status has become one of the tracked statuses, and the order is flagged as tracked at that moment. The wait ends by itself when the order is cancelled, refunded or fails, or once the order is older than the “Maximum order age” (30 minutes by default). Pending payment itself is still not counted as a sale, and every existing duplicate guard applies unchanged.
  • Fixed: with a custom data layer variable name, the Google Consent Mode default block pushed its defaults to dataLayer instead of the configured variable, so the container never received them and the consent defaults did not apply. The block now uses the configured name and stays out of WP Rocket’s combined JavaScript.
  • Fixed: on a subdomain multisite, or any site defining COOKIE_DOMAIN, the cache-safe data layer could not clear its event cookie after a one-shot event was delivered, so every later page view made a needless request. The cookie is now host-only.
  • Fixed: a login or registration event was lost when the visitor’s next request was a REST call (the WooCommerce Store API, a headless front end) rather than a page view.
  • Fixed: a user account created by a logged-in administrator through the REST API or an admin app fired gtm4wp.userRegistered in the administrator’s own browser instead of nowhere.
  • Fixed: the form interaction and Contact Form 7 events reported a hidden action field instead of the form’s URL when the form contained a field named action, id or target.
  • Fixed: the browser, OS and device data script reported all three signals when a page optimiser removed its inline configuration, ignoring which of them were enabled. It now reports nothing in that case.
  • Fixed: with the cache-safe data layer, a logged-in visitor served a cached page kept requesting their visitor data on every page view after WordPress refused the page’s nonce. When WordPress itself reports the rejected nonce, the data is requested once more anonymously and that page stops asking.
  • Updated: tested with WooCommerce 11.1.2.
  • Added: the data layer initialisation block carries the plugin’s Google tag developer ID, gtag(‘set’, ‘developer_id.dNGJiYT’, true), so Google can tell which platform installed the tag. It identifies GTM4WP only and adds nothing about the site or its visitors.

2.0.2

  • Updated: tested with WooCommerce 11.1.
  • Fixed: a product category or brand name containing an ampersand reached the data layer as “Shirts & Ties” rather than “Shirts & Ties”, which is what GA4 then reported. WordPress encodes term names when they are saved, and the plugin now decodes that once when it reads the name.
  • Fixed: item_id, sku and the dynamic remarketing id are now always strings. A product with no SKU falls back to its numeric id, and that fallback was written into the data layer as a number while the same fields are strings on every product that has a SKU. Check your GTM setup if a trigger or variable compares one of those fields against a number.

  • Fixed: the begin_checkout event was missing on stores where WooCommerce reports the checkout page as the cart page as well, which happens when a plugin or a theme forces that decision or when a cart shortcode is left in the checkout page content. Such a checkout page pushed view_cart and begin_checkout never fired anywhere. The checkout is now decided first, so a page reported as both is treated as the checkout page. The order-received page is recognized ahead of both on both halves as well: on such a store the thank-you page used to be taken for the cart page by the block tracker, which loaded there in its cart context in place of the regular tracker.

  • Fixed: add_to_cart and remove_from_cart never fired on a store whose product and cart blocks are built on the WordPress Interactivity API, the newer form of the WooCommerce blocks. Product pages now report the add once WooCommerce confirms that the item reached the cart, and cart changes made anywhere else are read back from the WooCommerce Store API and reported the same way as on a store using the older blocks. Variable products are covered as well: the interactive form publishes no variation data the plugin could read, so the event is completed from the cart line the add creates, which carries the data of the variation itself.
  • Fixed: a GTM4WP_HARDCODED_* value in wp-config.php that ends in a newline character – typically an untrimmed file read feeding the define() – is now rejected and named in the existing admin notice, like any other malformed value. Previously a gtm_auth/gtm_preview value with a trailing newline passed validation, the newline reached the container loader script and broke the whole block, so the container silently did not load with nothing pointing at wp-config. A container ID with a trailing newline used to be silently repaired and kept working; it is now reported the same way instead – remove the stray newline from the define() and the override applies again.
  • Fixed: a page whose author cannot be resolved no longer takes the whole page down with a critical error when PublishPress Authors is active. PublishPress reports such an author as no author at all, which happens when the author’s user account has been deleted, and the plugin passed that straight into the code reading the author name and ID, where it ended in a fatal error. The WooCommerce My Account page is the one most likely to hit it, since it is often the page nobody keeps an author on. An author that cannot be resolved is now skipped, so the page renders and the author variables are simply left out of the data layer, and a post that has one real author next to an unresolvable one is treated as having a single author.

2.0.1

  • 已修正:在區塊版商店中,開啟購物車頁面會在沒有互動的情況下將 add_shipping_info 和 add_payment_info 推送至資料層,接著兩個事件又會在結帳頁面再次觸發。區塊追蹤器原本是透過是否存在 WooCommerce 付款資料儲存區來區分兩個頁面,而 WooCommerce 也會在購物車頁面註冊該儲存區;現在購物車與結帳頁面各自會取得正確的上下文,結帳步驟事件也只會在結帳頁面觸發。
  • 已修正:設定畫面空白時,不再對空白原因保持沉默。某些廣告與隱私封鎖器的篩選清單會封鎖外掛資料夾下的所有內容,包括在瀏覽器中建置設定畫面的檔案,導致設定頁面空白且沒有任何說明。現在如果設定應用程式無法啟動,幾秒後便會顯示靜態通知,說明最可能的原因與因應方式(在網站管理區域暫停封鎖器,或為其加入例外)。

2.0.0

Major rewrite of the plugin. Please read the announcement post on gtm4wp.com before upgrading. This section is a summary; wordpress.org truncates a changelog after 5,000 words, so the complete list of 2.0.0 changes with every detail lives in the changelog on GitHub: https://github.com/duracelltomi/gtm4wp/blob/master/CHANGELOG.md

  • Changed: complete object-oriented rewrite. Every feature is a module that third-party plugins can extend. All public template functions, filter and action names, wp-config constants and the options storage key are unchanged, so existing integrations keep working.
  • Changed: minimum requirements raised to PHP 8.0 and WordPress 6.3.
  • Added: modern React-based settings screen with left pane navigation, tabbed option groups, option search, inline validation, a help link on every option, bookmarkable addresses and settings export and import.
  • Added: every Google Tag Manager container ID has its own environment parameters, custom domain and custom path; a production-only kill switch for staging copies; validation of the hard-coded wp-config constants with a warning that names the wrong one.
  • Changed: the tag restriction list is written under the documented gtm.allowlist / gtm.blocklist keys, the entity list is refreshed from Google’s documentation, and blocklist mode no longer blocks every tag.
  • Added: cache-safe data layer mode for sites behind a full page cache, with the visitor specific values fetched separately.
  • Changed: GA4 e-commerce tracking reworked for WooCommerce: reliable purchase tracking, custom order received page, order statuses that trigger the purchase event, list attribution across the funnel, block cart and checkout support, Store API data for the block trackers, and numeric-looking text values no longer turned into numbers.
  • Added: an Axeptio consent management platform integration and a CookieYes consent bridge; the WebToffee v2.x integration is deprecated. Media events cover more embedded players, and a player’s script is requested only on pages that contain one of its embeds.
  • Removed: the weather and geo data features and the scroll tracking feature (use the built-in Scroll Depth trigger of Google Tag Manager instead). Browser, OS and device data is now collected in the browser with User-Agent Client Hints, which replaces the bundled WhichBrowser library.
  • Deprecated: the “YouTube video events” option (Google Tag Manager ships a native YouTube Video trigger) and the $gtp4wp_plugin_url, $gtp4wp_plugin_basename and $gtp4wp_script_path global variables, which will be removed in 2.1.

1.22.5

A maintenance release for the 1.x line. 1.22.4 was intended to be the last one before GTM4WP 2.0; this release exists because the fixes below are worth shipping to 1.x users rather than holding for 2.0.

  • Fixed (security): hardened how the hidden product-data attribute is built for WooCommerce product lists and cart remove links, so that no product field value can affect the surrounding HTML. Certain values were not guaranteed to stay inside the attribute.
  • Fixed: when a custom X-Forwarded-For header is configured as the visitor IP source, all entries of the header are now evaluated. Only the first entry was ever considered, because the remaining ones were not trimmed of the space that follows each comma and therefore failed IP validation.
  • Fixed: the custom visitor IP header name is now validated in full. The check accepted any value that contained at least one valid character, so an invalid header name passed validation and was then simply never found. Setups with a working header name are unaffected.

1.22.4

  • Fixed: hardened how values are encoded into the data layer and into inline script blocks. Script blocks are no longer HTML entity decoded after sanitization, and every value written into a script context is now JSON encoded with the full set of hex escaping flags. Thanks cyn
  • Fixed: nonce attribute should not be sanitized. Thanks oxyc
  • Fixed: avoid warnings when saving settings. Thanks mircobabini
  • Fixed: only float number is returned in JavaScript processing. Thanks gkipouros
  • Updated: only load plugin files on frontend or on admin when the admin user has sufficient permissions.
  • Updated: WooCommerce 10.4+ compatibility – the checkout inline script no longer uses the deprecated wc_enqueue_js() function. The old function is still used as a fallback on setups where the tracker script is loaded in the page head.
  • Updated: WordPress and WooCommerce compatibility.
  • Deprecated: geo data (ipstack.com) and weather data (OpenWeatherMap) integrations. They still work in this version but will be removed in GTM4WP 2.0. There is no direct replacement: collect this data in Google Tag Manager or with a dedicated service instead.
  • Deprecated: scroll tracking. It still works in this version but will be removed in GTM4WP 2.0. Use the Scroll Depth trigger built into Google Tag Manager instead.
  • Deprecated: the “Custom tag/variable templates” blacklist option, plus the Universal Analytics and Mouseflow entries of the tag blacklist. These will be removed in GTM4WP 2.0.
  • Added: a dismissable admin notice announcing the upcoming GTM4WP 2.0 release. If your site uses one of the deprecated features above, the notice names it.

1.22.3

  • Fixed: when timeout for the select_item event with WooCommerce is set to 0, plugin does not halt the browser from loading the product page
  • Fixed: properly reading timeout for select_item eventCallback

1.22.2

  • Fixed: purchase event was not fired when is_order_received_page() WooCommerce tag was not supported by the template and the fallback method had to activate.

1.22.1

  • Fixed: yet another fix to the purchase tracking. Thanks Khnaz35

Older releases are listed in the full changelog on GitHub: https://github.com/duracelltomi/gtm4wp/blob/master/CHANGELOG.md