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.
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.
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”.
Now if you don’t have any content grouping added, then you should see (not set) as your only dimension value.
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”
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.
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.
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.
Now all you have to do is to pick this variable in your GA4 configuration in the field “Value”
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.
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.
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
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“.
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.
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.
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.
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!
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.
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