Integrate Google Tag Manager into WordPress and generate an advanced, customizable dataLayer for publishers, blogs, and digital media. Get detailed insights about reader behavior and maximize your monetization.
dataLayer Parameters
Initial Configuration
Manual Code Lines
Free
Everything you need for advanced content tracking
Automatically generates a complete dataLayer with detailed information about content: hierarchical categories, tags, author, format, multimedia, and more.
Customize separators, CSS selectors, which dataLayer parameters are sent, and the scroll/time values the plugin exposes for your GTM engagement setup.
Mark posts as premium and set a content type (trend, seasonal, or evergreen) from the WordPress editor. Differentiated tracking for monetization and editorial analytics.
Download a complete Google Tag Manager container wired to DataLayer events view_post_ready (first push from the plugin) and read_post_ready (fired in GTM when your scroll and timer conditions are met), with GA4 mapping ready to use.
Automatically detects multimedia, reading time, used editor, and traffic origin without manual configuration.
Optimized code for performance, data validation, security nonces, and full compatibility with WordPress.
1 Default engagement rule in the sample container: 30s + 90% scroll. The plugin also sends
gtm4pubs_event_scroll_percent and gtm4pubs_event_delay_ms on the first push so GTM can stay in sync with your WordPress settings.
Exclusive advantages for content sites
Set up, configure, and start tracking your content in just 5 minutes. No technical complications at all.
Get granular, actionable data about your readers' behavior and engagement with every piece of content.
The plugin pushes view_post_ready with configurable scroll % and delay. You configure read_post_ready in GTM using those values or your own rules.
Boost your monetization strategy with precise, real-time data about premium content and content type (trend, seasonal, evergreen).
Seamlessly integrates with Google Analytics 4 and BigQuery for advanced, custom content performance analysis.
Everything is generated automatically by the plugin. No need to write or maintain any manual code.
Works with all WordPress themes. Use customizable CSS selectors to adapt to any design or layout.
Join our active Telegram group to get help, share experiences, and connect with other publishers worldwide.
Analyze which editor generates better engagement
Detects posts created with Elementor Page Builder
Detects posts created with Divi Builder
Detects posts created with WP Bakery Page Builder
Detects posts created with the native block editor
gtm4pubs_editor - Contains the detected editor name (elementor, divi, wp_bakery, gutenberg, other)
See how tracking works in action
{
"event": "view_post_ready",
"gtm4pubs_categories": "technology>artificial-inteligence|marketing>analytics",
"gtm4pubs_tags": "ai,chatgpt,productivity,tools",
"gtm4pubs_author_id": 1,
"gtm4pubs_post_id": 1234,
"gtm4pubs_format": "standard",
"gtm4pubs_multimedia": "image,video,gallery",
"gtm4pubs_word_count": 2500,
"gtm4pubs_reading_time": 13,
"gtm4pubs_publication_date": "2024-01-15",
"gtm4pubs_update_date": "2024-01-20",
"gtm4pubs_sticky": 0,
"gtm4pubs_origin": "category",
"gtm4pubs_event_scroll_percent": 90,
"gtm4pubs_event_delay_ms": 30000,
"gtm4pubs_access": "premium",
"gtm4pubs_type": "evergreen",
"gtm4pubs_comments_count": 45,
"gtm4pubs_editor": "gutenberg",
"gtm4pubs_related": 1
}
This dataLayer is generated automatically on each individual post page. Fields like gtm4pubs_type appear when that parameter is enabled in plugin settings.
Complete access without hidden costs
Forever
Find answers to common questions and see advanced BigQuery analysis examples
Note: The plugin requires WordPress 5.0+ and PHP 7.4+.
Important: The container listens for DataLayer events view_post_ready and read_post_ready and maps post parameters to GA4 (often as view_post / read_post event names in GA4, depending on the imported tags).
gtm4pubs_type, etc.). You can map these variables in your GA4 configuration tag or in custom events. The included container already provides a recommended setup for most publishers.
read_post_ready (and your GA4 tag if it listens to that event). Align them with gtm4pubs_event_delay_ms and gtm4pubs_event_scroll_percent from the first dataLayer push, or use your own thresholds.
GTM4Publishers is designed to work alongside other Tag Manager plugins, but there are some considerations:
Note: The plugin uses unique variable names (gtm4pubs_*) to minimize conflicts with other plugins.
Yes! The plugin is designed to work perfectly with Google Analytics 4 and BigQuery. Once you have GA4 exporting data to BigQuery, you can use the dataLayer parameters (like categories, access, editor, etc.) for advanced analysis.
Below you'll find a comprehensive collection of BigQuery example queries that cover:
gtm4pubs_type)These queries are ready to use and will help you gain valuable insights into your content performance and user behavior.
view_post / read_post match the sample GTM container’s GA4 tags; your DataLayer uses view_post_ready and read_post_ready before GTM maps them.
Analyze which content categories generate the most engagement and read events.
SELECT
REGEXP_EXTRACT(event_params.value.string_value, r'([^>]+)$') as main_category,
COUNT(CASE WHEN event_name = 'view_post' THEN 1 END) as views,
COUNT(CASE WHEN event_name = 'read_post' THEN 1 END) as reads,
ROUND(COUNT(CASE WHEN event_name = 'read_post' THEN 1 END) * 100.0 /
COUNT(CASE WHEN event_name = 'view_post' THEN 1 END), 2) as engagement_rate
FROM `your-project.analytics_123456789.events_*`,
UNNEST(event_params) as event_params
WHERE event_params.key = 'gtm4pubs_categories'
AND _TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
GROUP BY main_category
ORDER BY engagement_rate DESC
Compare engagement rates between premium and public content to optimize monetization strategy.
SELECT
event_params.value.string_value as access_type,
COUNT(CASE WHEN event_name = 'view_post' THEN 1 END) as views,
COUNT(CASE WHEN event_name = 'read_post' THEN 1 END) as reads,
ROUND(COUNT(CASE WHEN event_name = 'read_post' THEN 1 END) * 100.0 /
COUNT(CASE WHEN event_name = 'view_post' THEN 1 END), 2) as engagement_rate
FROM `your-project.analytics_123456789.events_*`,
UNNEST(event_params) as event_params
WHERE event_params.key = 'gtm4pubs_access'
AND _TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
GROUP BY access_type
ORDER BY engagement_rate DESC
Compare which content editor (Elementor, Divi, WP Bakery, Gutenberg) generates better user engagement.
SELECT
event_params.value.string_value as editor,
COUNT(CASE WHEN event_name = 'view_post' THEN 1 END) as views,
COUNT(CASE WHEN event_name = 'read_post' THEN 1 END) as reads,
ROUND(COUNT(CASE WHEN event_name = 'read_post' THEN 1 END) * 100.0 /
COUNT(CASE WHEN event_name = 'view_post' THEN 1 END), 2) as engagement_rate
FROM `your-project.analytics_123456789.events_*`,
UNNEST(event_params) as event_params
WHERE event_params.key = 'gtm4pubs_editor'
AND _TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
GROUP BY editor
ORDER BY engagement_rate DESC
Compare engagement by content type using the gtm4pubs_type parameter (replaces the legacy gtm4pubs_evergreen flag for new setups).
SELECT
event_params.value.string_value as content_type,
COUNT(CASE WHEN event_name = 'view_post' THEN 1 END) as views,
COUNT(CASE WHEN event_name = 'read_post' THEN 1 END) as reads,
ROUND(COUNT(CASE WHEN event_name = 'read_post' THEN 1 END) * 100.0 /
COUNT(CASE WHEN event_name = 'view_post' THEN 1 END), 2) as engagement_rate
FROM `your-project.analytics_123456789.events_*`,
UNNEST(event_params) as event_params
WHERE event_params.key = 'gtm4pubs_type'
AND _TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
GROUP BY content_type
ORDER BY engagement_rate DESC
Identify which traffic sources bring the most engaged users by calculating engagement rates.
SELECT
traffic_source,
COUNT(*) as total_sessions,
COUNT(CASE WHEN event_name = 'read_post' THEN 1 END) as read_events,
ROUND(COUNT(CASE WHEN event_name = 'read_post' THEN 1 END) / COUNT(*) * 100, 2) as engagement_rate
FROM `your-project.analytics_123456789.events_*`
WHERE event_name IN ('page_view', 'read_post')
AND _TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
GROUP BY traffic_source
HAVING total_sessions > 100
ORDER BY engagement_rate DESC
Compare how different types of multimedia content perform in terms of user engagement.
SELECT
event_params.value.string_value as post_type,
COUNT(CASE WHEN event_params.value.string_value = 'true' THEN 1 END) as has_video,
COUNT(CASE WHEN event_params.value.string_value = 'true' THEN 1 END) as has_audio,
COUNT(CASE WHEN event_params.value.string_value = 'true' THEN 1 END) as has_gallery,
COUNT(*) as total_posts,
AVG(read_time) as avg_read_time,
COUNT(CASE WHEN event_name = 'read_post' THEN 1 END) as total_reads
FROM `your-project.analytics_123456789.events_*`,
UNNEST(event_params) as event_params
WHERE event_name = 'read_post'
AND event_params.key IN ('gtm4pubs_has_video', 'gtm4pubs_has_audio', 'gtm4pubs_has_gallery')
AND _TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
GROUP BY post_type, has_video, has_audio, has_gallery
ORDER BY avg_read_time DESC
Find the most engaging tags to understand what topics resonate best with your audience.
SELECT
event_params.value.string_value as post_tags,
COUNT(*) as total_posts,
AVG(read_time) as avg_read_time,
COUNT(CASE WHEN event_name = 'read_post' THEN 1 END) as total_reads
FROM `your-project.analytics_123456789.events_*`,
UNNEST(event_params) as event_params
WHERE event_name = 'read_post'
AND event_params.key = 'gtm4pubs_tags'
AND event_params.value.string_value IS NOT NULL
AND _TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
GROUP BY post_tags
ORDER BY avg_read_time DESC
LIMIT 15
Understand how user engagement varies across different device types.
SELECT
device.category as device_type,
COUNT(*) as total_sessions,
AVG(read_time) as avg_read_time,
COUNT(CASE WHEN event_name = 'read_post' THEN 1 END) as read_events
FROM `your-project.analytics_123456789.events_*`
WHERE event_name IN ('page_view', 'read_post')
AND _TABLE_SUFFIX >= FORMAT_DATE('%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
GROUP BY device_type
ORDER BY avg_read_time DESC
Real experiences from publishers
"GTM4Publishers revolutionized our tracking. In 5 minutes we had a complete dataLayer that gave us insights we'd never had before."
"Premium and content-type signals in the dataLayer helped us optimize our monetization strategy. The data is incredibly accurate."
"The pre-configured GTM container saved us hours of work. Everything worked perfectly from the first moment."
Need personalized help, training, or consulting to get the most out of GTM4Publishers and your analytics?
This plugin is completely free, but your support helps us dedicate more time to:
Advanced analytics and tracking capabilities
Faster responses and detailed assistance
Optimizations and speed improvements
Every contribution, no matter how small, makes a difference!
Join hundreds of publishers who are already getting valuable insights with GTM4Publishers