Content grouping in Google Analytics 4

Content grouping in Google Analytics 4 (GA4)

In this article, we will explore how we can create content groups in GA4 reports to make a better overview of your website performance.

In case you prefer video format, you can watch it below. Also, you canĀ subscribe to my YouTube channel!

Your website might have multiple sections that serve a different purpose, for example, E-commerce store, Blog, FAQ pages, etc.

You can analyze each section’s performance based on URL structure and filter out necessary pages manually in the GA interface, but there might be a lot of pages in each group and new pages might constantly appear in the reports. To make our life a bit easier we can group similar content under a single label in Google Analytics.

In a previous version of Google Analytics, it was called “Content grouping” and you could create such groups inside User Interface.

Content grouping setup example in previous version of Google Analytics

Unfortunately, Google Analytics 4 doesn’t support content grouping in the interface (yet), but luckily we can send that information from our tags. Let’s find out How.

How do I check if I have content grouping created for my GA4 account?

Open Reports > Engagement > Pages and screens report from the left sidebar.

GA4 Pages and screens report navigation

In your report on the right, find a table that lists all your pages and change “Page title and screen class” to a different primary dimension – “Content group”.

Page report in Google Analytics 4
Content group dimension in Google Analytics 4

Now if you don’t have any content grouping added, then you should see (not set) as your only dimension value.

Content group report values with (not set)

Depending on how your Google Analytics tag was added on the website the method how you pass information about content group will be different, so let’s take a look at separately how you would add it using Google Tag Manager or gtag.js

Setup grouping using the “content_group” parameter

To have visibility on the content group that visitor has seen there is a dedicated attribute in Google Analytics 4 called “content_group” that we can use to pass this information into our reports. The additional nice thing is that you can actually use the same parameter to group your content in an app, you can read more in the official documentation.

Adding attribute in GTM tag

Open your Google Analytics 4 tag, and under “Fields to set” click on “Add row”

Google Tag Manager GA4 tag configuration

Under “Field Name” enter – “content_group” , and in the “Value” field you need to provide a GTM variable that will contain the content group for the current page. In my case, I have this value in dataLayer under “pagePostType” parameter so I’m passing this value to GA4.

Additional fields for Google Analytics 4 tag - content_group

How do I get a variable that contains a content group?

Depending on the website setup and what data is available in dataLayer there could be multiple ways how to pass dynamic content group variables. You could ask your developer to pass additional value to dataLayer and then fetch that value from dataLayer. If you are using WordPress you could use a plugin that populates dataLayer with a page type on each page. If the website URL structure allows it, you can also create a custom JS variable or a lookup table that will dynamically create the necessary group name.

Using a dataLayer variable

If you have a large website and a non-descriptive URL structure, then the easiest way how to get a content group for a page is using the help of a developer and adding an additional dataLayer attribute.

To pass the content group we can add dataLayer push before GTM loads (ensuring that this data will be available before pageview hit is sent) and then fetch it in the GTM interface.

Here is an example code that you could use for this:

<script>
    window.dataLayer = window.dataLayer || [];
    window.dataLayer.push({
      "contentGroup": "Homepage" // Replace with dynamic content group name depending on visited section
    });
</script>

First of all, we are defining a dataLayer or just using an existing object in case it exists. You can check why it is important in this great article by Simo Ahava.

window.dataLayer = window.dataLayer || [];

Then we are adding additional data points into our dataLayer object with information about the content group. In this case, our attribute is called “contentGroup”, but you can use any other name while you keep it consistent with your GTM variable setup.

window.dataLayer.push({
  "contentGroup": "Homepage" // Replace with dynamic content group name depending on visited section
});

“contentGroup” attribute values should dynamically change depending on the visited site section. You should explicitly explain that to a person who will implement this code on your website and define when each of the values should appear in the dataLayer.
For example “Homepage” for the homepage, “Product” for any product pages, “Blog article” for any blog articles, etc.

When the code is implemented all we need to do is to create a new variable in GTM that will fetch this value. Under the “Variables” section click “New” to create a new variable.

How to create new user variable in Google Tag Manager

Choose variable type “Data Layer Variable” and add the variable name “contentGroup” or whatever name you have used in your dataLayer code. Then save the variable.

contentGroup dataLayer variable creation

Now all you have to do is to pick this variable in your GA4 configuration in the field “Value”

Set custom variable in a Google Analytics tag

I’ve used a similar approach on this website, except that I had my dataLayer populated by a 3rd party plugin. You can see I have a “pagePostType” attribute available instead of “contentGroup” as in the example above.

dataLayer example from WordPress site

Using RegEx table variable based on URL structure

If for some reason you want to avoid adding any dataLayer code on the website and group your content using available URLs, you can try your luck with RegEx tables.
RegEx table will try to match provided regular expressions and return a pre-defined value if the pattern matches the URL that the customer sees on your website. In this post, I will not cover what is a regular expression and how you can use that in GTM, but if this concept is new to you, you can start your reading here. You can also read a detailed article explaining the RegEx table in GTM.

In this case, we will skip the dataLayer setup part and create a new variable straight away.

Create a new variable with the type “RegEx Table”, and make sure to select “Page path” or “Page URL” as your Input variable.

RegEx table setup example

The main idea here is to specify all the URL patterns that will match your specific page group. I will keep it as simple as possible just to show the idea, the rest will be unique for each website and URL setup.

Let’s say we want to group our content in 4 categories on our E-commerce store:

  • Category page
  • Product page
  • Blog article
  • Other

In our example E-commerce store has disctinct URLs for each of those website sections:

  • Category page – example.com/category/t-shirts
  • Product page – example.com/product/234/blue-t-shirt-with-smiley-face
  • Blog article – example.com/article/great-thirt-designs-for-your-family
  • Other – Any other page that doesn’t match URL patterns above

If we are sure that these categories will always have following URL structure, we can use consistent parts of each URL to create out RegEx table. The setup will look like this:

  • /category/ – “Category page”
  • /product/ – “Product page”
  • /article/ – “Blog article”

And we will return a default value as “Other” if nothing was matched

Regex table setup to fetch content groups based on URLs

Now under Advanced settings, we also need to disable “Full Matches Only”, so that our table would return value if there is a partial match only. If we leave it as is, table will match only Page paths that equal example.com/category/

Also, you need to disable “Enable Capture Groups and Replace Functionality”, otherwise your content groups could return unexpected output based on URL content (E.g. instead of “Category page” it would return “Category paget-shirts“.

RegEx table advanced settings in Google Tag Manager

That’s it, now you would save the variable and use it as a variable in GA4 tag, as we did in the previous example with dataLayer.

Adding attribute using gtag.js

If you are using gtag.js, then similarly as with dataLayer setup, this information would need to be calculated and added by your web developer.

The code that you need to add to your GTAG setup:

gtag('set', 'content_group', 'Homepage'); // 'Homepage' should be dynamically replaced depending on page group

Instead of “Homepage”, the developer would need to dynamically replace this value depending on the page type. This will set the content group for all data streams on your site.

If you prefer, you can also set it only for a specific data stream:

gtag('config', 'STREAM_ID', {
  'content_group': 'Homepage'
});

As in the first example, this also needs to be changed in your main gtag.js code.

Preview your content group

Now when you are already collecting data, when you go back to Reports > Engagement > Pages and screens you should see your new content groups.

Content group report after adjustments have been done

Going further – multiple content groups in GA4

What to do if I want multiple content groups as in good old GA3?

As you might have suspected, we have only 1 pre-defined attribute for the content group in GA4, which means any additional groups need to be passed as an Event level custom dimension.

To have additional groups you would have to create a new custom dimension, like “content_group_2” and then pass dynamic data there from GTM or Gtag.js similarly as in the examples described above.

Secondary content group dimension setup in Google Analytics

In the default reports, it wouldn’t be available as a primary dimension, but you could add it as a secondary dimension from Custom Event scoped parameter list.

How to select secondary dimension in Google Analytics 4

Summary

At the time of the writing Content grouping in Google Analytics 4 is not yet as flexible as in the previous GA version, but the good thing is that it is fairly easy to set up if you add additional values in the dataLayer.
If Google were to update the current “Modify Event” functionality to support RegEx matching, then I believe it would open an opportunity to adjust Content groups based on URLs without leaving the GA interface, which would be an interesting option to explore.
So I hope you have found something useful in this post for your own projects and I wish you Good luck!

2 thoughts on “Content grouping in Google Analytics 4 (GA4)

  1. Thanks for this nice article. I have added the content grouping using the gtag.js but still seeing the ‘Not set’ when I select Content group in the reports.
    This is what I added to my pages:
    gtag(‘set’, ‘content_group’, ‘tutorials’);

    Is there something I am missing.

    1. Hey Prakash,

      Have you tried to debug this in DebugView in GA4? You can click on the page_view event from there and search for content_group parameter. It should be displayed if data is being sent correctly. If you’re not using GTM at all (only gtag.js) you can enable preview mode using any of the methods outlined here – https://support.google.com/analytics/answer/7201382?hl=en#zippy=%2Cgoogle-tag-gtagjs

      You can also share a page where you have this code installed, I can quickly take a look if I can spot any issues from my side.

      BR,
      Vlad

Leave a Reply

Your email address will not be published. Required fields are marked *