Google Ads conversion tracking belongs to the targeting category of TermsFeed Free Cookie Consent. Send ad_storage, ad_user_data, and ad_personalization through Google Consent Mode v2 from your callback, with the Google Ads snippet untagged, or tagged so that, by default, it waits for the answer. Both approaches keep Google Ads cookies out of the browser for visitors who decline. Only the untagged snippet sends Google cookieless pings before the answer.

Google asks advertisers to collect consent from visitors in the European Economic Area (EEA), according to the Google Ads EU user consent policy page. Advertisers share consent signals with Google for measurement, ad personalization, and remarketing. Read how basic and advanced consent mode differ in the Google Ads Help page About consent mode.

Start with the Cookie Consent code from the TermsFeed generator already on your pages. Note your Google Ads tag ID, which starts with AW-, and the conversion label of each conversion action. Google Ads shows both on its tag setup screen.

Load the Google tag untagged, and set every signal to denied in the first script in <head>, after only the charset meta. Then send the 3 ad signals from the user_consent_saved callback, granted once the visitor accepts targeting. Google Ads then receives cookieless pings from a visitor who declines, and Google uses them for modeled conversions only once your ad traffic meets the conversion modeling thresholds.

The denied default goes above the Google tag, any Google Tag Manager container, and the Cookie Consent code. Replace AW-XXXXXXXXX in the Google tag after the default with your Google Ads tag ID.

<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('consent', 'default', {
    'ad_storage': 'denied',
    'ad_user_data': 'denied',
    'ad_personalization': 'denied',
    'analytics_storage': 'denied',
    'functionality_storage': 'denied',
    'personalization_storage': 'denied',
    'wait_for_update': 500
  });
</script>
<script async src="https://www.googletagmanager.com/gtag/js?id=AW-XXXXXXXXX"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'AW-XXXXXXXXX');
</script>

Add this event snippet to the conversion page, untagged and below the Google tag, and replace the ID and the label with the values Google Ads shows.

<script>
  gtag('event', 'conversion', {'send_to': 'AW-XXXXXXXXX/CONVERSION_LABEL'});
</script>

The callback sets each Google signal to granted or denied from its category in details, so details.targeting decides the 3 ad signals. Add the user_consent_saved_on_page_load and callbacks options to the run() call the TermsFeed generator wrote, beside its other options.

"user_consent_saved_on_page_load": true,
"callbacks": {
  "user_consent_saved": (details) => {
    gtag('consent', 'update', {
      'analytics_storage': details.tracking ? 'granted' : 'denied',
      'ad_storage': details.targeting ? 'granted' : 'denied',
      'ad_user_data': details.targeting ? 'granted' : 'denied',
      'ad_personalization': details.targeting ? 'granted' : 'denied',
      'functionality_storage': details.functionality ? 'granted' : 'denied',
      'personalization_storage': details.functionality ? 'granted' : 'denied'
    });
  }
}

Keep user_consent_saved_on_page_load: true. Without the option, the callback skips every later page load of a visitor who answered, and the Google tag on those pages keeps the denied default. The untagged Google tag is not held, so it usually loads first and takes the update within its wait_for_update time.

The callback sends denied for the 3 ad signals as soon as a visitor who turns targeting off saves the choice. Follow every step of this setup, including the complete page, in Set Up Google Consent Mode v2.

Approach 2: Tag the Google Ads snippet with targeting

Tag the Google tag and the event snippet with targeting. Keep the untagged denied default, the user_consent_saved callback, and user_consent_saved_on_page_load: true of the untagged setup, because Google Ads needs ad_user_data and ad_personalization even from a tagged Google tag. No request reaches Google Ads before the visitor accepts, and the released tag starts with the 3 ad signals granted. Google calls this setup basic consent mode. Google receives nothing from visitors who decline, not even the consent status, so conversion modeling falls back to a general model.

Put this tagged Google tag in <head>, where Google asks for it.

<script type="text/plain" data-cookie-consent="targeting" async src="https://www.googletagmanager.com/gtag/js?id=AW-XXXXXXXXX"></script>
<script type="text/plain" data-cookie-consent="targeting">
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'AW-XXXXXXXXX');
</script>

Place this tagged event snippet on the conversion page after the Google tag, because Cookie Consent runs the tagged scripts of a category in page order.

<script type="text/plain" data-cookie-consent="targeting">
  gtag('event', 'conversion', {'send_to': 'AW-XXXXXXXXX/CONVERSION_LABEL'});
</script>

Cookie Consent runs both tagged scripts at once for a visitor who accepts on the conversion page itself, with no reload, so Google Ads records that conversion. Read how tagged scripts run and keep their attributes in Block Scripts Until Consent.

The checks assume express consent with page_load_consent_levels left out or at the generator value ["strictly-necessary"], and the "I decline" button shown. Publish the change and clear any page cache before the check. The _gcl_au cookie in the Application tab shows the result of both approaches. Close every private window, then run the check in a new one, which does not hold a saved answer.

  1. Open your site in that window of Chrome, open DevTools, and select the Application tab. Under Cookies, your site does not list a _gcl_au cookie while the consent banner shows.
  2. Select the Network tab and type googleads in the filter box, then reload. The filter matches www.googleadservices.com and googleads.g.doubleclick.net, which Google lists for Google Ads in its Content Security Policy guide. With the tagged snippet, no request appears. With the untagged snippet, requests that appear do not store a cookie: the Application tab still does not list a _gcl_au cookie.
  3. Click the "I agree" button. The _gcl_au cookie appears in the Application tab.
  4. With either approach, open tagassistant.google.com in that same private window and connect it to your site, so the site it opens holds your answer. In the Tag Assistant Summary, select the most recent "Consent" event, open your Google tag, and select the "Consent" tab in its Output. The "On-page Update" column shows "Granted" for ad_storage, ad_user_data, and ad_personalization.
  5. Close every private window and open a new one. Open DevTools, type googleads in the Network filter, load your site, click the "I decline" button, and reload. No _gcl_au cookie appears in the Application tab, and with the tagged snippet the googleads filter stays empty.

Tag Assistant shows the consent state of each signal before and after the answer. Follow the full Tag Assistant check in Set Up Google Consent Mode v2.

Cookies Google Ads sets

Google Ads conversion tracking stores first-party cookies on your domain, each with a 90-day lifetime, according to the Google list of advertising cookies. List them in your Cookies Policy under targeting cookies.

Cookie Lifetime Set when
_gcl_au 90 days The Google tag runs with ad_storage granted
_gcl_aw 90 days A visitor arrives from a Google Ads click
_gcl_gb, _gcl_gs, _gcl_ag 90 days The Google tag runs other Google Ads measurement features with ad_storage granted

Google sets more cookies on its own domains, such as doubleclick.net, which the browser lists under those domains. In both approaches, the same Google tag sets them, and it follows the ad_storage signal for them as it does for _gcl_au.

Common mistakes with Google Ads

Find each mistake in your setup from Tag Assistant, the page source, or the Application tab.

  • The callback sends ad_storage alone. Google Ads reads ad_user_data and ad_personalization too, and a missing signal stays denied. Tag Assistant then shows "Denied" for ad_user_data and ad_personalization after the visitor accepts. Send all 3 from details.targeting.
  • The default runs after the Google tag. Tag Assistant reports that a tag read the consent state before a default was set. Move the default script above every Google script.
  • user_consent_saved_on_page_load is missing. The ad signals read "Granted" only on the page where the visitor accepted. Add "user_consent_saved_on_page_load": true to run().
  • A tagged and an untagged copy of the Google tag both load. Search the page source for gtag/js, and look for a tagged and an untagged copy. Pick one approach for the Google tag, or every conversion is counted twice.
  • A platform adds its own Google Ads tag. Shopify, WooCommerce plugins, and tag manager containers add an untagged copy that runs outside Cookie Consent. Search the page source and your tag manager container for your AW- ID to find every copy. Remove the copy there and keep only yours.
  • Google Analytics 4 and Google Ads share one tagged Google tag. A single tagged loader takes one category, so a visitor who accepts tracking alone sends nothing to Google Analytics 4 when the loader carries targeting. The page source shows both gtag('config', ...) calls inside one tagged script. Load a shared Google tag untagged in advanced consent mode, which grants analytics_storage and the ad signals separately.
  • You expect a withdrawal to delete _gcl_au. A denied signal stops new cookies, but neither Cookie Consent nor the signal deletes a cookie Google stored earlier. The Application tab still lists _gcl_au after the withdrawal. Delete the _gcl_au cookie from a callback with the pattern in Rejecting Does Not Delete Cookies Already Set.

Google Ads remarketing lists grow more slowly once the consent banner is live, because Google does not store a remarketing cookie for visitors who decline. Check the full mapping of each category to its Google signals in Map Categories to Vendor Consent Signals.