> ## Knowledge Base Index
> Fetch the complete knowledge base index at: https://help.pandectes.io/sitemap.xml
> Use this file to discover available pages before exploring further.
> Pure-Markdown content can be obtained by appending a '.md' suffix to the content URLs listed in the sitemap (without the trailing slash).

# 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)](https://help.pandectes.io/it/article/google-consent-mode-in-a-shopify-custom-pixel-google-tag-manager-xqpahf/).

Questa è una guida all'implementazione. Per i fondamenti sui comandi `default` e `update` e sulla modalità Advanced, consulta [Consent Mode con gtag.js](https://developers.google.com/tag-platform/security/guides/consent?consentmode=advanced#gtag.js_2) della documentazione di Google.

### Prima di iniziare

#### Prima attiva l'integrazione di Google Consent Mode

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](https://help.pandectes.io/it/article/usare-l-integrazione-google-consent-mode-1vrm719/). 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 Mode**
| Sandbox 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)](https://help.pandectes.io/it/article/google-consent-mode-in-a-shopify-custom-pixel-google-tag-manager-xqpahf/) |
| 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`.

```javascript
/* 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.

```javascript
/* 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 impostati
| `ads_data_redaction` | Se gli ID di clic degli annunci vengono rimossi dai ping senza cookie mentre `ad_storage` è negato
| `allow_enhanced_conversions` | Se possono essere inviati dati cliente sottoposti ad hash con le conversioni
| `restricted_data_processing` | La restrizione statunitense di vendita o condivisione per stato, legata a `saleOfDataAllowed` di Shopify
| `wait_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`:

```javascript
// 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.