How to Set Up Google Ads Enhanced Conversions on Duda Using GTM


Callum Wells • 27 March 2026

What Are Enhanced Conversions (and Why Should You Care)?

When someone fills in a form on your website and that counts as a conversion, Google Ads needs to match that conversion back to the person who clicked your ad. Normally it does this with cookies. But cookies are becoming less reliable - browsers block them, people clear them, and privacy rules limit what they can do.

Enhanced Conversions give Google a backup method. When someone submits a form, you take the data they typed in (like their email address or phone number), scramble it into a code that can't be reversed (called hashing), and send that scrambled version to Google. Google then matches it against the data they already have on that user from their Google account.

The result: better conversion tracking, better data in your ad account, and better decisions on where your budget goes.

Important: The data is hashed before it leaves the browser. Google never sees the actual email or phone number from your site. It only sees the scrambled version.

Does This Work With Both Duda Form Types?

Yes. This guide works with both the standard Contact Form widget and the newer Advanced Form widget (the flex-based one in Editor 2.0).

Both form types render as standard HTML <form> elements in the browser. The hashing script in this guide uses document.querySelectorAll('form') to find all forms on the page, so it catches both types automatically. As long as your email field uses type="email" and your phone field uses type="tel" (which Duda sets by default for both form types), the script will detect and hash the data correctly.

The only difference between the two is how the success state looks after submission. We cover both scenarios in the trigger setup section below.

What You'll Need Before Your Start

- A Duda website with at least one form (Contact Form or Advanced Form) that you want to track as a conversion
- A Google Ads account with a conversion action already set up
- A Google Tag Manager (GTM) container already connected to your Duda site
- About 30 minutes

If you haven't connected GTM to Duda yet, go to your Duda site editor, click Site Settings > Head HTML , and paste your GTM snippet there. That's the <!-- Google Tag Manager --> script that GTM gives you when you set up a container.

Step 1: Turn On Enhanced Conversions in Google Ads

Before touching GTM, you need to tell Google Ads that you'll be sending enhanced conversion data.

1. Log in to Google Ads
2. Click Goals in the left menu
3. Click Conversions then Summary
4. Click the conversion action you want to enhance (e.g. "Form Submission" or "Lead")
5. Scroll down to Enhanced conversions and click Turn on enhanced conversions
6. Select Google Tag Manager as your setup method
7. Click Save

That's it on the Google Ads side. You're telling Google: "I'm going to send you hashed data through GTM. Be ready for it."

Step 2: Create a Custom HTML Tag to Capture and Hash Form Data

This is the core of the setup. You're going to create a tag in GTM that watches for form submissions on your Duda site, grabs the email and phone fields, hashes them, and stores them so GTM can use them.

1. Open Google Tag Manager
2. Select your Duda site's container
3. Click Tags in the left menu
4. Click New
5. Name it: Enhanced Conversions - Hash Form Data
6. Click Tag Configuration and choose Custom HTML
7. Paste the following code:

Html
 <script> 
 (function() { 
 function sha256(str) { 
 var buffer = new TextEncoder().encode(str.trim().toLowerCase()); 
 return crypto.subtle.digest('SHA-256', buffer).then(function(hash) { 
 return Array.from(new Uint8Array(hash)) 
 .map(function(b) { return b.toString(16).padStart(2, '0'); }) 
 .join(''); 
 }); 
 } 
  
 function findInputByType(form, types, namePatterns) { 
 var inputs = form.querySelectorAll('input, select, textarea'); 
 for (var i = 0; i < inputs.length; i++) { 
 var input = inputs[i]; 
 for (var t = 0; t < types.length; t++) { 
 if (input.type === types[t]) return input; 
 } 
 for (var n = 0; n < namePatterns.length; n++) { 
 var name = (input.name || '').toLowerCase(); 
 var id = (input.id || '').toLowerCase(); 
 var placeholder = (input.placeholder || '').toLowerCase(); 
 if (name.indexOf(namePatterns[n]) > -1 || 
 id.indexOf(namePatterns[n]) > -1 || 
 placeholder.indexOf(namePatterns[n]) > -1) { 
 return input; 
 } 
 } 
 } 
 return null; 
 } 
  
 var forms = document.querySelectorAll('form'); 
  
 forms.forEach(function(form) { 
 if (form.dataset.ecBound) return; 
 form.dataset.ecBound = 'true'; 
  
 form.addEventListener('submit', function() { 
 var emailInput = findInputByType(form, ['email'], ['email', 'e-mail']); 
 var phoneInput = findInputByType(form, ['tel'], ['phone', 'mobile', 'telephone']); 
  
 var promises = []; 
 var userData = {}; 
  
 if (emailInput && emailInput.value) { 
 promises.push( 
 sha256(emailInput.value).then(function(hash) { 
 userData.sha256_email_address = hash; 
 }) 
 ); 
 } 
  
 if (phoneInput && phoneInput.value) { 
 promises.push( 
 sha256(phoneInput.value).then(function(hash) { 
 userData.sha256_phone_number = hash; 
 }) 
 ); 
 } 
  
 Promise.all(promises).then(function() { 
 window.enhanced_conversion_data = userData; 
 }); 
 }); 
 }); 
 })(); 
 </script> 

What this code does in plain English:

- It finds every form on the page (both Contact Forms and Advanced Forms)
- It attaches a listener that runs when someone submits a form
- When the form is submitted, it looks for email and phone fields
- It takes whatever the person typed, converts it to lowercase, removes any extra spaces, and scrambles it using SHA-256 (the same hashing method Google requires)
- It stores the scrambled data in a place where GTM can pick it up ( window.enhanced_conversion_data )
- It also saves a backup copy in sessionStorage (needed if the form redirects to a thank you page)

Now set the trigger:

1. Click Triggering
2. Click the + icon to create a new trigger
3. Name it: All Pages - DOM Ready
4. Choose DOM Ready as the trigger type
5. Select All DOM Ready Events
6. Save the trigger, then save the tag

You want this running on DOM Ready (not Page View) because Duda forms load dynamically, and you need the form elements to exist before the script tries to find them.

Step 3: Create a User-Provided Data Variable

GTM needs a variable that points to the hashed data you stored in Step 2.

1. Click Variables in the left menu
2. Under User-Defined Variables , click New
3. Name it: Enhanced Conversion Data
4. Click Variable Configuration
5. Choose JavaScript Variable
6. In the Global Variable Name field, type: enhanced_conversion_data
7. Save

This variable now reads from window.enhanced_conversion_data , which is where your hashing script stores the scrambled email and phone data.

Step 4: Set Up Your Conversion Tag with Enhanced Conversions

If you already have a Google Ads Conversion Tracking tag in GTM, you'll edit it. If not, create a new one.

1. Go to Tags
2. Either click your existing conversion tag or click New
3. Name it: Google Ads Conversion - Form Submit (or whatever makes sense)
4. Click Tag Configuration
5. Choose Google Ads Conversion Tracking
6. Fill in your Conversion ID ( AW-XXXXXXX ) and Conversion Label from your Google Ads conversion action settings
7. Set Conversion Value and Currency Code if applicable
8. Scroll down and tick Include user-provided data from your website
9. Under User-Provided Data , choose Manual Configuration

For the user-provided data fields, create two separate JavaScript Variables:

  • Variable name: EC - Hashed Email / Type: JavaScript Variable / Global Variable Name: enhanced_conversion_data.sha256_email_address
  • Variable name: EC - Hashed Phone / Type: JavaScript Variable / Global Variable Name: enhanced_conversion_data.sha256_phone_number

Then in your conversion tag's user-provided data section, map Email to EC - Hashed Email and Phone to EC - Hashed Phone .

Step 5: Set the Conversion Trigger

Your conversion tag needs to fire when the form is actually submitted. There are two ways to handle this on Duda, depending on whether your form shows an inline thank you message or redirects to a separate page.

Option A: Inline Thank You Message (Form Stays on the Same Page)

Both the Contact Form and Advanced Form can show inline success messages after submission. To detect this, add a small script to your Duda site's Body End HTML (Site Settings > Body End) that watches for the success message to appear and pushes an event to GTM:

Html
 <script> 
 (function() { 
 var observer = new MutationObserver(function(mutations) { 
 mutations.forEach(function(mutation) { 
 mutation.addedNodes.forEach(function(node) { 
 if (node.nodeType === 1 && node.classList && 
 (node.classList.contains('form-success') || 
 node.classList.contains('form-confirmation'))) { 
 window.dataLayer = window.dataLayer || []; 
 window.dataLayer.push({ event: 'duda_form_submit' }); 
 } 
 }); 
 }); 
 }); 
 observer.observe(document.body, { childList: true, subtree: true }); 
 })(); 
 </script> 

Why the broad selector list? The standard Contact Form and Advanced Form use different CSS classes for their success states. This script checks for multiple possible class names and also watches for attribute changes (some forms toggle visibility via inline styles rather than adding classes). The offsetHeight > 0 check ensures we only fire when the element is actually visible.

Then in GTM, create a Custom Event trigger with the event name duda_form_submit and assign it to your conversion tag.

Option B: Thank You Page Redirect

If your form redirects to a /thank-you page after submission:

1. Create a new trigger in GTM
2. Name it: Thank You Page View
3. Choose Page View as the trigger type
4. Set it to fire on Some Page Views
5. Set the condition: Page Path contains /thank-you (or whatever your thank you page URL is)
6. Save and assign this trigger to your conversion tag

Important: The hashing script runs on the form page, but the conversion fires on the thank you page. The hashed data stored in window.enhanced_conversion_data won't survive the page change. That's why the hashing script in Step 2 already includes a sessionStorage backup.

You also need a recovery script. Create a separate Custom HTML tag in GTM that fires on the thank you page (DOM Ready trigger filtered to your thank you page path):

Html
 <script> 
 (function() { 
 try { 
 var stored = sessionStorage.getItem('enhanced_conversion_data'); 
 if (stored) { 
 window.enhanced_conversion_data = JSON.parse(stored); 
 sessionStorage.removeItem('enhanced_conversion_data'); 
 } 
 } catch(e) {} 
 })(); 
 </script> 

Make sure this recovery tag fires before your conversion tag. In GTM, edit your conversion tag, expand Advanced Settings > Tag Sequencing , and set the recovery tag as a setup tag.

Step 6: Preview, Test, and Publish

Preview first. Always.

1. Click Preview in GTM
2. Enter your Duda site URL
3. Navigate to the page with your form
4. Fill in the form with a test email and phone number
5. Submit the form

What to check in GTM's preview panel:

- Your Enhanced Conversions - Hash Form Data tag should show as "Fired" on DOM Ready
- After form submission, click on the Variables tab and look for enhanced_conversion_data - it should contain sha256_email_address and/or sha256_phone_number values (long strings of letters and numbers)
- Your conversion tag should fire on the form submission event (or page view of the thank you page)
- The conversion tag summary should show user-provided data is being sent

If the hashed data isn't showing:

- Inspect the form in your browser and check what the email input's type and name attributes are. Duda sometimes uses generic names - if so, adjust the findInputByType patterns in the hashing script
- Make sure the Custom HTML tag is firing on DOM Ready, not Page View
- If you're using an Advanced Form with multi-step pages, the email field might not be on the first step. The script attaches on DOM Ready, so fields on later steps should still be caught when the form is submitted
- Check the browser console for any errors

Once everything looks right:

1. Go back to GTM
2. Click Submit
3. Name your version something useful like "Added Enhanced Conversions for form submissions"
4. Click Publish

Step 7: Verify in Google Ads

Enhanced Conversions don't show results instantly. Give it 48-72 hours, then check:

1. Go to Google Ads
2. Click Goals > Conversions > Summary
3. Click your conversion action
4. Look for the Enhanced conversions section - it should show a match rate percentage

A match rate of 30-60% is normal and healthy. It won't be 100% because not everyone uses the same email for your form as they do for their Google account, and that's fine. Even a 30% match rate significantly improves your conversion data.

Quick Reference: What Goes Where

  • GTM container snippet - Duda Site Settings > Head HTML - Loads GTM on your sit
  • Hash Form Data tag - GTM (Custom HTML, DOM Ready) - Scrambles form data and stores it
  • Enhanced Conversion Data variable - GTM (JavaScript Variable) - Points GTM to the hashed data
  • Conversion Tracking tag - GTM (Google Ads Conversion) - Sends conversion + hashed data to Google
  • MutationObserver script - Duda Body End HTML (optional) - Detects inline form success for triggering
  • sessionStorage recovery script - GTM (Custom HTML, thank you page only) - Recovers hashed data after page redirect

Common Questions

  • Does this work with Duda's built-in form analytics?

    This runs completely separately from Duda's own form tracking. They don't interfere with each other.

  • What about multi-step Advanced Forms?

    The script attaches to the form's submit event, which only fires when the user clicks the final submit button (not when navigating between steps). So even if the email field is on step 1 and the submit button is on step 3, it will still capture the data correctly because all fields remain in the DOM.

  • What if my form has name and address fields too?

    You can hash and send those as well. Google supports sha256_first_name , sha256_last_name , sha256_street , and more. Add extra findInputByType calls for each field and include them in the userData object. See Google's documentation for the full list of supported fields.

  • Is this GDPR compliant?

    The hashing happens in the browser before any data is sent to Google. Google receives a scrambled string, not the actual personal data. That said, you still need to disclose in your privacy policy that you use conversion tracking and share hashed data with Google for ad measurement. The hashing doesn't exempt you from needing consent - you should still be collecting cookie/tracking consent where required.

  • Can I use this without GTM (using gtag.js directly)?

    Yes. If you're using the global site tag instead of GTM, the setup is simpler - you use gtag('set', 'user_data', {...}) before firing the conversion event. But GTM gives you more control and easier debugging, which is why this guide focuses on that approach.

  • What if I have multiple forms on one page?

    The script handles this automatically. It attaches to every form on the page and only hashes data from the form that was actually submitted.

Wrapping Up

Enhanced Conversions are one of the best things you can do for your Google Ads performance on Duda. The setup takes a bit of work because Duda doesn't have a native integration for it, but once it's running, it's set and forget.

The match rate data alone makes it worth doing - you'll finally know how much conversion data you've been missing, and your Smart Bidding strategies will have significantly more signal to work with.

    Join For Free

    Become a member today on our free tier and get instant access to 5 custom components.

    White label Duda development, from the team behind Agency Genius

    WebHero now offers white label builds, custom widgets and more for Duda agencies. Your clients, our dev team.

    Recent Articles