<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Emily Grace</title>
    <description>The latest articles on DEV Community by Emily Grace (@emily_grace_e783ccee3239e).</description>
    <link>https://dev.to/emily_grace_e783ccee3239e</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3814228%2Fed5a19c5-22e1-4e22-91dd-a66751976321.png</url>
      <title>DEV Community: Emily Grace</title>
      <link>https://dev.to/emily_grace_e783ccee3239e</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/emily_grace_e783ccee3239e"/>
    <language>en</language>
    <item>
      <title>Consent Mode v2: The Load Order That Decides What Google Tags Do</title>
      <dc:creator>Emily Grace</dc:creator>
      <pubDate>Tue, 13 Oct 2026 10:43:10 +0000</pubDate>
      <link>https://dev.to/emily_grace_e783ccee3239e/consent-mode-v2-the-load-order-that-decides-what-google-tags-do-2opf</link>
      <guid>https://dev.to/emily_grace_e783ccee3239e/consent-mode-v2-the-load-order-that-decides-what-google-tags-do-2opf</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Call the consent &lt;code&gt;default&lt;/code&gt; command before the Google tag or GTM snippet loads.&lt;/li&gt;
&lt;li&gt;Give an async banner time to respond with &lt;code&gt;wait_for_update&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Send an &lt;code&gt;update&lt;/code&gt; when the visitor accepts, and again when they withdraw.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;region&lt;/code&gt; when UK, EU and US visitors need different defaults.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If GA4 and Google Ads disagree about your EEA traffic, or conversion modelling doesn't seem to start, check the order of your consent code first. Google's developer guide says the order is "vital" and that consent defaults won't work if the code runs out of order. Tags can then run with no consent state at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Defaults go first
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataLayer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataLayer&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;gtag&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;&lt;span class="nx"&gt;dataLayer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;);}&lt;/span&gt;
  &lt;span class="nf"&gt;gtag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;consent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ad_storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;denied&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ad_user_data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;denied&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ad_personalization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;denied&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;analytics_storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;denied&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wait_for_update&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- Google tag or GTM snippet loads after this --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ad_user_data&lt;/code&gt; and &lt;code&gt;ad_personalization&lt;/code&gt; are the two parameters added in v2. Since March 2024, Google has required consent from EEA users for advertisers who want to keep measurement, ad personalisation and remarketing features.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Update on accept and on withdrawal
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;gtag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;consent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;update&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ad_storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;granted&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ad_user_data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;granted&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ad_personalization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;granted&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;analytics_storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;granted&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Withdrawal is the same call with &lt;code&gt;'denied'&lt;/code&gt;. Make sure your preference centre sends it too, or a withdrawal won't reach Google.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Basic or advanced
&lt;/h2&gt;

&lt;p&gt;Basic mode blocks Google tags until the visitor consents. Advanced mode loads them in a denied state, and they send cookieless pings that Google uses to model conversions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters to the business
&lt;/h2&gt;

&lt;p&gt;The order decides whether tags set cookies before anyone has chosen, and whether you get modelled conversions for people who decline.&lt;/p&gt;

&lt;p&gt;If you would rather not hand-write this, &lt;a href="https://seers.ai/google-consent-mode-v2/" rel="noopener noreferrer"&gt;Seers handles Consent Mode v2&lt;/a&gt; by setting all four signals from the banner choice, in basic or advanced mode. Seers is listed as a Gold partner in Google's CMP Partner Program.&lt;/p&gt;

&lt;p&gt;Consent Mode only passes the choice to Google. Records, withdrawals and other vendors are part of wider &lt;a href="https://seers.ai/blogs/consent-management-best-practices/" rel="noopener noreferrer"&gt;consent management best practices&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Implementing Server-Side Consent Tracking in eCommerce</title>
      <dc:creator>Emily Grace</dc:creator>
      <pubDate>Mon, 09 Mar 2026 10:07:31 +0000</pubDate>
      <link>https://dev.to/emily_grace_e783ccee3239e/implementing-server-side-consent-tracking-in-ecommerce-2ffa</link>
      <guid>https://dev.to/emily_grace_e783ccee3239e/implementing-server-side-consent-tracking-in-ecommerce-2ffa</guid>
      <description>&lt;p&gt;If you are building or maintaining an eCommerce stack, consent management is no longer just a legal checkbox. It directly impacts your data pipeline, analytics accuracy, and ad performance. Let us get into the technical side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Client-Side Tracking Breaks
&lt;/h2&gt;

&lt;p&gt;Client-side tracking via JavaScript tags relies on the browser. The problem? Ad blockers, browser privacy settings, and ITP (Intelligent Tracking Prevention) in Safari strip or block these scripts. You end up with incomplete event data and broken attribution models.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server-Side Tagging: The Fix
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://seers.ai/server-side-tagging/" rel="noopener noreferrer"&gt;Server-side tagging&lt;/a&gt; moves your tag execution from the client browser to your own server container. Events fire server-to-server, bypassing browser restrictions entirely. This means better data fidelity, faster page loads (fewer client scripts), and improved consent compliance.&lt;br&gt;
Here is a simplified flow: User visits site. Consent banner fires via &lt;a href="https://seers.ai/" rel="noopener noreferrer"&gt;SeersAI&lt;/a&gt;. On consent accept, events are routed to your server container. Server container forwards to GA4, Meta CAPI, or any endpoint. No browser dependency in the data chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Consent State Integration
&lt;/h2&gt;

&lt;p&gt;SeersAI exposes a consent state API you can integrate with your tag manager. On consent change, the consent state updates. Your server container reads the state before firing any tag. This makes your implementation fully &lt;a href="https://seers.ai/regulation/gdpr/" rel="noopener noreferrer"&gt;GDPR&lt;/a&gt; and &lt;a href="https://seers.ai/regulation/ccpa/" rel="noopener noreferrer"&gt;CCPA&lt;/a&gt; compliant without manual scripting on every new tag.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shopify Developers
&lt;/h2&gt;

&lt;p&gt;If your client runs Shopify, the &lt;a href="https://apps.shopify.com/seers-cookie-consent" rel="noopener noreferrer"&gt;SeersAI Shopify plugin&lt;/a&gt; handles consent banner injection and consent state management out of the box. You can hook into the consent state via their JS API to conditionally load analytics and marketing scripts.&lt;br&gt;
Want the full implementation walkthrough including tag manager setup, API reference, and testing checklist? Read the full article for the complete technical guide.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>productivity</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
