Tag Manager: Fire Tag Only if CSS Class is Absent

I finally stepped away from Google Analytics and implemented Plausible's cookie-free tracking on the blog. Ironically, to implement Plausible's code, I used Google's Tag Manager (this doesn't compromise Plausible's code in any way; I just think it's sad that Google is still a crutch for my dev-ops). Since Plausible doesn't gather Personally Identifiable Information (PII), though, excluding my own usage on the site becomes a slight challenge; Google Analytics let's you exclude data based on IP--but, that's not an option with Plausible. With the help of Tag Manager, however, I can prevent Plausible's code from loading based on whether a CSS class is present on a DOM Element. When logged into Drupal, there are any number of CSS classes that are unique in the DOM. This provides a simple solution to excluding my own usage from Plausible's analytic data. Here's how to do that.

Step 1: Finding Unique Classes in the DOM

This technique isn't limited to excluding analytics tags. By finding unique classes in the DOM, you can setup both exclusion and inclusion rules for Tag Manager to fire a tag of any type. This is actually a pretty powerful ability. In my case, though, I need to find a CSS class (or classes) in the DOM that only appears when I'm logged into the blog. Drupal adds these kinds of classes throughout the DOM, but the most logical candidate, for me, is a class in the <body> tag. If I open up Firefox's Developer Tools (ctl + shift + i), here's what I see (note: I'm on Drupal 8; the classes attached to the <body> may differ for D7 or D9):

looking at the DOM with Firefox's developer tools
I feel so exposed...

There are a handful of juicy classes up in that <body> tag. The one I want to take note of is the class user-logged-in. This one only appears in the <body> tag when... believe it or not... a user is logged in. Basically I'd like Tag Manager to create a rule that says: if the user-logged-in class is absent from the <body> tag (i.e., a user isn't logged in), go ahead and fire the tracking script.

The first step in setting that up, however, is to find a way of letting Tag Manager target the <body> tag so that it can establish this rule. I could target the body tag with an ID; unfortunately, as you can see, my <body> tag doesn't have any ID attributes. So, to target it, paradoxically, I'll need the help of CSS once again. I need to find another class, other than user-logged-in that shows across most (or, ideally, all) of the site.

But, wait!!--why can't I just target the <body> with theĀ  user-logged-in class? No--because I won't then be able to setup a rule for when it's absent. By targeting the <body> with user-logged-in, I ensure Tag Manager always sees it there. That's no good. I need a different class to target the <body>. Here are some of the other notable classes in my <body> tag:

  • layout-one-sidebar -- will show on any page with a one-sidebar layout (basically, all user facing content).
  • path-node -- should show on anything that is a node (probably not views-based pages, though--like my front page).
  • path-node-type-article -- will show on anything in the article content type.
  • toolbar-fixed -- should show on any page viewed when a user is logged in.

The best candidate is the layout-one-sidebar class. This class is likely placed there by my theme (Bartik)--so you may not have it in whatever theme you're running. In my case, though, I know it covers all user facing content, so that's a pretty good start. For any admin facing content, I can prevent the script from firing based on URL rather than the absence of a specific class (most admin pages will have /admin in their path).

Now that I have a class to target the <body> tag with, let's go set up a new variable.

Step 2: Setting a DOM Element Variable

Find your way to the Variables section and create a new variable; for Variable Type, choose "DOM Element". This should bring up a Variable Configuration panel asking how you'd like to target the DOM element in question. For the Selection Method, you can, again, choose an ID if that works best for you. Since I don't have a choice, I've selected "CSS Selector". The Element Selector is the class name that you're working with--in my case .layout-one-sidebar. Lastly, the Attribute Name is the kind of attribute that the name belongs to--i.e., layout-one-sidebar is a "class". Here's an example:

variable configuration on google tag manager
It would be nice if Google Tag Manager, and the script pedaling digital marketing industry as whole, could use the same lingo everyday developers use. At the end of the day, it all makes sense, but none of it is particularly intuitive.

You'll want to save your variable and give it a name. I've called mine "Body", since it essentially turns the <body> tag (containing the layout-one-sidebar class) into a variable. Now that the variable is set up, you can reference it in the rules you use to fire (or not fire) your tag.

Step 3: Triggering Only if CSS Class is Absent

I'm going to assume you can more or less work through the basic setup of a tag. In my case, I'm setting up a Custom HTML tag (containing my tracking script), and for Firing Triggers I'm using "Page View". The "Page View" Trigger Configuration is where we can employ our exclusion rule. Once at the configuration panel, you'll want to select "Some Page Views" under This trigger fires on. We don't want the script to fire on all page views, so selecting this will allow us to apply some logic as to when the trigger allows the tag to fire. You should see two drop downs and field to which you can apply some logic. The first drop down should contain a list of variables to use. The "Body" variable we setup in the last step should be there--go ahead and select it. The middle drop down should contain logical operators: equals, does not equal, contains, does not contain, etc. Go ahead and select "does not contain". In the last field, we place the user-logged-in class. Now we've set our rule: "Fire this trigger when 'Body' 'does not contain' 'user-logged-in'." Here's what it should look like:

configuring a Tag Manager trigger to fire only if css class is absent
Mmmm... more than a few rules here.

You'll note that, in addition to my "Body" rule, I've also set the tag not to fire if the page path contains expressions associated with admin side of the site. This is a technique that should work across any version of Drupal, and any other CMS (I would imagine). Once again, save your trigger, preview your tag, and you should be good to deploy.