For decades, marketers and publishers have been obsessed with page views, average time on site, and – of course – the bounce rate. Sadly, these KPIs often leave stakeholders frustrated because they don’t necessarily reflect actual user engagement. In this post, I share a tag manager-based method to better measure whether users stay on the site long enough to read the contents of a page.
Prerequisites to page content measurement
The first thing we need is basic data collection done right, which means using:
- Decent consent management, not just a banner that reads “wE LOvE YOUr priVaCY (and we send data to a gazillion partners)”
- Tag manager-based data collection with the TMS of your choice (Google, Adobe, Piwik Pro, Commanders Act, Matomo, etc.) along with server-side collection
- An event-based data collection platform (Google, Piwik Pro, Piano, Amplitude, etc.)
All set? Let’s proceed.

Introducing Browser Active Minutes Frequency
We’re going to measure whether users actually take the time required to read through a piece of content using a new metric I call Browser Active Minutes Frequency (BAMF), which is measured using the following formula:
BAMF = LMFAO / GTFO
For this, we’re going to measure the LMFAO (Length Measure For Article Output), aka the number of words in a piece of content, against the GTFO (General Text Flow Output), the average number of words read per minute. For reference, the average GTFO is about 175–300 words per minute for non-fiction English text. Your resulting BAMF will be measured in minutes and seconds.
So far, so good.
Measuring the number of words in a page
Depending on your Content Management System (CMS), you may already have this information handy. You can then surface this information as a META tag or via your TMS’s data layer.
In the example below, we’re going to estimate our LMFAO by measuring the amount of actual content words in a WordPress article, using JavaScript in GTM to scan WordPress elements for the number of words they contain. We will be using the <article> tag for posts, and <main> tag for pages.
Use the code below in Google Tag Manager to create a Custom JavaScript variable called CJS – Word count.
function(){
// Assuming WordPress but use your own selector for the content container
var article = document.querySelector("article");
// Mari Kondo that text
var article_text = article.innerText;
var cleaned_text = article_text.replace(/\s+/g, ' ').trim();
// Break text blob into chunks (words)
var words = cleaned_text.split(/\s+/);
// Handling empty text if trimming goes too hard
if (words.length === 1 && words[0] === "") {
return 0;
}
// Profit!
return words.length;
}
Now let’s create another Custom JavaScript variable called CJS – Time to read the article, which leverages our BAMF formula:
function(){
// Substract zero from your LMFAO
// for forced conversion to integer
var word_count = {{CJS - Word count}} - 0;
// Set your average words read per minute here,
// based on GTFO
var average_wpm = 200;
// Here is the BAMF formula: LMFAO/GTFO
// prepare time in milliseconds
var timeToRead = parseInt(word_count/average_wpm) * 60000;
return timeToRead;
}
Alternative options: enrich your dataLayer using PHP. This requires modifying your header file, ideally in your child theme. Use data layer-based variables such as DLV – Word Count (word_count) and DLV – Time to read the article (reading_time) to replace the CJS equivalents in the rest of this tutorial.
<?php wp_head(); ?>
<script>
<?php
$LMFAO = str_word_count(
strip_tags(strip_shortcodes(
get_post_field('post_content', $post->ID)
)));
$GTFO = 200;
$BAMF = ($LMFAO / $GTFO) * 60000;
?>
var dataLayer = dataLayer || [];
dataLayer.push({
"post_id" : "<?php print $post->ID; ?>",
"word_count" : <?php print $LMFAO ?>, // LMFAO
"reading_time": <?php print $BAMF ?> // BAMF
});
</script>
Expected output:
<script>
var dataLayer = dataLayer || [];
dataLayer.push({
"post_id" : "3135",
"word_count" : 454, // LMFAO
"reading_time": 136200 // BAMF
});
</script>
Now we need to use a GTM timer-based trigger to make use of that BAMF.
As you can see below we’re using a timer with a interval set to our BAMF returned by the CJS – Time to read the article variable.

Finally, let’s tie a GA4 event tag to that trigger as you can see in the tag configuration below.

Your BAMF! GA4 event is now ready to hit your reports for activation! And yes, any event platform will do.
Of course you can enrich the event parameters with, say, word range and reading time brackets to create LMFAO and GTFO models. Create audiences of non-BAMF users and start a Page Interaction Maximization Percentage (PIMP) program to further optimize your content.
In closing
As you can see, calculating your BAMF potential using a tag manager is fairly easy. Actually, the entire endeavour took me less time than writing up this post and coming up with the puns. Therefore, I encourage you to set it up, play with the results and let me know if you got satisfactory PIMP results!

Leave a Reply