GoHighLevel Google Tag Manager Setup: Funnels & Sites (2026) — HL Growth Partner, Dr Priya Jaganathan

GoHighLevel Google Tag Manager Setup: Funnels & Sites (2026)

September 16, 2026

By Dr Priya Jaganathan, GoHighLevel Certified Admin · HL Growth Partner, Australia · Updated 16 September 2026 · 9 min read

Some links below are affiliate links — if you sign up through them, HL Growth Partner may earn a commission at no extra cost to you. It never changes what we recommend. Full disclosure.

A clean GoHighLevel Google Tag Manager install takes about twenty minutes, and it is the single change that stops you guessing which ad, page or headline actually produced a booking. Most accounts I inherit have the opposite: a GA4 tag pasted into one funnel, a Meta pixel pasted into another, and nobody sure what is firing where.

This guide covers installing GTM on HighLevel funnels and websites, wiring GA4 and ad conversions through it, and tracking the two things GHL makes awkward — form submissions and calendar bookings. It also covers consent under Australian privacy rules, and why GTM will never exactly match GHL's attribution report.

Quick Facts

Where the code goesEach funnel and each website has its own Settings area with head and body tracking-code fields
ScopeFunnel-level code applies to every step in that funnel; page-level custom code applies to one page only
Injection methodHighLevel injects tracking code client-side, so it will not appear in static "view source"
Forms and calendarsRendered in iframes, so GTM's built-in form trigger usually will not see them
Testing toolsGTM Preview mode plus Google Tag Assistant; GA4 DebugView for the receiving end
Biggest gotchaDuplicate tags — GTM firing GA4 while a hard-coded GA4 tag also sits in the funnel settings

Where HighLevel actually lets you inject GTM code

Before you install GTM in GHL, understand that there are three separate places code can live, and they do not behave the same way.

Funnel-level tracking code

Open the funnel, go into its Settings, and find the tracking-code section: a head field and a body field. Anything pasted here is injected on every step of that funnel — opt-in, sales page, upsell, thank-you page.

This is where your GTM container belongs. Steps you add next month inherit it automatically, with no extra work.

Page-level custom code

Individual pages also accept custom code in the page builder. Use it sparingly — for something one page genuinely needs and the rest of the funnel does not, never for anything you want site-wide.

Still designing the funnel? My lead capture funnel build guide covers the page structure that makes this tracking worth having.

Websites versus funnels

GHL Sites and Funnels are different objects with near-identical settings panels. A website has its own tracking-code fields, separate from every funnel in the sub-account — installing GTM on a funnel does nothing for the website. HighLevel's websites overview documentation is the current reference if the interface has moved.

Sub-account level

There is also a sub-account settings area carrying tracking code intended to apply across that location's pages. Treat it as a convenience, not a guarantee. Install once at the highest level that covers your pages, then confirm by testing, never by trusting.

The container snippet: why the body half still matters on HighLevel

Google splits the container into two pieces. The JavaScript block goes as high as possible in the head. The noscript iframe block goes immediately after the opening body tag.

<!-- HEAD field -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push(
{'gtm.start':new Date().getTime(),event:'gtm.js'});
/* ...standard Google container code... */
})(window,document,'script','dataLayer','GTM-XXXXXXX');</script>

<!-- BODY field -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>

People skip the body half because nobody disables JavaScript any more. Keep it anyway — it costs nothing and keeps your install matching Google's documented standard.

One HighLevel-specific detail matters. GHL injects these snippets client-side rather than baking them into the served HTML, so View Source will not show your container. Use the browser's element inspector or GTM Preview mode to verify — not View Source. I have watched people reinstall a perfectly working container three times over this.

Fire GA4 through GTM rather than pasting it into GHL

You can paste a GA4 tag straight into the funnel's head field and it works. I route it through GTM anyway, because the second and third tags are where pasting falls apart.

ConsiderationTags pasted directly into GHLTags managed in GTM
Adding a new platformEdit every funnel and site by handAdd one tag, publish once
Conditional firingNot possible without custom codeTriggers handle page, click and event conditions
RollbackManual re-paste, no historyVersion history, one-click revert
Consent controlAll-or-nothingBuilt-in consent settings per tag
Who can change itAnyone with sub-account accessSeparate GTM permissions and approvals
Every tag you paste directly into a funnel is a tag that someone will forget exists — usually six months later, while debugging why conversions doubled overnight.

Tracking form submissions and calendar bookings without guesswork

This is where most GHL tracking setups quietly fail. Forms, surveys and calendar widgets render inside iframes, so GTM's built-in form submission trigger on the parent page generally cannot see them.

You have two workable approaches.

The thank-you page approach

Send the form or calendar to a dedicated confirmation step, then fire the conversion on a page view of that URL. Crude, reliable, and it survives platform updates. The cost: a distinct thank-you URL per offer, and bookmarked pages can double-count.

Listening for the submission message

The cleaner method is a Custom HTML tag in GTM that listens for the message the GHL iframe posts to the parent window on successful submission, then pushes your own event into the dataLayer.

<script>
window.addEventListener('message', function(e){
  var d = e.data || {};
  if (d && (d.type === 'form' || d.type === 'appointment')) {
    window.dataLayer = window.dataLayer || [];
    window.dataLayer.push({event: 'ghl_conversion', ghl_type: d.type});
  }
});
</script>

Fire that listener on the Initialization trigger, not on All Pages, so it is registered before a fast visitor can submit. Then build a Custom Event trigger on ghl_conversion and attach your GA4 and ad platform tags to it.

Payload shapes change, so inspect the actual message in your console before writing conditions. If your forms need work first, start with the forms and surveys setup walkthrough.

What you want to trackGTM trigger typePractical note
Container loaded on every stepInitialization / All PagesUse Initialization for listeners and consent defaults
Embedded form submittedCustom Event from your listenerBuilt-in Form Submission trigger will not see iframes
Calendar booking completedCustom Event, or Page View on confirmation stepConfirmation-page method is the safer fallback
CTA button clickedClick — All Elements, filteredFilter on Click Text or a class you set in the builder
Outbound or tel: linkClick — Just LinksEnable Wait for Tags on links that navigate away
Long-page engagementScroll Depth or Element VisibilityElement Visibility is better for an offer block

Not on HighLevel yet? Start with a free 30-day trial here — long enough to build everything in this guide before you pay a cent.

Button and CTA clicks, without brittle selectors

Auto-generated class names in page builders change when you edit a section. A trigger built on them breaks silently.

Two habits fix this. Give important buttons a custom CSS class in the builder — cta-book-call, say — and trigger on that. Or trigger on Click Text where the copy is stable.

Name the event for the action, not the element. click_book_call_hero still makes sense in a year; button_3_click does not. The same discipline applies to your trigger link tracking in email campaigns.

Meta and Google Ads conversion tags through the same container

Once the ghl_conversion event exists, both ad platforms hang off it. Google Ads uses a conversion linker plus a conversion tracking tag; Meta uses its base pixel on all pages plus an event tag on the custom event.

Three rules I apply on every build:

  • Conversion Linker fires on all pages, first, so click identifiers are stored properly
  • Exactly one Meta base pixel exists — in GTM or hard-coded, never both
  • Booking and purchase stay separate conversion actions, because a booked call is not revenue

For higher-intent campaigns, pair this with offline conversion imports from your GHL pipeline so Google optimises toward closed deals rather than raw form fills.

Consent Mode v2 uses four signals — ad_storage, analytics_storage, ad_user_data and ad_personalization. The first two govern what is written to the device; the two added in v2 govern what is transmitted to Google and how it may be used. Google's official consent settings documentation is the reference to follow.

Google made Consent Mode v2 mandatory for advertisers serving EEA and UK traffic from March 2024. If your client sells only in Australia, that specific mandate is not yours — but do not conclude the topic is irrelevant.

Australia does not impose a cookie-banner rule in the way the GDPR does. The OAIC published guidance in November 2024 confirming that personal information collected through tracking pixels falls under the Privacy Act 1988, and the Privacy and Other Legislation Amendment Act 2024 tightened the enforcement picture further.

Practically: say what you collect, in plain words, in your privacy policy, and give people a way to opt out. A consent banner wired into GTM's consent settings is the tidiest way to honour that choice.

Testing the install before you trust a single number

Turn on GTM Preview mode, enter your funnel URL, and walk the real path — land, scroll, click the CTA, submit the form, complete a booking.

Watch three things at each step:

  • Did the expected trigger appear in the left-hand event stream?
  • Did the tag move into the Tags Fired section, not Not Fired?
  • Did GA4 DebugView receive the event with the parameters you expect?

After publishing, open Google Tag Assistant on the live page and check for duplicate GA4 configuration tags. Duplicates are the most common defect I find, and they inflate everything downstream — including any split test you run on those pages.

Why GTM and GHL's attribution report will never agree

Clients ask this every time, so answer it before they do. The two systems count different things.

GHL attributes a contact using the session data captured when that contact was created, and it persists against the record. GA4 counts browser events, shaped by its own session and modelling logic, consent signals, ad blockers and cross-device gaps.

A person who researches on mobile and converts on a laptop is one contact in GHL and often two users in GA4. Use GHL for who converted; use GA4 for how traffic behaves in aggregate. Build the client-facing view around pipeline numbers — see my GHL dashboards and reporting guide — and treat GTM as the diagnostic layer underneath.

Common mistakes to avoid

  • Pasting the head snippet into the body field, or vice versa — they are not interchangeable
  • Installing the container on one funnel and assuming the sub-account is covered
  • Leaving a hard-coded GA4 or Meta tag in funnel settings after moving that tag into GTM
  • Using the built-in Form Submission trigger on GHL's iframe-rendered forms, then wondering why nothing fires
  • Checking the install with View Source instead of the element inspector or Preview mode
  • Publishing the container without walking a real submission end to end

If you want your GTM container, GA4 events and GHL conversion tracking audited and rebuilt, book a strategy call with the HL Growth Partner team.

Book Your Strategy Call →

Or if you just need the software first: grab the 30-day HighLevel trial and book us when you're ready to scale it.

Frequently asked questions

Where do I paste the Google Tag Manager code in GoHighLevel?

Open the funnel or website, go into its settings, and find the tracking-code section containing separate head and body fields. The GTM JavaScript block goes in the head field and the noscript iframe block goes in the body field. Installing at funnel or site level means the container loads on every step automatically.

Why can't I see my GTM container in the page source?

HighLevel injects tracking code on the client side rather than serving it in the initial HTML, so View Source will not show it. Use your browser's element inspector on the rendered page, or GTM Preview mode, to confirm the container loaded. Reinstalling because View Source looked empty is a common and unnecessary step.

Will GTM's form submission trigger work on GoHighLevel forms?

Usually not. GHL forms, surveys and calendar widgets render inside iframes, and browser security stops a parent-page listener from seeing events inside them. Use a Custom HTML tag that listens for the message the iframe posts to the parent window, or fall back to firing on a dedicated thank-you page view.

Should I still paste GA4 directly into HighLevel if I have GTM?

No — pick one. Running a hard-coded GA4 tag alongside a GA4 tag in GTM produces duplicate pageviews and inflated event counts. Move everything into the container and remove the pasted version, then verify with Google Tag Assistant.

Does a funnel-level tracking code cover my GHL website too?

No. Funnels and websites are separate objects in HighLevel, each with their own tracking-code fields. Code added to a funnel does not apply to a site, and the reverse is equally true. Install the container in both, or use the sub-account level setting and then verify each property.

Do Australian businesses need a cookie consent banner for GTM?

Australia has no direct equivalent of the GDPR cookie-banner rule, but the OAIC confirmed in its November 2024 guidance that personal information collected via tracking pixels is covered by the Privacy Act 1988. Disclose your tracking clearly in your privacy policy and offer a genuine opt-out. Wiring a consent banner into GTM's consent settings is the cleanest way to honour that choice.

Why don't my GA4 conversions match GHL's attribution report?

They measure different objects. GHL attributes a contact record using the session data captured at contact creation and keeps it against that contact, while GA4 counts browser events shaped by its own sessionisation, consent signals and modelling. Cross-device journeys widen the gap further, so expect a persistent difference and report pipeline numbers as the source of truth.

Paid ads and conversion data

Pages, forms and testing

Reporting and agency operations

Dr PriyaJaganathan

Dr PriyaJaganathan

Dr Priya Jaganathan is a Go High Level Certified Admin, trusted CRM consultant based in Australia, and a keynote speaker at SaaSpreneur Sydney and Level Up 2025 in Dallas.

Back to Blog