Articoli su: Integrazioni
Questo articolo è disponibile anche in:

Google Consent Mode in un custom pixel di Shopify (gtag.js)

Panoramica


Alcuni store caricano Google Analytics 4 (G-) o Google Ads (AW-) direttamente con gtag.js da un Shopify custom pixel (Settings > Customer events). Questo articolo ti fornisce codice pronto da incollare nel pixel, che applica Google Consent Mode Advanced a queste proprietà, usando il consenso che i visitatori danno sul banner di Pandectes.


Se le tue proprietà Google sono caricate da un container di Google Tag Manager, usa invece Google Consent Mode in un custom pixel di Shopify (Google Tag Manager).


Questa è una guida all'implementazione. Per i fondamenti sui comandi default e update e sulla modalità Advanced, consulta Consent Mode con gtag.js della documentazione di Google.


Prima di iniziare



Questo pixel è una metà di una configurazione in due parti. Nel Shopify Admin vai su Apps > Pandectes GDPR > Integrations, clicca su Configure nella scheda Google Consent Mode e attiva l'integrazione. Vedi Uso dell'integrazione Google Consent Mode. Google Consent Mode funziona con il piano Plus e superiori.


Un custom pixel di Shopify viene eseguito in un iframe sandbox con il proprio window, il proprio dataLayer e una copia di gtag.js. È separato dalla pagina dello storefront, e il consenso impostato in uno è invisibile all'altro. Quindi ciascuno richiede la propria configurazione:


Dove | Cosa viene eseguito lì | Cosa imposta la modalità di consenso--- | --- | --- |Pagina dello storefront | Tag Google in theme.liquid, il tuo container GTM, tag di altre app | L'integrazione Pandectes Google Consent ModeSandbox del pixel | Il gtag.js che carichi nel pixel e le sue proprietà | Il codice di questo articolo


Il pixel non sostituisce l'integrazione. Nulla nel pixel può raggiungere la pagina dello storefront, quindi senza l'integrazione lo storefront non ha alcuna modalità di consenso.


Usi Google Tag Manager?


Se il tuo store ha un container GTM, verifica se le tue proprietà Google sono già caricate lì. Di solito lo sono. Aggiungere un pixel che carica di nuovo la stessa proprietà GA4 o Google Ads duplica visualizzazioni di pagina, sessioni, acquisti e conversioni, e crea due stati di consenso in competizione.


La tua configurazione | Segui--- | --- |
| GA4 o Google Ads caricati da un container GTM | Google Consent Mode in un custom pixel di Shopify (Google Tag Manager) |
Senza GTM, proprietà caricate con gtag.js in un custom pixel | Questo articolo


Cosa copre questo codice


Il codice imposta solo lo stato del consenso. Invia a Google la policy predefinita dello store, applica la scelta del visitatore, la tiene sincronizzata con il banner e carica il tag Google, così i segnali di consenso hanno una destinazione. Da solo non invia dati di analytics o di conversione.


Pandectes fornisce solo il livello del consenso. Quali eventi invii, quali dati trasportano, come si collegano alla tua proprietà GA4 o alle conversioni di Google Ads e se il reporting è accurato sono di tua responsabilità. Pandectes non supporta né verifica il tracciamento costruito sopra questo codice.


Le tue iscrizioni agli eventi vanno nello stesso pixel


Inviare a Google gli eventi clienti di Shopify è lo scopo reale del pixel, e quelle iscrizioni devono stare nello stesso pixel, sotto il codice del consenso. Gli esempi in ogni snippet sono commentati di proposito. Decommentali o sostituiscili con i tuoi.


Ogni pixel che carica una proprietà Google ha bisogno della propria copia


Non puoi mettere il codice del consenso in un custom pixel e i tuoi eventi in un altro. Ogni pixel è un sandbox separato. Un pixel che carica GA4 o Google Ads senza il codice del consenso invia tutto con i valori predefiniti di Google, come se la modalità di consenso non esistesse, e Shopify non ti avvisa.


  • Un pixel carica le tue proprietà: una copia del codice, con gli eventi di quel pixel sotto.
  • Tre pixel caricano ciascuno una proprietà Google: tre copie, una in ogni pixel.
  • Se più pixel caricano la stessa proprietà, risolvi prima questa duplicazione.


Modalità Advanced e permesso del pixel


Questo codice ti dà la Google Consent Mode Advanced: il tag Google si carica a ogni visualizzazione di pagina, invia ping senza cookie finché il consenso è negato e passa alla misurazione completa una volta concesso il consenso. È ciò che permette a Google di modellare le conversioni dei visitatori che non acconsentono.


Per questo il pixel deve poter essere eseguito prima del consenso. Nel Shopify Admin vai su Settings > Customer events, apri il tuo custom pixel e, in Customer privacy, imposta Permission su Not required. Se lo imposti su Required, Shopify trattiene il pixel finché il visitatore non accetta: il tag Google non si carica mai prima del consenso e non vengono inviati ping senza cookie.


Se preferisci Basic mode (niente si carica finché non viene dato il consenso), non ti serve questo codice. Imposta Permission su Required, seleziona le categorie che ti servono e lascia che Shopify trattenga il pixel.


Come funziona il codice


Shopify fornisce al pixel il consenso del visitatore in init.customerPrivacy, ma non dice se si tratta del valore predefinito dello store o di una scelta che il visitatore aveva già fatto. Quindi il codice esegue sempre questi passaggi, in quest'ordine:


  1. consent default: la policy dello store, scritta nel codice.
  2. consent update: quello che contiene init.customerPrivacy. Se era solo il valore predefinito, non cambia nulla. Se era una scelta salvata, viene applicata prima del primo hit.
  3. Carica gtag.js e configura le tue proprietà Google.
  4. Resta in ascolto di visitorConsentCollected e invia un update ogni volta che il visitatore cambia la sua scelta.


In un custom pixel, analytics, browser e init sono disponibili direttamente, ma customerPrivacy si raggiunge tramite api. Chiamare customerPrivacy.subscribe(...) senza api. genera un ReferenceError.


I valori di consenso di Shopify corrispondono ai tipi di consenso di Google così:


Shopify | Google--- | --- |

analyticsProcessingAllowed

analytics_storage

marketingAllowed

ad_storage, ad_user_data, ad_personalization

preferencesProcessingAllowed

functionality_storage, personalization_storage

saleOfDataAllowed

Nessun equivalente in Consent Mode. È un segnale statunitense di vendita o condivisione per stato (vedi restricted_data_processing).

(sempre)

security_storage è sempre granted


Quale snippet ti serve?


Policy del tuo store | Usa--- | --- |Stessa policy in tutto il mondo: niente si attiva finché il visitatore non dà il consenso | Snippet 1 (un solo comando predefinito)Consenso raccolto solo in alcune regioni, consentito altrove | Snippet 2 (comandi predefiniti per regione)


Entrambi gli snippet supportano GA4, Google Ads o entrambi.


  1. Nel Shopify Admin vai su Settings > Customer events e clicca su Add custom pixel.
  2. Dai un nome al pixel e incolla uno degli snippet.
  3. Inserisci i tuoi ID tra START_MODIFY_FOR_YOUR_STORE e END_MODIFY_FOR_YOUR_STORE.
  4. Aggiungi in fondo le tue iscrizioni agli eventi.
  5. Imposta il permesso come descritto sopra, clicca su Save, poi su Connect.


Snippet 1: un solo comando predefinito


Un comando default senza regione, quindi si applica a ogni visitatore. Tutto è negato tranne security_storage.


/* START_MODIFY_FOR_YOUR_STORE */
const GA4_ID = ""; // e.g. "G-XXXXXXXXXX", leave empty if not used
const AW_ID = ""; // e.g. "AW-XXXXXXXXXX", leave empty if not used
const DEBUG = false; // true sends GA4 hits to DebugView while testing
/* END_MODIFY_FOR_YOUR_STORE */

const GRANTED = "granted";
const DENIED = "denied";
const GOOGLE_URL = "https://www.googletagmanager.com/gtag/js?id=";
const DEVELOPER_ID = "dMTZkMj";

/* Shopify customerPrivacy -> Google consent state */
const toConsentState = (cp) => ({
ad_storage: cp.marketingAllowed ? GRANTED : DENIED,
ad_user_data: cp.marketingAllowed ? GRANTED : DENIED,
ad_personalization: cp.marketingAllowed ? GRANTED : DENIED,
analytics_storage: cp.analyticsProcessingAllowed ? GRANTED : DENIED,
functionality_storage: cp.preferencesProcessingAllowed ? GRANTED : DENIED,
personalization_storage: cp.preferencesProcessingAllowed ? GRANTED : DENIED,
security_storage: GRANTED,
});

/* The pixel sandbox has its own dataLayer. */
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}

/* Pandectes developer ID. Identifies the implementation to Google,
* has no effect on your data. Leave it as it is. */
gtag("set", `developer_id.${DEVELOPER_ID}`, true);

/* STEP 1: store policy, before gtag.js loads. Applies to everyone. */
gtag("consent", "default", {
ad_storage: DENIED,
ad_user_data: DENIED,
ad_personalization: DENIED,
analytics_storage: DENIED,
functionality_storage: DENIED,
personalization_storage: DENIED,
security_storage: GRANTED,
});

/* STEP 2: visitor state, always sent. If it is only the default,
* nothing changes. If it is a saved choice, it lands before the first hit. */
gtag("consent", "update", toConsentState(init.customerPrivacy));

/* STEP 3: load the Google tag once and configure each property. */
const TAG_IDS = [GA4_ID, AW_ID].filter(Boolean);

if (TAG_IDS.length) {
gtag("js", new Date());

if (GA4_ID) {
gtag("config", GA4_ID, {
send_page_view: false,
...(DEBUG ? { debug_mode: true } : {}),
});
}

if (AW_ID) {
gtag("config", AW_ID);
}

const script = document.createElement("script");
script.async = true;
script.src = GOOGLE_URL + TAG_IDS[0];
document.head.appendChild(script);
}

/* STEP 4: follow the visitor's choices. Note the api. prefix. */
api.customerPrivacy.subscribe("visitorConsentCollected", (event) => {
gtag("consent", "update", toConsentState(event.customerPrivacy));
});

/* YOUR EVENT SUBSCRIPTIONS GO HERE, IN THIS SAME PIXEL.
* The examples are commented out on purpose. What you send is yours
* to own and verify. */

/* Page view: only if the storefront does not already send page_view
* for the same property, or it is counted twice. */
// analytics.subscribe("page_viewed", (event) => {
// gtag("event", "page_view", {
// page_path: event.context.document.location.pathname,
// page_title: event.context.document.title,
// page_location: event.context.window.location.href,
// });
// });

/* Purchase: if GA4 and Google Ads are linked, import the GA4 purchase
* as a conversion in Google Ads and delete the conversion block below,
* or every order is counted twice. */
// analytics.subscribe("checkout_completed", (event) => {
// const checkout = event.data.checkout;
// const items = checkout.lineItems.map((line) => ({
// item_id: "shopify_" + line.variant.product.id + "_" + line.variant.id,
// item_name: line.title,
// item_variant: line.variant.title,
// price: line.variant.price.amount,
// quantity: line.quantity,
// }));
//
// gtag("event", "purchase", {
// transaction_id: checkout.token,
// currency: checkout.currencyCode,
// value: checkout.totalPrice.amount,
// tax: checkout.totalTax.amount,
// shipping: checkout.shippingLine ? checkout.shippingLine.price.amount : 0,
// items: items,
// });
//
// // Google Ads conversion, ONLY when GA4 and Google Ads are NOT linked.
// // Use the conversion label from your Google Ads conversion action.
// gtag("event", "conversion", {
// send_to: "AW-XXXXXXXXXX/AbC-D_efGhIjKlMnOp",
// transaction_id: checkout.token,
// currency: checkout.currencyCode,
// value: checkout.totalPrice.amount,
// });
// });


Snippet 2: comandi predefiniti per regione


Per gli store che raccolgono il consenso solo dove è richiesto per legge. Ci sono due comandi default: uno globale che concede tutto e uno per le regioni elencate che nega tutto tranne security_storage. Quando entrambi corrispondono a un visitatore, vince la regione più specifica.


Il resto è identico allo Snippet 1.


/* START_MODIFY_FOR_YOUR_STORE */
const GA4_ID = ""; // e.g. "G-XXXXXXXXXX", leave empty if not used
const AW_ID = ""; // e.g. "AW-XXXXXXXXXX", leave empty if not used

/* ISO 3166-2 codes where the store collects consent: EEA + UK below.
* Add US states ("US-CA", "US-CO", ...) if you treat them as opt-in.
* This list MUST match the regions where your banner collects consent. */
const RESTRICTED_REGIONS = [
"AT", "BE", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR",
"DE", "GR", "HU", "IE", "IT", "LV", "LT", "LU", "MT", "NL",
"PL", "PT", "RO", "SK", "SI", "ES", "SE", "GB", "LI", "NO", "IS",
];

const DEBUG = false; // true sends GA4 hits to DebugView while testing
/* END_MODIFY_FOR_YOUR_STORE */

const GRANTED = "granted";
const DENIED = "denied";
const GOOGLE_URL = "https://www.googletagmanager.com/gtag/js?id=";
const DEVELOPER_ID = "dMTZkMj";

/* Shopify customerPrivacy -> Google consent state */
const toConsentState = (cp) => ({
ad_storage: cp.marketingAllowed ? GRANTED : DENIED,
ad_user_data: cp.marketingAllowed ? GRANTED : DENIED,
ad_personalization: cp.marketingAllowed ? GRANTED : DENIED,
analytics_storage: cp.analyticsProcessingAllowed ? GRANTED : DENIED,
functionality_storage: cp.preferencesProcessingAllowed ? GRANTED : DENIED,
personalization_storage: cp.preferencesProcessingAllowed ? GRANTED : DENIED,
security_storage: GRANTED,
});

/* The pixel sandbox has its own dataLayer. */
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}

/* Pandectes developer ID. Identifies the implementation to Google,
* has no effect on your data. Leave it as it is. */
gtag("set", `developer_id.${DEVELOPER_ID}`, true);

/* STEP 1a: policy for everyone outside the listed regions. */
gtag("consent", "default", {
ad_storage: GRANTED,
ad_user_data: GRANTED,
ad_personalization: GRANTED,
analytics_storage: GRANTED,
functionality_storage: GRANTED,
personalization_storage: GRANTED,
security_storage: GRANTED,
});

/* STEP 1b: policy for the listed regions. Google resolves the region
* from the IP address, so test it with a VPN. */
gtag("consent", "default", {
ad_storage: DENIED,
ad_user_data: DENIED,
ad_personalization: DENIED,
analytics_storage: DENIED,
functionality_storage: DENIED,
personalization_storage: DENIED,
security_storage: GRANTED,
region: RESTRICTED_REGIONS,
});

/* STEP 2: visitor state, always sent. Shopify has already applied your
* regional settings to init.customerPrivacy, so this matches 1a or 1b. */
gtag("consent", "update", toConsentState(init.customerPrivacy));

/* STEP 3: load the Google tag once and configure each property. */
const TAG_IDS = [GA4_ID, AW_ID].filter(Boolean);

if (TAG_IDS.length) {
gtag("js", new Date());

if (GA4_ID) {
gtag("config", GA4_ID, {
send_page_view: false,
...(DEBUG ? { debug_mode: true } : {}),
});
}

if (AW_ID) {
gtag("config", AW_ID);
}

const script = document.createElement("script");
script.async = true;
script.src = GOOGLE_URL + TAG_IDS[0];
document.head.appendChild(script);
}

/* STEP 4: follow the visitor's choices. Note the api. prefix. */
api.customerPrivacy.subscribe("visitorConsentCollected", (event) => {
gtag("consent", "update", toConsentState(event.customerPrivacy));
});

/* YOUR EVENT SUBSCRIPTIONS GO HERE, IN THIS SAME PIXEL.
* Use the same page view and purchase examples as in Snippet 1. */


Verifica che funzioni


Tag Assistant non vede il pixel


Google Tag Assistant ispeziona solo la pagina dello storefront. Il gtag, il dataLayer e le proprietà del pixel vivono in un iframe sandbox che non raggiunge, quindi non riporta nulla (o solo i tag dello storefront) anche quando il pixel funziona correttamente. È un comportamento previsto e non è un errore.


Controlla il dataLayer nel frame del pixel


  1. Apri Chrome DevTools e vai alla scheda Console.
  2. Nella barra degli strumenti della console apri il menu a tendina dei frame (di solito mostra top) e seleziona il frame sandbox del pixel (il cui nome inizia con web-pixel). Shopify crea un frame per ogni custom pixel, quindi scegli quello giusto se ne hai più di uno.
  3. Esegui i controlli qui sotto.


Nel frame top, dataLayer è il dataLayer dello storefront, che non dice nulla sul pixel.


  • I valori predefiniti vengono prima? In dataLayer, le voci consent devono comparire prima delle voci config.
  • Il consenso arriva al tag? Imposta DEBUG = true, decommenta un evento in modo che venga inviato qualcosa, e apri GA4 DebugView. Con analytics_storage negato vedi un ping senza cookie invece di un hit normale.
  • Il pixel si carica prima del consenso? Deve farlo, per la modalità Advanced. Se il tag Google compare solo dopo che il visitatore ha accettato, il permesso del pixel è impostato su Required e sei in modalità Basic.
  • La logica per regione funziona? Prova con una VPN dentro e fuori da un paese elencato.
  • L'iscrizione si attiva? Aggiungi temporaneamente un console.log dentro la callback visitorConsentCollected e cambia la tua scelta sul banner.


Errori comuni


Errore

Cosa succede

Codice del consenso in un pixel, eventi in un altro

Il pixel degli eventi non ha gtag e nessuno stato di consenso. I suoi eventi non vanno da nessuna parte.

Più pixel caricano una proprietà Google, solo uno ha il codice del consenso

Gli altri inviano senza alcuna modalità di consenso, senza avvisi.

Pixel Permission impostato su Required

Il tag non si carica mai prima del consenso: nessun ping senza cookie e nessuna modellazione. Questa è la modalità Basic.

Evento conversion di Ads inviato mentre l'acquisto GA4 viene anche importato come conversione

Ogni ordine viene conteggiato due volte in Google Ads.

customerPrivacy.subscribe(...) senza api.

ReferenceError. Il consenso non si aggiorna mai dopo il banner.

Saltare il update perché init.customerPrivacy sembra il valore predefinito

I visitatori di ritorno con un consenso salvato ricevono tag negati già alla prima visualizzazione di pagina.

default inviato dopo config

La modalità di consenso non viene applicata ai primi hit.

Integrazione Google Consent Mode non attivata in Pandectes

Solo le proprietà del pixel ricevono la modalità di consenso. I tag Google dello storefront girano senza.

Pixel creato mentre GTM carica già la stessa proprietà

Visualizzazioni di pagina, sessioni, acquisti e conversioni duplicati, più due stati di consenso.

Test con Tag Assistant o lettura di dataLayer nel frame top

Nessuno dei due guarda dentro il sandbox del pixel.

security_storage negato

Compromette i segnali di prevenzione delle frodi senza alcun vantaggio in termini di conformità.

RESTRICTED_REGIONS non corrisponde alle regioni del banner

Il valore predefinito e l'aggiornamento non coincidono. Vince l'aggiornamento e la policy per regione viene ignorata.


Impostazioni che questo articolo non copre


Gli snippet non includono le impostazioni a livello di account di Google, quindi si applicano i valori predefiniti di Google:


Impostazione | Cosa controlla--- | --- |url_passthrough | Se gli ID di clic degli annunci, come GCLID, vengono passati nell'URL tra una pagina e l'altra quando i cookie non possono essere impostatiads_data_redaction | Se gli ID di clic degli annunci vengono rimossi dai ping senza cookie mentre ad_storage è negatoallow_enhanced_conversions | Se possono essere inviati dati cliente sottoposti ad hash con le conversionirestricted_data_processing | La restrizione statunitense di vendita o condivisione per stato, legata a saleOfDataAllowed di Shopifywait_for_update | Quanto a lungo i tag attendono un aggiornamento del consenso prima di attivarsi


Pandectes non può consigliarti su queste impostazioni. I valori giusti dipendono dai tuoi account Google, dal modello di attribuzione su cui fai affidamento e dalla posizione legale della tua attività. Discutine con chi gestisce la tua configurazione Google o, se c'è una questione di privacy, con il tuo consulente legale.


Se decidi di impostarne una, aggiungila come chiamata gtag("set", ...) prima dei comandi consent default:


// gtag("set", "url_passthrough", true);
// gtag("set", "ads_data_redaction", true);


wait_for_update è l'eccezione: va dentro un comando default. Questi snippet non ne hanno bisogno, perché init.customerPrivacy è disponibile subito e update viene inviato subito dopo i valori predefiniti.

Aggiornato il: 30/10/2026

È stato utile questo articolo?

Condividi il tuo feedback

Annulla

Grazie!