How to Embed GoHighLevel Forms with UTM Parameters on External Websites
Learn how to embed GoHighLevel forms on external websites and pass UTM parameters into hidden fields for full campaign attribution and lead tracking.
If you are running paid ads or multi-channel marketing campaigns for your agency, you need to know exactly which traffic sources are generating leads. Without proper UTM tracking on your GoHighLevel forms, you are flying blind -- spending ad budget with no way to attribute which campaign, keyword, or ad creative actually drove the conversion.
This guide walks you through embedding GHL forms on any external website and automatically capturing UTM parameters in hidden form fields. By the end, you will have full attribution data flowing into your GHL CRM on every single lead.
What Are UTM Parameters and Why Do They Matter?
UTM (Urchin Tracking Module) parameters are tags you add to the end of a URL to track where your traffic is coming from. When someone clicks a link with UTM parameters, those values get passed along in the URL and can be captured by your forms.
The five standard UTM parameters are:
- utm_source -- Identifies the traffic source (e.g., google, facebook, newsletter)
- utm_medium -- Identifies the marketing medium (e.g., cpc, email, social)
- utm_campaign -- Identifies the specific campaign name (e.g., spring_sale_2026)
- utm_term -- Identifies the paid search keyword (e.g., gohighlevel+pricing)
- utm_content -- Differentiates ad variations or links (e.g., hero_cta, sidebar_banner)
A typical UTM-tagged URL looks like this:
1https://yoursite.com/landing-page?utm_source=google&utm_medium=cpc&utm_campaign=brand_search&utm_term=gohighlevel+review&utm_content=ad_v2
Why This Matters for Agencies
For agencies managing multiple clients and campaigns, UTM tracking is not optional. It lets you:
- Prove ROI to clients by showing exactly which campaigns generated leads
- Optimize ad spend by identifying your highest-converting traffic sources
- Build attribution reports inside GHL that tie revenue back to specific campaigns
- Compare channels to understand whether Google Ads, Facebook, email, or organic is performing best
- Identify winning ad creatives by tracking which content variations drive the most conversions
Without UTM data captured at the form level, you are limited to whatever analytics tools tell you about sessions -- but you lose the direct connection between a specific lead and the campaign that brought them in.
How GoHighLevel Form Embedding Works
GoHighLevel provides a few ways to embed forms on external websites. Understanding your options helps you choose the right approach for your setup.
Method 1: Native Form Embed Script
GoHighLevel generates an embed snippet for every form you create. You can find it by going to Sites > Forms, selecting your form, and clicking the embed or share icon. The native embed code looks something like this:
1<iframe2 src="https://link.msgsndr.com/widget/form/YOUR_FORM_ID"3 style="width:100%;height:500px;border:none;border-radius:4px"4 id="inline-YOUR_FORM_ID"5 data-layout="{'id':'INLINE'}"6 data-trigger-type="alwaysShow"7 data-trigger-value=""8 data-activation-type="alwaysActivated"9 data-activation-value=""10 data-deactivation-type="neverDeactivate"11 data-deactivation-value=""12 data-form-name="Your Form Name"13 data-height="500"14 data-layout-iframe-id="inline-YOUR_FORM_ID"15 data-form-id="YOUR_FORM_ID"16 title="Your Form Name"17></iframe>18<script src="https://link.msgsndr.com/js/form_embed.js"></script>
This is the simplest approach -- paste it into your page and it works. However, it does not automatically forward UTM parameters from the parent page URL into the form.
Method 2: Iframe Embed with UTM Passthrough (JavaScript)
This is where the real power comes in. By using a small JavaScript snippet, you can dynamically build the iframe URL and append whatever UTM parameters are present in the current page URL. This means the UTM data gets passed into the form as URL parameters, which GHL can then capture in hidden fields.
Setting Up UTM Tracking on Your GHL Form
Before writing any code, you need to configure your GHL form to receive UTM data.
Step 1: Add Hidden Fields to Your Form
Open your form in the GHL form builder and add five hidden custom fields:
- utm_source
- utm_medium
- utm_campaign
- utm_term
- utm_content
To do this, add a Text field for each parameter, set the label to the UTM parameter name, and then toggle the field to Hidden. Alternatively, you can create custom contact fields in your GHL settings first and then map them in the form builder.
The key is that the field names in the form must match the UTM parameter names exactly. When a form is loaded with URL parameters that match hidden field names, GHL will auto-populate those hidden fields with the corresponding values.
Step 2: Create Matching Custom Fields in GHL
Go to Settings > Custom Fields and create custom contact fields for each UTM parameter if you have not already. These fields store the UTM data on the contact record so you can use them in:
- Automation workflow conditions
- Smart lists and segments
- Pipeline reporting
- Custom dashboards and attribution reports
The JavaScript Embed Code
Here is the complete JavaScript snippet that embeds your GHL form on any external website and automatically passes UTM parameters from the page URL into the form.
1<div id="ghl-form-container"></div>2<script>3 // ===== CONFIGURATION =====4 var formId = 'YOUR_FORM_ID'; // Replace with your GHL form ID5 var formHeight = '500px'; // Adjust height as needed67 // ===== UTM PARAMETER EXTRACTION =====8 function getURLParameter(name) {9 var results = new RegExp('[?&]' + name + '=([^&#]*)').exec(window.location.search);10 return results ? decodeURIComponent(results[1].replace(/\+/g, ' ')) : '';11 }1213 var utmParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'];14 var baseUrl = 'https://link.msgsndr.com/widget/form/' + formId;15 var queryParts = [];1617 for (var i = 0; i < utmParams.length; i++) {18 var value = getURLParameter(utmParams[i]);19 if (value && value.trim().length > 0) {20 queryParts.push(utmParams[i] + '=' + encodeURIComponent(value));21 }22 }2324 var formUrl = baseUrl;25 if (queryParts.length > 0) {26 formUrl += '?' + queryParts.join('&');27 }2829 // ===== CREATE AND INSERT IFRAME =====30 var iframe = document.createElement('iframe');31 iframe.setAttribute('id', 'ghl-form-' + formId);32 iframe.setAttribute('src', formUrl);33 iframe.setAttribute('scrolling', 'no');34 iframe.style.border = 'none';35 iframe.style.width = '100%';36 iframe.style.height = formHeight;3738 var script = document.createElement('script');39 script.type = 'text/javascript';40 script.src = 'https://link.msgsndr.com/js/form_embed.js';4142 var container = document.getElementById('ghl-form-container');43 container.appendChild(iframe);44 container.appendChild(script);45</script>
How to Use This Code
- Replace YOUR_FORM_IDFORMID` with your actual GHL form ID. You can find this in the form embed code or in the form URL inside GHL.
- Adjust formHeight if your form needs more or less vertical space.
- Paste the entire snippet into the HTML of your external website wherever you want the form to appear.
- Make sure the page receives traffic with UTM-tagged URLs so the parameters are available in the URL for the script to capture.
How It Works
The script does the following:
- Reads the current page URL and extracts any UTM parameters present.
- Builds the GHL form iframe URL with those UTM values appended as query parameters.
- Creates the iframe element and injects it into the page.
- When the form loads inside the iframe, GHL recognizes the URL parameters and auto-fills the matching hidden fields.
- When the visitor submits the form, the UTM data is saved to the contact record.
Preserving UTM Parameters Across Multiple Pages
One common problem is that a visitor might land on your homepage with UTM parameters in the URL but then navigate to a different page before filling out a form. At that point, the UTM parameters are gone from the URL.
To solve this, you can store UTM parameters in the browser's local storage or cookies when the visitor first arrives, and then read from storage when rendering the form. Here is an enhanced version:
1<script>2 // Store UTM params on first visit3 (function() {4 var utmParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'];5 var params = new URLSearchParams(window.location.search);67 for (var i = 0; i < utmParams.length; i++) {8 var value = params.get(utmParams[i]);9 if (value) {10 localStorage.setItem(utmParams[i], value);11 }12 }13 })();14</script>
Place this script in your site header so it runs on every page load. Then modify the form embed script to read from local storage as a fallback:
1function getUTMValue(name) {2 // First check the current URL3 var params = new URLSearchParams(window.location.search);4 var urlValue = params.get(name);5 if (urlValue) return urlValue;67 // Fall back to stored value8 return localStorage.getItem(name) || '';9}
This ensures UTM data is captured even if the visitor navigates to an internal page before converting.
Using UTM Data for Attribution Reporting in GHL
Once UTM data is flowing into your contact records, you can put it to work.
Build Smart Lists for Campaign Segmentation
Create Smart Lists filtered by UTM values to group contacts by traffic source. For example:
- All leads from Google Ads: filter where utm_source equals google
- All leads from a specific campaign: filter where utm_campaign equals your campaign name
- All leads from email: filter where utm_medium equals email
Trigger Automations Based on Source
Use UTM data in workflow triggers and conditions. For example:
- Route leads from paid campaigns to a faster follow-up sequence
- Tag contacts differently based on their acquisition channel
- Assign leads from high-value campaigns directly to senior sales reps
Build Custom Attribution Dashboards
Use the reporting features in GHL along with UTM custom fields to build dashboards that show:
- Lead volume by source and medium
- Cost per lead by campaign (when combined with ad spend data)
- Conversion rates by traffic source
- Revenue attribution by campaign
Troubleshooting Common Issues
UTM values are not being captured:
- Verify your hidden form fields are named exactly `utmsource`, `utmmedium`, etc.
- Check that the URL parameters are present in the page URL before the form loads.
- Use your browser's developer tools to inspect the iframe src attribute and confirm the UTM parameters are being appended.
Form is not displaying:
- Confirm your form ID is correct and the form is published in GHL.
- Check for JavaScript errors in the browser console.
- Make sure the ghl-form-container div exists on the page before the script runs.
UTM data shows "null" or "undefined":
- The script filters out null and empty values. If you are seeing these, check that your getURLParameter function is returning clean results.
- Ensure the URL encoding is correct -- special characters in UTM values can cause parsing issues.
Form height is too short or too tall:
- Adjust the formHeight variable. For most forms, 500px to 700px works well. For longer forms, increase to 800px or more.
Wrapping Up
Capturing UTM parameters on your GoHighLevel forms is one of the highest-impact tracking improvements you can make. It takes about 15 minutes to set up, costs nothing, and gives you direct attribution data on every lead that enters your pipeline.
The combination of hidden form fields, a simple JavaScript embed, and local storage for persistence covers the vast majority of use cases agencies encounter. Once the data is flowing, you can build reports, optimize campaigns, and prove ROI with confidence.
Get Started
Ready to try GoHighLevel?
Pick between a 14-day standard trial or our 30-day extended trial on the same page. Full feature access, 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.
