How I built two websites to learn marketing — Part 3: making them measurable

8/14/20266 min read

In the second part I dealt with the legal side of the websites. This part is about the opposite problem: not what I am required to tell visitors, but what the visitors can tell me.

A website that nobody measures is just a document. If I want to claim I can do performance marketing, I have to be able to answer basic questions about my own sites: how many people came, where they came from, and whether they did the thing on my website that I wanted them to do. That means analytics. And because these are European sites, it also means consent, since you are not allowed to track people who have not agreed to be tracked.

The setup is the same on both websites and has four parts. I will explain each one, because before this project I would not have been able to explain any of them.

Google Tag Manager is the hub. Without it, every tracking tool you add means pasting another piece of code into your website. With it, you paste one container into the site, and then everything else is managed from inside that container. It took me a while to understand that Tag Manager does not track anything itself. It is a manager. You give it tags, which are the tools that do the actual work, and triggers, which tell each tag when to fire. Tag Manager just sits in the middle and gives the orders.

Cookiebot is the consent banner, and more importantly the consent gate. It asks visitors what they allow, and holds everything else back until they answer. It runs through Tag Manager together with Google Consent Mode, which means that before a visitor makes a choice, the tracking tools are not merely quiet — they are blocked. I tested this in a private browser window: before touching the banner, nothing fires at all. After allowing, everything does.

Google Analytics 4 measures the traffic and the conversions. Meta Pixel does the equivalent for Facebook and Instagram advertising, and the music site additionally has a TikTok Pixel. The marketing site deliberately does not have one, because there is no TikTok presence for it and there is nothing to track.

One important thing to keep in mind here. Hostinger gives you fields where you can paste a Google Analytics ID or a Meta Pixel ID directly into the site settings. I left all of them empty and ran everything through Tag Manager instead. If you use both routes at once, every visit gets counted twice, and the data becomes wrong in a way that still looks plausible — which is worse than data that is obviously broken.

All of this runs on free plans. Tag Manager, Analytics and the pixels are free. Cookiebot has a free tier, although it covers one domain per account, so with two websites I needed two accounts.

Then I had to do another interesting part.

Counting page views is not very useful on its own. What I wanted was a conversion event: when somebody subscribes to my newsletter, that should be recorded as a specific event, so that if I later run an advertising campaign, the platform knows what a successful outcome looks like and can go and find more people likely to do the same thing.

My newsletter form is a Mailchimp form embedded on the page. When you subscribe, a green message appears saying the subscription still needs to be confirmed by email. So the plan was straightforward: create a trigger in Tag Manager that watches for that green message appearing, and when it appears, fire a sign-up event to Analytics and a lead event to Meta.

But when I created the trigger in Tag Manager, nothing fired.

I started checking the obvious things. A trigger has to be told exactly what to watch for. You do that by giving it the element's identifier — a name that exists in the page's code but that visitors never see. Every browser has a built-in tool for looking at that code: you right-click on something on the page and choose "Inspect", and a panel opens showing the underlying structure of what you just clicked on. So I right-clicked the green success message, opened the inspector, and read off the identifier the browser showed me. It matched what I had put into the trigger. So that was not the problem.

I also checked that I had accepted my own cookie banner while testing, since nothing is allowed to fire before consent, and it would be an easy mistake to sit there refusing my own tracking and wondering why nothing happens. I had accepted it. So both obvious explanations were wrong. I ran the test again several times, watched the green message appear on the page with my own eyes, and watched Tag Manager report that nothing had happened.

The reason turned out to be an iframe.

When you paste an embedded form into the Hostinger builder — or into any website builder — it does not simply place that code on your page. It wraps it in an iframe. An iframe is a way of putting one webpage inside another. It is an element that says: load this other web address here, in this rectangle. The browser then fetches that other page and displays it inside the box, as part of the layout.

So when I pasted Mailchimp's form code into Hostinger, Hostinger did not copy that code into my page. It created a frame on my page and loaded Mailchimp's form into it, from Mailchimp's own servers. What a visitor sees is one page. What is actually there is my page with a window cut into it, and behind that window, a different page belonging to somebody else.

This is extremely common. Embedded YouTube videos work this way, and so do embedded maps, payment forms, booking calendars and chat widgets. You have probably been looking at iframes for years without noticing.

And that was my problem: the form is technically its own sealed document, loaded from a different address — Mailchimp's, not mine. Browsers deliberately do not allow code on the outer page to look inside an iframe that comes from a different domain. That rule is not a bug. It is the thing that stops any website you visit from reaching into an embedded payment form and reading your card number as you type it. It is a security boundary.

So essentially, Tag Manager was being asked to watch something it is forbidden to see. And the same wall would have defeated my obvious fallback, which was to trigger on the click of the subscribe button instead — because the button is inside the same iframe.

The way through was the one route browsers do allow. They block the outer page from reaching into an iframe, but they do provide a deliberate way for the two to communicate: a built-in function called postMessage. Any code running inside the iframe can call it and send a short message outward, to the page that contains the frame. The containing page can set up a listener that waits for those messages and reacts when one arrives.

The important detail is who is in control. The outer page cannot go in and take anything — the inner page decides what to send, and when. That is why it is allowed: nothing is being read without permission, something is being volunteered. The wall stays intact, and the information still gets across, as long as the sending happens from the inside.

So that is what I built. Instead of watching the form from outside, I put a small script inside the Mailchimp form itself, where it is allowed to see the success message. It watches for that message and, the moment it appears, calls postMessage and sends one short signal outward.

On my page, a listener waits for that signal, and when it arrives it writes an entry into something called the dataLayer. The dataLayer is Tag Manager's message board. It is simply a list that sits on the page, and anything on the site can add an entry to it saying "this just happened". Tag Manager watches that list constantly. This is how Tag Manager learns about things it could not otherwise detect on its own: rather than trying to observe the page directly, it reads announcements that the page makes to it. So the listener's job is just to translate — it hears a message from inside the iframe and turns it into an announcement Tag Manager can understand.

That announcement is what my trigger now watches for, instead of the green message it was never allowed to see. From there everything is normal. Google Analytics records a sign_up, Meta records a Lead, and both remain consent-gated like everything else, so nothing fires for a visitor who declined.

It worked when I ran the next test. Both tags reported as fired and successful. After an evening of watching nothing happen, that was one of the better moments of this project.

My instinct, when it did not work, had been to assume I had configured something wrong and to keep re-checking my own settings. That was a mistake, and it cost me most of the time. What actually solved it was looking at the page itself and finding out how it was really put together. My configuration was right. My picture of the page was wrong, and no amount of re-checking the configuration was ever going to reveal that.

In the end, the whole setup cost nothing. Every tool involved has a free tier that is more than enough at my scale.

And this is how I built the two websites to learn marketing. It took quite a bit of time, but it brought quite a few new understandings as well.