How do I debug the JS that DTM injects?

I’m guessing that by now, you are sick of reading about DTM. Let me reassure you that I have other articles in the pipeline. Also: let me know what else you want me to write about. Know that I can write about DTM all day long ūüėČ

Anyway, today we’re looking at ways to debug with DTM.

I want to mention three things:

1. How can you put a break point into an Event-based Rule or otherwise debug it?
2. Is there a way to trigger a rule manually for debugging?
3. What is this _satellite.notify() method good for?

Since I am me, I will start with the third.


At some point between Basic, Pascal and C, a good friend of mine introduced me to gdb. That was back in the days when we did everything in emacs. Until then, I had been adding System.err.println() statements into my code happily, and ‚ÄĒ frankly ‚ÄĒ gdb was like an epiphany. All of a sudden, I could stop my code anywhere, see and modify everything that mattered, even step through it!

Fast-forward 20 years or so, and I am back to printing. Javascript as an environment is not easily geared to debugging, but there are of course tools. Later.

For now, let’s start with the simple things: debug output, like in the old days.

Most people use console.log() to write debug statements into their code. I suggest you use _satellite.notify() instead.


Two reasons:

  • you’ll only see your debug output when you’re actually debugging. No more “oops, I forgot to remove the log output!” situations (even though you should of course still remove it!)
  • you get “levels” 1 – 5, and the different levels cause different visual output. Makes debugging a heck of a lot easier.

DTM – output from _satellite.notify()
One gotcha to keep in mind: you should only use _satellite.notify() in the code that you place in DTM!

If you use it in your own code, on the page, you create a dependency. Tag management in general is all about removing dependencies, so please don’t do that. There’s a difference between “technical debt” and “oh, come on! seriously?!”

How to set Breakpoints

When you’re tired of putting debug output into your code, it may be time for you to step it up a little.

The Developer Tools in most modern browsers (“Chrome”) are pretty powerful. Since I am no longer a programmer, I am constantly surprised by the things you can do with Chrome, the Console, and maybe a bit of Charles and Map Local.

I sometimes find myself wanting to stop DTM while it is executing a rule, specifically an Event-based Rule, so I can see what the DOM looks like. That would help me pick values out of the DOM.

But setting a break point on DTM code is a bit of work. DTM delivers minified code, a full 4 lines of it. How do you set a break point on some specific part of that? Well, you can’t.

My workflow used to be:

You have to redo that after any change you make in DTM, so the process really is too much.

My office neighbour (who is a developer) showed me this alternative: temporarily define a helper that spits out information about the click.

If your site is using jQuery, all you need to do is open the Console and type this:

	$(document).on("click", function(e) { console.log(e); });

What does that do?

Well, the command creates a handler function that outputs the argument passed into it. The handler is attached to anything that can be clicked, and it outputs the click event.

Doesn’t sound like much, but “e” includes a wealth of information!

jQuery “Click Debug Helper”
Thank you, Senol, this is going to make my life considerably easier!

I guess if you want to take it up to 11, you could define the function separately, which would allow you to put a break point on it.

Also, David Vallejo posted an article last week with a) similar content and b) two top tips, one of them being that you can beautify JS code right in Chrome! I won’t describe it here since his GIF animation of it is pretty good.

It doesn’t help too much for break points, but it sure is useful.

Make sure you check out his article! I love the tip on console.table()!


Thanks, David!

Trigger Rules Manually

A slightly obscure topic, this one, I guess.

I was in a situation the other day with a customer. We had a staging site and we were building rules. Sometimes, the staging environment wasn’t fast enough for our rules, so we would have loved to just execute them again, manually, when we thought it was a good time.

The bad news is that nothing officially supports doing this in DTM.

The good news is that you can very easily fire all the Page Load Rules that are set to “Page Bottom” by simply calling _satellite.pageBottom().

So now we know what that code in your page actually does. Makes sense.

How about the other Page Load Rules?

There is a method called firePageLoadEvent(), which does the trick. Call it like this to fire all “Top of Page” Rules:


The possible values for calling this method are “aftertoolinit”, “pagetop”, “pagebottom”, “domready”, “windowload”. The latter four correspond to the conditions in Page Load Rules, and I’m afraid I don’t know exactly when the first one fires.

Good, we can fire groups of rules. Not bad.


Event-based Rules

Can we be more surgical? Fire a single rule? Maybe an Event-based rule?

Oh yes!

You can see a list of all the Event-based rules that you have define by calling _satellite.rules. The result is an array of “rule” objects.

Now you can call _satellite.fireRule() with one of those objects as the argument, and there you go: you fired a rule.

DTM – call Event-based rule
Careful! The rule will be fired! fireRule does not check the conditions!

Page Load Rules

We have seen how to fire bunches of Page Load Rules based on their conditions.

By the way: the trick only works if you’re in “staging” mode, because DTM otherwise forgets Page Load Rules as soon as it has fired them. Which makes total sense, of course.

So, if _satellite.pageLoadRules returns an empty array, check whether you are really in “staging” mode!

If you are in “staging”, though, you can use firePageLoadEvent(), and you can also see that _satellite.pageLoadRules contains your rules.

What happens when you try to fire one of them using fireRule?

Well, all the things that the rule is supposed to do happen. It’ll happily set variables or events, and it’ll even trigger code.

But it won’t track!

That is because the logic for Page Load Rules in DTM seems to be¬†about the five¬†stages I listed above. DTM goes through them, fires the rules, collects “variables”, then eventually does what the respective Tool wants it to do (tracking in the case of Analytics). But that’s the Tool doing the work, not the rules.

Conclusion: you can see what variables the rule would set and what JS it would execute, but you can only actually make it fire along with the other rules by using firePageLoadEvent.

Fair enough.

Direct-call Rules

Last but not least, how do you fire Direct-call Rules manually?

Well… the very nature of them is to be called manually, using the _satellite.track() method.

So there is really nothing more to say here.

Happy debugging!

3 thoughts on “How do I debug the JS that DTM injects?

  1. Jan: ‘let me know what else you want me to write about’

    Adobes enforcing a Data Retention Policy across their analytics customers.
    Its provoked a lot of good questions here about what we should and need to have from our data from > 3 years ago for it still to have value to the business and the core data guys.
    Also if we want to keep it and not pay Adobe for the privileged of storing it for us, whats the best options and approaches available.

    I think that could be a good topic for all : )


    1. Hi Matt,

      Thanks for that. Do you think it would be relevant on this blog? (“for developers”)

      I guess the second part, about how to get data out, preferably raw data, would be. How about the first?



Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.