How to Embed GoHighLevel Forms with UTM Parameters on External Websites
A step-by-step guide to embedding GoHighLevel forms on external sites and passing UTM parameters into your CRM for accurate lead attribution.
Accurate lead attribution is essential when running paid ads or multi-channel campaigns to identify exactly which traffic sources, keywords, and creatives generate leads. Without proper UTM tracking on GoHighLevel (GHL) forms, ad budgets are spent with no way to prove ROI or optimize marketing spend. This guide provides a comprehensive, step-by-step solution to ensure marketing data flows seamlessly from an external website (WordPress, Webflow, Shopify, or custom HTML) directly into the GHL CRM.
1. Why UTM Tracking Matters
What are UTM Parameters?
UTM (Urchin Tracking Module) parameters are tags added to the end of a URL to track the effectiveness of online marketing campaigns. The five standard parameters are:
- utm_source: The platform (e.g., google, facebook, newsletter).
- utm_medium: The marketing medium (e.g., cpc, email, social).
- utm_campaign: The specific campaign name (e.g., springsale2024).
- utm_term: The paid search keyword (e.g., agency+management+software).
- utm_content: The specific ad variation or link (e.g., bluebutton, sidebarbanner).
The Challenge: The "Iframe Isolation" Problem
GoHighLevel forms are typically embedded on external websites using an iframe. Because an iframe acts as an independent window into another domain, the iframe is isolated from the parent webpage's URL data. If a visitor lands on an external website URL like yoursite.com?utm_source=google, the embedded GHL form inside that page cannot see those parameters by default.
Bridging the gap between the external website's URL and the GHL form's source code solves this iframe isolation problem.
2. Step 1: Prepare the GoHighLevel Form
Before modifying any code on the external website, the GHL sub-account must be configured to receive and store the UTM data.
Create Custom Fields
- Navigate to Settings > Custom Fields in the GHL sub-account.
- Click Add Field > Text and create a field for each parameter: utm_source, utm_medium, utm_campaign, utm_term, and utm_content.
- Crucial: Ensure the "Query Key" (or internal name) matches these standard naming conventions exactly, as they are case-sensitive.
Add Hidden Fields to the Form
- Go to Sites > Forms > Builder and select the GHL form.
- Drag the newly created UTM custom fields into the form.
- Click on each field in the builder and toggle the "Hidden" setting in the right-hand sidebar. This ensures users do not see these fields, but the CRM still captures the data.
- Save the form.
3. Step 2: Choose the Embedding Method
GHL forms can be embedded using two primary methods. The JavaScript approach is highly recommended for reliable UTM tracking.
Method A: Native JS Embed (Simplest)
The native JS embed snippet allows the GHL form to "read" the parent window's URL parameters more reliably than a raw iframe.
1<script src="https://link.msgsndr.com/js/form_embed.js"></script>2<iframe3 src="https://link.msgsndr.com/widget/form/YOUR_FORM_ID"4 style="width:100%;height:500px;border:none;"5 id="inline-YOUR_FORM_ID"6 data-form-id="YOUR_FORM_ID">7</iframe>
Method B: Dynamic UTM Passthrough Script (Most Robust)
If a standard iframe is used or UTM parameters are not passing correctly, the dynamic UTM passthrough script provides a robust solution. This script reads the external website's URL and manually injects the UTMs into the GHL iframe's source.
The Implementation:
- Paste the GHL Iframe code on the webpage.
- Add this script immediately before the closing </body> tag:
1document.addEventListener("DOMContentLoaded", function() {2 // 1. Get the URL parameters from the website3 const urlParams = new URLSearchParams(window.location.search);4 const queryString = urlParams.toString();56 if (queryString) {7 // 2. Target the GHL iframe (Replace YOUR_FORM_ID with the actual ID)8 const ghlIframe = document.querySelector('iframe[src*="msgsndr.com/widget/form"]');910 if (ghlIframe) {11 // 3. Append the UTM parameters to the iframe's src URL12 const currentSrc = ghlIframe.src;13 const separator = currentSrc.includes('?') ? '&' : '?';14 ghlIframe.src = currentSrc + separator + queryString;15 console.log("GHL Form src updated with UTMs:", ghlIframe.src);16 }17 }18});
4. Step 3: Advanced Persistence (Tracking Across Multiple Pages)
A common issue occurs when a visitor lands on a homepage with UTMs but navigates to a contact page before converting. Since the new page load clears the previous URL data, the parameters are lost.
To solve this parameter loss, add the following script to the external website's header to store UTMs in the browser's Local Storage:
1(function() {2 var utmParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'];3 var params = new URLSearchParams(window.location.search);4 utmParams.forEach(function(param) {5 var value = params.get(param);6 if (value) {7 localStorage.setItem(param, value);8 }9 });10})();
The form script can then be modified to check Local Storage if the URL parameters are missing from the active page.
5. Step 4: Testing and Verification
To ensure the UTM tracking setup is working correctly:
- Open a new Incognito window.
- Navigate to the external webpage using a URL with a test string: https://yourwebsite.com/page?utm_source=test_source&utm_medium=test_medium&utm_campaign=test_campaign
- Fill out and submit the embedded GHL form.
- In GoHighLevel, navigate to Contacts, open the new contact record, and check the "Additional Info" tab.
- The hidden fields should be populated with the test values.
6. Utilizing UTM Data in GoHighLevel
Once the UTM data is flowing into GoHighLevel, it can be leveraged for:
- Smart Lists: Group leads by utm_source to compare Google Ads leads against Facebook leads.
- Workflows: Trigger specific automations (e.g., "Fast Follow-up") for leads originating from high-cost "cpc" campaigns.
- Attribution Reporting: Build custom dashboards to visualize Lead Volume and Conversion Rates by channel.
- Sales Routing: Assign leads from specific campaigns to specialized sales representatives.
7. Troubleshooting Common Issues
- Field Mapping: Ensure the "Query Key" in GoHighLevel matches the URL parameter exactly (case-sensitive).
- Caching Plugins: On platforms like WordPress, aggressive caching (e.g., WP Rocket) can prevent scripts from executing. Clear the website cache after installation.
- Redirects: If an ad points to site.com/offer but redirects to site.com/main-offer, the UTMs may be stripped during the redirect. Ensure the server preserves query strings.
- Iframe ID: Ensure the id in the JavaScript (inline-YOUR_FORM_ID) matches the id attribute in the GHL iframe embed code exactly.
- Form Height: If the embedded form is cut off, adjust the height attribute in the iframe code (e.g., increase from 500px to 800px).
Get Started
Ready to try GoHighLevel?
Get full access to every GoHighLevel feature with our exclusive 30-day extended trial. No commitment — cancel anytime.
Start Your Free TrialThe 30-day extended trial is exclusive to GHL Experts referrals.
Join thousands of agencies using GoHighLevel to replace their entire marketing stack and boost recurring revenue.
