WP Manifestindependent plugin directory
manifest / analytics / hm-gtm

Google Tag Manager tools WP Registry grade B. Medium-severity findings · 1 findingWP RegistryMedium-severity findings · 1 findingOpen the reportB #7 in Analytics & Tracking

Google Tag Manager template tags and settings tool

★ 35stars
197kcomposer installs
3.1.4latest · 12mo ago

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/humanmade/hm-gtm/archive/refs/heads/master.zip

On Packagist as humanmade/hm-gtm:

composer require humanmade/hm-gtm
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

Google Tag Manager template tags and settings tool. Now supports Server Side GTM.

v3 Breaking Changes

There are some breaking changes in v3.0.0:

  • data layer no longer passes post.author_id by default
  • data layer post.ID renamed to post.id
  • data layer term.ID renamed to term.id
  • data layer author.ID renamed to author.id
  • data layer user.role is no longer an array but a comma separated list of roles
  • data layer post.<taxonomy> is no longer an array but a comma separated list of term names
  • data layer post.author_slug is no longer available by default, use post.author_name instead

Usage

Once the plugin is installed and activated there are 2 places you can configure:

  1. On the general settings page in admin add your container ID eg. GTM-123ABC
  2. For a multisite install you can set a network wide container ID on the network settings screen

Server Side GTM

You can optionally specify the following:

  1. Server container URL - this should the absolute path to the server container, even if you are using a reverse proxy.
  2. Custom code snippet - this is a block of code that will be added to the <head> of the page. Some server side container providers have subtle or extensive changes to the standard GTM snippet so you can override it fully if needed.
  3. Cookie preservation - you can set a special UUID cookie that lasts a long time, some server side providers allow restoring cookies set by 3rd parties or client side code in this way.

No script fallback

NOTE: This is not needed for block themes.

If your theme is a classic theme, and you wish to support the fallback iframe for devices without javascript, add the following code just after the opening <body> tag in your theme:

<?php wp_body_open(); ?>

Data Layer

GTM offers a dataLayer which allows you pass arbitrary data that can be used to modify which tags are added to your site.

This plugin adds some default information such as page author, tags and categories and provides a simple filter for adding in your own custom key/value pairs.

<?php

add_filter( 'hm_gtm_data_layer', function( $data ) {
    $data['my_var'] = 'hello';
    return $data;
} );

?>

Find out more about using the dataLayer variable here.

You can explore and view the dataLayer variables by previewing your container and using the overlay on your website.

Custom event tracking

In the block editor you can add event tracking to any block via the settings panel in the block sidebar. This calls dataLayer.push() with the event data specified.

All blocks are opted in to support this by default, but you can set block support to false with the following during block registration, or via block.json. For example:

register_block_type( 'my-plugin/my-block', [
  'supports' => [
    'gtm' => false,
  ],
) );

By default the plugin will look for elements with special data attributes in your markup and listen to the specified event to push events to the data layer.

The data attributes are:

  • data-gtm-on: enum [click|submit|keyup|focusin|focusout|mouseenter|mouseleave] The JS event to listen for, defaults to 'click'.
  • data-gtm-event: string The name or action of the event eg. "play".
  • data-gtm-category: string Optional group the event belongs to.
  • data-gtm-label: string Optional human readable label for the event.
  • data-gtm-value: number Optional numeric value associated with the event eg. product price.
  • data-gtm-fields: string Optional extra data provided as encoded JSON.
  • data-gtm-var: string Optionally override the default dataLayer variable name for this event.

Example:

<button
  data-gtm-on="click"
  data-gtm-event="play"
  data-gtm-category="videos"
  data-gtm-label="Featured Promotional Video"
>
  Play video
</button>

There is also a helper function to return these data attributes called get_gtm_data_attributes().

To deactivate custom event tracking use the following code:

add_filter( 'hm_gtm_enable_event_tracking', '__return_false' );

Releases

19 releases.

Tag
Published
3.1.4 latest
Oct 27, 2025 12mo ago
Feb 12, 2025 1 year ago
Sep 11, 2024 2 years ago
Aug 28, 2024 2 years ago
Aug 28, 2024 2 years ago
Jul 15, 2024 2 years ago
Jul 13, 2024 2 years ago
Jul 18, 2022 4 years ago
Jun 21, 2022 4 years ago
May 30, 2022 4 years ago
Feb 3, 2021 5 years ago
May 21, 2020 6 years ago
Apr 13, 2020 6 years ago
Apr 13, 2020 6 years ago
Mar 5, 2020 6 years ago
Dec 11, 2019 6 years ago
Sep 13, 2019 7 years ago
Apr 15, 2019 7 years ago
Sep 21, 2018 8 years ago

These releases are tags only. The author does not attach a packaged zip, so there are no download counts to report.

B grade

Security

Google Tag Manager tools 3.1.3 · audited by WP Registry

Medium-severity findings.

1 medium
Audited release
3.1.3
Findings
1
Worst severity
medium
Content hash
ebd771408c8f87ca578abc88…

Findings

  • medium Stored XSS in admin-bar dataLayer UI via unescaped post titles

    xss_stored

    When 'Show data layer in admin bar' is enabled, admin_bar_data_layer_ui() dumps get_gtm_data_layer() through flatten_array() and sets each value as a WP_Admin_Bar node title. Core prints those titles as HTML. flatten_array() does trim(json_encode($value), '"'), which does not HTML-escape <>. get_gtm_data_layer() copies $post->post_title raw (inc/template-tags.php), so a Contributor/Author can store <img src=x onerror=...> or a <script> in the title. The public dataLayer script path is safe (wp_json_encode); this sink is not. Reachability: option hm_gtm_show_datalayer must be on; current_user_can('hm_gtm_data_layer') must pass. view_data_layer_cap() never grants that primitive to single-site admins (it appends the same cap instead of mapping to manage_options), so default single-site installs do not render the UI. Multisite super_admins pass has_cap unconditionally, and anyone explicitly granted hm_gtm_data_layer would too. Victim is that privileged user viewing the front end of the author's post (including preview of a pending contributor post).

    inc/namespace.php:646-678

    Recommendation

    Escape both the flattened key and value with esc_html() (or wp_kses to a tight tag list) before assigning the admin-bar title. Do not use json_encode as an HTML encoder. Optionally map hm_gtm_data_layer to manage_options via user_has_cap (the current map_meta_cap filter does not actually grant the cap on single site).

WP Registry hashes the installable build and reports on that exact bytes-for-bytes copy. Embargoed findings are withheld until they are disclosed, so a clean verdict means nothing public is outstanding. WP Manifest does not audit code itself.