Knowledge base

Developer setup

Google Consent Mode v2 with gtag.js: code and timing

Place the default command before Google tags, update four consent signals from your banner and test mixed preferences without reloading.

Editorial illustration for Google Consent Mode v2 with gtag.js: code and timing
Editorial illustration by Consentory.

In brief

For a direct gtag.js install, command order in the page head is the first thing to verify.

Place the default before Google tags

Create dataLayer and gtag, then call gtag('consent', 'default', ...) before loading the Google tag or sending config/event commands. Start with denied values when no preference is known. Google must see the state before measurement begins.

The interactive example below generates only the consent commands. Insert them into your site's actual tag sequence and replace the example update with your banner callback.

For the meaning of each default and update value, use the four-signal Consent Mode overview alongside your code review.

Use all four v2 parameters

analytics_storage controls Analytics storage. ad_storage controls advertising storage. ad_user_data and ad_personalization carry additional advertising choices. Do not grant the latter two just because analytics is enabled.

Keep one deliberate mapping between your banner's analytics and advertising categories and these signals. If a category is absent, decide how your policy treats it before writing the mapping.

Update on the same page

When the visitor changes a choice, call gtag('consent', 'update', ...) immediately. Check the state in Tag Assistant without refreshing. Save the preference separately if the visitor should be recognized on the next page.

If your CMP script loads asynchronously, an update from it cannot retroactively protect an earlier page request. Put a safe default in the head before any Google tag.

Test mixed choices and withdrawal

Test accept all, reject all, analytics only, and a later withdrawal. In Tag Assistant, compare the Consent tab before and after each action. In the browser Network and Storage panels, check what actually loaded or was stored.

  • Analytics only: analytics_storage granted; all three advertising signals denied.
  • Reject all: four signals denied.
  • Withdrawal: the update changes state immediately, and future hits follow that state.

Avoid two owners for the same state

If GTM and direct gtag.js both set consent, you can create competing defaults or updates. Pick one clearly documented owner for default and update commands. Inspect the final rendered page, not only the source component.

Try it

Build a consent default and update example

Select a sample visitor choice. The default remains denied; only the update changes.

// Run before loading the Google tag.
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('consent', 'default', {
  'analytics_storage': 'denied',
  'ad_storage': 'denied',
  'ad_user_data': 'denied',
  'ad_personalization': 'denied'
});

// In your banner's choice callback, on the same page:
gtag('consent', 'update', {
  'analytics_storage': 'denied',
  'ad_storage': 'denied',
  'ad_user_data': 'denied',
  'ad_personalization': 'denied'
});

Example for direct gtag.js only. If GTM owns consent, use its template APIs and Consent Initialization instead. Review category mapping and script order before publishing.

Continue with a related guide

Primary sources

Reviewed 15 October 2026. Validate product interfaces and requirements for your own implementation.

Check the implementation on your site

Consentory helps teams inspect trackers, configure prior blocking and document consent choices. The guides above give you a test plan before rollout.