Documentazione per integratori
Installa Biscotti e collega le integrazioni alla scelta del visitatore. Riferimento dell’API v1 distribuita.
Installazione HTML
Aggiungi l’host esatto, installa il codice, verifica l’installazione e pubblica la configurazione. Copia il codice da Installazione. Sostituisci YOUR_SITE_KEY con la chiave pubblica e usa l’origine della piattaforma: produzione https://biscotti.dev, dev separato https://dev.biscotti.dev. La chiave non concede accesso amministrativo. Inserisci un solo SDK in head prima delle integrazioni, con un metodo per documento. Gli script attivi possono partire prima dell’SDK differito: rendili inerti. Mantieni le impostazioni cookie nel piè di pagina.
Aggiornamenti automatici (consigliato)
Incolla il codice una volta. Ricevi automaticamente le correzioni dello script, senza sostituire il codice a mano. Le installazioni esistenti e WordPress funzionano allo stesso modo.
<script id="biscotti-sdk" src="https://biscotti.dev/consent.js" data-site-key="YOUR_SITE_KEY" defer></script>Versione fissa con SRI (avanzato)
Scegli una versione specifica dello script. Non ricevi correzioni automatiche, comprese quelle di sicurezza. Per aggiornarla devi sostituire il codice a mano. Le impostazioni pubblicate del banner vengono caricate automaticamente in entrambe le modalità.
<script id="biscotti-sdk" src="https://biscotti.dev/sdk/9c2bc03275827be7431adcc709a295afb1f7778553dbaf3c3c4f8a2df233f702/consent.js" integrity="sha384-VtJRmbHcw1tU2ZG0b1SkNpDBvF0Wk2fuFyZG/CNH7stj+z9FgY8pbYK6eyk5KqmD" crossorigin="anonymous" data-site-key="YOUR_SITE_KEY" defer></script>WordPress
Scarica lo ZIP, installa e attiva il plugin. In Biscotti → Installazione → WordPress copia URL della piattaforma e chiave pubblica nel plugin. Un amministratore genera il codice temporaneo monouso di abbinamento. Non pubblicare codici o credenziali nell’HTML. Collega l’host esatto, pubblica ed elimina installazioni SDK duplicate. Abbinamento e importazione non pubblicano la bozza e non bloccano automaticamente tutti i plugin. Verifica gli script reali del tema e dei plugin.
Scarica · WordPressGoogle Tag Manager — Basic
Installa Biscotti fuori dal contenitore. Rimuovi il codice GTM standard e l’iframe noscript. Inserisci il loader sotto l’SDK e sostituisci GTM-XXXXXXX. Attende il consenso analitico; un contenitore misto richiede regole per ciascun tag. Incolla il modello scaricato nel Codice di un modello nativo, non in Custom HTML. Consenti access_consent write per i sette segnali, access_globals per eseguire Biscotti.onConsentChange, Biscotti.canActivate e dataLayer.push e leggere/scrivere dataLayer. Usa Consent Initialization – All Pages e requisiti aggiuntivi di consenso per i tag. Verifica Preview / Tag Assistant. biscotti_consent_update in dataLayer è diverso da DOM biscotti:consentchange. Le regole pubblicate richiedono una condizione canActivate positiva. Il modello non è nella Community Template Gallery.
<script type="text/plain" data-consent-category="analytics">
(function () {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ 'gtm.start': Date.now(), event: 'gtm.js' });
var script = document.createElement('script');
script.async = true;
script.src = 'https://www.googletagmanager.com/gtm.js?id=GTM-XXXXXXX';
document.head.appendChild(script);
})();
</script>Scarica · GTMAPI e disponibilità
window.Biscotti o load non indicano che l’SDK sia pronto. La configurazione inizia a caricarsi prima di DOMContentLoaded; la UI attende il DOM. Ready significa pubblicazione convalidata, preferenze risolte, UI, condizioni, Consent Mode e ascolto tra schede pronti. Nessuna scelta e rifiuto salvato sono validi. Non attende audit, visualizzazioni, font o tag esterni. Gli adattatori ripristinati partono dopo gli eventi iniziali; i callback Promise possono seguire gli adattatori sincroni. ready/error sono stati finali dell’inizializzazione. Un errore runtime non cambia ready. Dopo un errore iniziale, le nuove scelte continuano a emettere cambiamenti, ma whenReady resta rifiutata.
| Metodo | Comportamento |
|---|---|
apiVersion | Costante 1: versione del contratto. |
openPreferences() | Apre le preferenze; in loading accoda la richiesta, senza concedere consenso. |
getConsent() | Nuova copia modificabile di sei booleani; necessary sempre true. |
canActivate(ruleId) | Condizione positiva di una regola pubblicata; sconosciuta, sospesa o indisponibile restituisce false. |
onConsentChange(callback) | Callback immediato con copia e dopo le preferenze applicate; può ripetersi. Restituisce unsubscribe, isola le eccezioni. |
getStatus() | loading/ready/error dell’inizializzazione, non la decisione. |
whenReady() | Promise dello snapshot iniziale congelato anche per chiamate tardive; rifiuta se fallisce l’avvio. |
getLastError() | Ultimo errore congelato o null; una scelta riuscita non cancella la cronologia. |
Eventi DOM e dati
Ascolta window prima dell’SDK. ready arriva una volta; consentchange aggiunge reason ed error aggiunge code/phase allo snapshot. Sono CustomEvent senza propagazione o annullamento. I listener tardivi usano whenReady/getConsent/getLastError. Avvio: stato/GCM/UI → callback → ready → consentchange iniziale → adattatori. Modifica: stato → callback → consentchange → attivazione o ricarica. Errore: rifiuto opzionale → consentchange se cambia → error; nessun ready se fallisce l’avvio. Snapshot e consents sono congelati, senza ID della decisione, valori cookie, URL del visitatore o eccezioni grezze. hasDecision distingue rifiuto esplicito e assenza di scelta; metadati null prima della convalida. Le eccezioni dei listener non interrompono l’applicazione del consenso; le conferme dell’audit non duplicano gli eventi.
W17 — biscotti:beforereload precede il reload/replace necessario dopo la revoca. BeforeReloadDetail = SdkSnapshot + reason + navigation. Il codice sincrono del listener su window viene eseguito prima della navigazione. L’evento non può annullare la navigazione; il SDK non attende operazioni asincrone. Ordine ed esempio sono nella sezione sulla revoca.
window.addEventListener('biscotti:ready', ({ detail }) => {
document.documentElement.dataset.biscottiReady = String(detail.apiVersion);
});
window.addEventListener('biscotti:consentchange', ({ detail }) => {
document.documentElement.dataset.analyticsConsent = String(detail.consents.analytics);
});
window.addEventListener('biscotti:error', ({ detail }) => {
console.warn('Biscotti', detail.code, detail.phase);
});type SdkSnapshot = {
readonly apiVersion: 1;
readonly siteKey: string | null;
readonly publicationVersion: number | null;
readonly consentEpoch: number | null;
readonly environment?: 'development';
readonly hasDecision: boolean;
readonly consents: Readonly<{
necessary: true;
functional: boolean; analytics: boolean; performance: boolean;
advertising: boolean; unclassified: boolean;
}>;
};
type ConsentChangeDetail = SdkSnapshot & {
readonly reason: 'initial' | 'choice' | 'storage' | 'expiry' | 'error';
};
type BeforeReloadDetail = SdkSnapshot & {
readonly reason: ConsentChangeDetail['reason'];
readonly navigation: 'reload' | 'replace';
};
type SdkErrorDetail = SdkSnapshot & {
readonly code:
| 'INVALID_SITE_KEY' | 'CONFIGURATION_UNAVAILABLE'
| 'INVALID_CONFIGURATION' | 'STORAGE_UNAVAILABLE'
| 'CONSENT_MODE_FAILED' | 'ADAPTER_FAILED'
| 'SYNC_FAILED' | 'INITIALIZATION_FAILED';
readonly phase: 'initialization' | 'runtime';
};Applicazioni SPA
Esegui l’esempio quando l’elemento script dell’SDK esiste già nel DOM, prima o dopo il caricamento del file. Installa l’SDK una volta nella struttura del documento. Iscriviti anche se whenReady fallisce. L’esempio aggiorna un attributo DOM; chiama disconnectBiscotti allo smontaggio. whenReady mantiene lo snapshot iniziale; usa getConsent o la sottoscrizione per la scelta corrente. La navigazione SPA non reinizializza e non recupera una nuova pubblicazione. I nuovi elementi inerti possono partire una volta per elemento. Non sostituire window.Biscotti con una coda o un’API provvisoria.
function connectBiscotti() {
const api = window.Biscotti;
if (!api || api.apiVersion !== 1) return () => {};
const unsubscribe = api.onConsentChange(consents => {
document.documentElement.dataset.analyticsConsent = String(consents.analytics);
});
void api.whenReady().catch(error => {
console.warn('Biscotti initialization', error.code);
});
return unsubscribe;
}
const script = document.getElementById('biscotti-sdk');
let disconnect = () => {};
const onLoad = () => { disconnect(); disconnect = connectBiscotti(); };
if (window.Biscotti) onLoad();
else script?.addEventListener('load', onLoad, { once: true });
const onError = () => { document.documentElement.dataset.analyticsConsent = 'false'; };
script?.addEventListener('error', onError);
function disconnectBiscotti() {
script?.removeEventListener('load', onLoad);
script?.removeEventListener('error', onError);
disconnect();
}Adattatori di script inerti
Usa type="text/plain", data-consent-category e data-consent-src invece di src per gli script esterni. Sostituisci l’URL di esempio. Le categorie opzionali partono rifiutate; ogni elemento si avvia una volta per documento dopo il consenso. Supportati script classici inline e HTTP(S); nonce, integrity e crossorigin vengono copiati. Moduli, nomodule, iframe noscript, pixel arbitrari e cookie del server sono esclusi. L’adattatore di categoria è indipendente dalla pausa delle regole; canActivate controlla la regola pubblicata senza avviare tag. Verifica separatamente i tag misti.
<script type="text/plain" data-consent-category="analytics">
window.exampleAnalyticsStarted = true;
</script>
<script type="text/plain" data-consent-category="analytics"
data-consent-src="https://analytics.example.com/sdk.js"></script>Categorie e Google Consent Mode
I segnali opzionali partono denied, security_storage granted; la tabella mostra le associazioni. La modalità è Basic, senza installazione automatica di GA/GTM o Advanced. performance e unclassified non hanno un segnale Google nativo: applica la categoria o una condizione positiva della regola pubblicata. L’assenza di segnale non è un permesso. Le categorie disabilitate non si concedono. GTM richiede anche consensi aggiuntivi e condizioni adatte.
performance riguarda misurazioni tecniche: velocità di caricamento e stabilità del sito. Classifica traffico, comportamento dei visitatori, GA4 e Clarity come analytics; misurazione delle campagne e remarketing come advertising, anche se lo strumento misura la velocità. Conta la finalità effettiva; separa gli strumenti con più finalità o richiedi tutti i consensi pertinenti. performance e unclassified non hanno un segnale Google nativo. performance da sola non concede analytics_storage né consensi pubblicitari. Richiedi questa categoria o una condizione positiva della regola pubblicata; l’assenza di segnale non è un permesso. In GTM richiedi biscottiPerformance uguale a true e, per le regole, anche la condizione positiva. Non inventare performance_storage. Il significato dei consensi salvati non cambia; questa correzione non richiede una nuova decisione. Se cambi finalità o ambito, pubblica rinnovando i consensi.
| Categoria | Comportamento | Google Consent Mode |
|---|---|---|
necessary | Funzioni essenziali, sicurezza e memorizzazione della decisione. Sempre attivi. | security_storage = granted |
functional | Funzioni aggiuntive e memorizzazione delle preferenze del visitatore. | functionality_storage, personalization_storage |
analytics | Misurazione del traffico e analisi dell’utilizzo del sito. | analytics_storage |
advertising | Personalizzazione degli annunci e misurazione dell’efficacia delle campagne. | ad_storage, ad_user_data, ad_personalization |
performance | Misurazione di velocità, stabilità e prestazioni del sito. | Nessun segnale Google nativo |
unclassified | Altri cookie la cui finalità deve ancora essere determinata. | Nessun segnale Google nativo |
Domini e test
Ogni pubblicazione corrisponde a un hostname esatto: example.com, www.example.com e shop.example.com sono diversi. SDK e CORS verificano l’host; la chiave non aggira il controllo. Preferenze host-only, senza condivisione automatica fra sottodomini. Dev e produzione hanno dati separati. Non esistono ancora eccezioni localhost o staging collegato in una licenza. Playground non ha privilegi; localhost può fallire la verifica sulla piattaforma ospitata. Usa un host di test raggiungibile con pubblicazione verificata. Una nuova pubblicazione viene recuperata in un nuovo documento.
Chiave separata per localhost e staging. I dati di test sono esclusi dai report di produzione e dalla fatturazione. Prima salva la bozza e approva le informazioni sui cookie. La copia usa questi dati e le ultime regole pubblicate (nessuna prima della pubblicazione). Ogni salvataggio rinnova il consenso di test. Localhost, 127.0.0.1 e [::1] richiedono la porta esatta. Staging richiede HTTPS sulla porta 443 e verifica con la chiave di test. L’host di produzione è escluso.
Nel pannello scegli Installazione → Modalità sviluppatore → Salva configurazione di test, aggiungi http://localhost:5173 e copia il codice dev_. Esegui l’esempio su questo origin con la piattaforma Biscotti ospitata, senza installare localmente la piattaforma. I dati di produzione e la chiave site_ restano separati. Per staging aggiungi l’origin HTTPS esatto, installa il codice sulla pagina iniziale e verifica l’installazione. La verifica non contatta indirizzi privati.
Preferenze e coda sono separate per chiave e origin, inclusa la porta. Snapshot ed eventi aggiungono environment: development; il banner indica il test. Disattivare, rimuovere l’origin o rinnovare la chiave blocca richieste successive; ricarica i documenti aperti. La chiave è pubblica: Origin limita i browser, non autentica i server. Dopo il consenso gli adattatori eseguono integrazioni reali: usa account di test. Non viene creato un altro sito con licenza né staging collegato. Il rinnovo elimina solo dati di test e richiede una nuova verifica di staging.
Limiti: 10 origin, 20 configurazioni, 1000 decisioni e 1000 visite. Rinnova la chiave per azzerare.
Staging pubblico deve essere un sottodominio proprio del dominio di produzione, ad esempio staging.example.com per example.com o www.example.com (si rimuove solo un prefisso www. iniziale); aggiungi un sito separato per i test su un altro dominio.
<script>
window.addEventListener('biscotti:ready', ({ detail }) => {
console.assert(detail.environment === 'development');
});
</script>
<script src="https://biscotti.dev/consent.js" data-site-key="YOUR_TEST_KEY" defer></script>
<script type="text/plain" data-consent-category="analytics">
document.documentElement.dataset.testAnalytics = 'active';
</script>
<button type="button" data-biscotti-preferences>Cookies</button>Modifica e revoca del consenso
Mantieni questo controllo nel piè di pagina. openPreferences apre le impostazioni senza concedere il consenso. Se gli adattatori SDK sono stati eseguiti, anche una revoca parziale richiede di ricaricare il documento per rimuovere il loro codice attivo.
Ascolta biscotti:beforereload su window. BeforeReloadDetail è congelato e contiene lo SdkSnapshot attuale, reason (choice, storage, expiry o error) e navigation (reload o replace). Per una scelta esplicita, il salvataggio, gli aggiornamenti di Consent Mode, la chiusura dei controlli e consentchange precedono questo evento. Il rifiuto di emergenza nega localmente, tenta di aggiornare Consent Mode e cancellare le preferenze (la sincronizzazione non cancella la scelta di un’altra scheda), emette consentchange se necessario ed eventuali error, poi beforereload e replace con rifiuto forzato. Se Consent Mode fallisce, i controlli restano chiusi ed error segnala il guasto.
Salva lo stato dell’applicazione in modo sincrono, ad esempio un identificatore della vista in sessionStorage. L’evento non è annullabile; preventDefault, eccezioni del listener e Promise restituite non annullano la navigazione. Il SDK non attende operazioni asincrone. Il codice sincrono del listener viene eseguito prima della navigazione. Il segnale copre modifiche locali, altre schede, scadenza e rifiuto di emergenza; non viene emesso se non serve ricaricare. Cookie ed elaborazione sul server richiedono controlli propri. Un cookie non firmato non autentica l’utente.
Se scegli di restare nel dialogo beforeunload del browser, una revoca successiva emette di nuovo il segnale e ritenta la navigazione.
<button type="button" data-biscotti-preferences>Impostazioni cookie</button>window.addEventListener('biscotti:beforereload', ({ detail }) => {
try {
sessionStorage.setItem('app:view', document.documentElement.dataset.currentView ?? 'home');
} catch { /* Storage may be unavailable; consent withdrawal still proceeds. */ }
document.documentElement.dataset.biscottiReloadReason = detail.reason;
});CSP, CORS e integrità
Consenti l’origine della piattaforma in script-src/connect-src, /brand/fonts in font-src e le integrazioni autorizzate. Gli adattatori inline richiedono nonce/hash CSP; il nonce dello script viene copiato. Lo stile Shadow DOM dell’SDK non riceve un nonce di stile: una politica restrittiva deve considerarlo, il nonce dello script non basta. Non esiste un CSP universale. CORS ammette l’host pubblicato; l’SDK omette credentials e CORS non autentica i server. Incolla il codice una volta. Ricevi automaticamente le correzioni dello script, senza sostituire il codice a mano. Le installazioni esistenti e WordPress funzionano allo stesso modo. Aggiornamenti automatici (consigliato): /consent.js. Versione fissa con SRI (avanzato): /sdk/<SHA-256>/consent.js, integrity SHA-384, crossorigin="anonymous". SDK pubblico e manifesti consentono CORS *, mentre l’API verifica ancora l’host del sito. SRI verifica JavaScript, non configurazione API, font o tag esterni. /consent.js resta un URL modificabile per installazioni esistenti e WordPress; non fissare un hash SRI a questo URL.
Il banner può usare configurazione convalidata in localStorage per 15 minuti, separata per piattaforma, chiave e origine. Ogni documento conferma pubblicazione e host con il server; ETag/304 evita di ritrasmettere configurazione invariata. Accettazione e script facoltativi restano disattivati fino alla conferma, mentre il rifiuto funziona subito. Il rifiuto durante un guasto cancella il consenso locale; la prova di audit richiede configurazione attuale. Pubblicazione o modifica di consentEpoch restituisce nuova configurazione; ritiro, host rimosso ed errori cancellano la cache e negano i permessi. La cache non ritarda autorizzazioni in nuovi documenti; dopo 8 secondi senza risposta resta il rifiuto. Un documento aperto conserva la copia fino alla navigazione senza controlli periodici: non esiste un termine di propagazione per schede sempre aperte. La prima visita senza cache attende il server. dev_ non usa la cache. Non devi modificare il codice di installazione.
Errori e verifica
Usa code stabile, non Error.message. whenReady rifiuta con BiscottiInitializationError se l’avvio fallisce; getLastError conserva l’ultimo errore anche dopo una scelta riuscita. phase è initialization/runtime indipendentemente dallo stato finale. Gli errori negano le categorie opzionali. Gestisci il download fallito sull’elemento script. Verifica Network/Console, host, chiave, CORS, CSP, storage e pubblicazione. Prova prima visita, rifiuto, consenso parziale/completo, ritorno, altra scheda, revoca e API/storage indisponibili. Verifica separatamente i veri tag GTM e plugin WordPress.
code | Comportamento |
|---|---|
INVALID_SITE_KEY | data-site-key assente o errato. |
CONFIGURATION_UNAVAILABLE | Rete, timeout, dimensione o configurazione fuori da 2xx. |
INVALID_CONFIGURATION | JSON/schema, chiave o host errati. |
STORAGE_UNAVAILABLE | Storage/cookie indisponibili o struttura danneggiata. |
CONSENT_MODE_FAILED | Impossibile aggiornare dataLayer. |
ADAPTER_FAILED | Errore o timeout dell’adattatore. |
SYNC_FAILED | Coda audit errata o bloccata definitivamente; un errore di rete temporaneo lascia solo la voce in coda. |
INITIALIZATION_FAILED | Altro errore di inizializzazione dell’interfaccia o dei listener. |
Versioni e cronologia
API v1 della versione b0449f1, distribuita il 2026-10-17. apiVersion identifica il contratto, publicationVersion la configurazione e consentEpoch il rinnovo. Non sono URL immutabili dello script. Le aggiunte mantengono v1; eliminare un metodo o cambiarne il significato richiede un nuovo contratto.
2026-10-17 — Disponibilità, stato, ultimo errore, tre eventi DOM e snapshot congelati; metodi precedenti mantenuti. Verificati ripristino SPA, fase esplicita e nome BiscottiInitializationError.
W16 — Modalità sviluppatore. Chiave separata per localhost e staging. I dati di test sono esclusi dai report di produzione e dalla fatturazione.
Aggiornamenti automatici (consigliato): Incolla il codice una volta. Ricevi automaticamente le correzioni dello script, senza sostituire il codice a mano. Le installazioni esistenti e WordPress funzionano allo stesso modo. Versione fissa con SRI (avanzato): Scegli una versione specifica dello script. Non ricevi correzioni automatiche, comprese quelle di sicurezza. Per aggiornarla devi sostituire il codice a mano. Le impostazioni pubblicate del banner vengono caricate automaticamente in entrambe le modalità.
W20 — Versioni SDK e SRI. /sdk/manifest.json elenca la versione attuale e quelle conservate. src è l’URL immutabile, integrity il suo hash SHA-384 e bytes la dimensione. Ogni versione ha anche un manifesto accanto allo script. L’URL contiene SHA-256 del contenuto e usa cache immutable per un anno; la configurazione del sito non lo modifica.
Per una versione fissa con SRI: prima di aggiornare conserva il codice precedente e sostituisci insieme src e integrity dal pannello o manifesto. Mantieni chiave e crossorigin="anonymous". Verifica disponibilità, rifiuto, consenso e revoca su localhost o staging. Per tornare indietro ripristina la coppia src/integrity precedente. Il build non sovrascrive né elimina le versioni conservate. Le versioni fissate richiedono aggiornamenti manuali, anche di sicurezza; non rimuovere integrity per aggirare un errore SRI. L’hash non è apiVersion, publicationVersion o consentEpoch. Tornare allo script precedente non ripristina pubblicazioni o dati; verifica prima la compatibilità API.
W17 — biscotti:beforereload precede il reload/replace necessario dopo la revoca. BeforeReloadDetail = SdkSnapshot + reason + navigation. Il codice sincrono del listener su window viene eseguito prima della navigazione. L’evento non può annullare la navigazione; il SDK non attende operazioni asincrone. Ordine ed esempio sono nella sezione sulla revoca.
{
"apiVersion": 1,
"version": "9c2bc03275827be7431adcc709a295afb1f7778553dbaf3c3c4f8a2df233f702",
"src": "/sdk/9c2bc03275827be7431adcc709a295afb1f7778553dbaf3c3c4f8a2df233f702/consent.js",
"integrity": "sha384-VtJRmbHcw1tU2ZG0b1SkNpDBvF0Wk2fuFyZG/CNH7stj+z9FgY8pbYK6eyk5KqmD",
"bytes": 83837
}