Documentation pour les intégrateurs
Installe Biscotti et relie tes intégrations au choix du visiteur. Référence de l’API v1 déployée.
Installation HTML
Ajoute le nom d’hôte exact, installe le code, vérifie l’installation et publie la configuration. Copie le code depuis Installation. Remplace YOUR_SITE_KEY par la clé publique et utilise l’origine de ta plateforme : production https://biscotti.dev, dev séparé https://dev.biscotti.dev. La clé ne donne pas d’accès administratif. Place un seul SDK dans head avant les intégrations, avec une seule méthode par document. Un script actif peut démarrer avant le SDK différé : rends ces scripts inertes. Garde un accès permanent aux réglages cookies dans le pied de page.
Mises à jour automatiques (recommandé)
Colle le code une seule fois. Les correctifs du script arrivent automatiquement, sans remplacer le code manuellement. Les installations existantes et WordPress fonctionnent de la même façon.
<script id="biscotti-sdk" src="https://biscotti.dev/consent.js" data-site-key="YOUR_SITE_KEY" defer></script>Version fixe avec SRI (avancé)
Tu choisis une version précise du script. Elle ne reçoit aucun correctif automatique, y compris de sécurité. Pour la mettre à jour, tu dois remplacer le code manuellement. Les réglages publiés de la bannière sont récupérés automatiquement dans les deux modes.
<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
Télécharge le ZIP, installe et active l’extension. Dans Biscotti → Installation → WordPress, copie l’URL de plateforme et la clé publique dans l’extension. Un administrateur crée un code temporaire d’association à usage unique. Ne publie pas les codes ni identifiants dans le HTML. Associe l’hôte exact, publie et supprime les installations SDK en double. L’association et l’import ne publient pas le brouillon et ne bloquent pas automatiquement les autres extensions. Vérifie les vrais scripts du thème et des extensions.
Télécharger · WordPressGoogle Tag Manager — Basic
Installe Biscotti hors du conteneur. Supprime le code GTM standard et son iframe noscript. Place le chargeur sous le SDK et remplace GTM-XXXXXXX. Il attend le consentement analytique ; un conteneur mixte exige des règles par balise. Colle le modèle téléchargé dans Code d’un modèle natif, pas Custom HTML. Autorise access_consent write pour les sept signaux, access_globals pour exécuter Biscotti.onConsentChange, Biscotti.canActivate et dataLayer.push, et lire/écrire dataLayer. Utilise Consent Initialization – All Pages et des consentements supplémentaires par balise. Vérifie Preview / Tag Assistant. biscotti_consent_update dans dataLayer diffère du DOM biscotti:consentchange. Une règle publiée exige une condition canActivate positive. Le modèle n’est pas dans 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>Télécharger · GTMAPI et disponibilité
La présence de window.Biscotti ou load ne signifie pas que le SDK est prêt. La configuration commence à charger avant DOMContentLoaded ; l’interface attend le DOM. Ready signifie publication validée, préférences résolues, interface, conditions, Consent Mode et écoute inter-onglets prêts. L’absence de choix et le refus enregistré sont valides. Le SDK n’attend pas l’audit, les vues, les polices ni les balises externes. Les adaptateurs restaurés suivent les événements initiaux ; les callbacks Promise peuvent suivre les adaptateurs synchrones. ready/error sont définitifs pour l’initialisation du document. Une erreur d’exécution ne change pas ready. Après un échec initial, les choix suivants émettent encore des changements, mais whenReady reste rejetée.
| Méthode | Comportement |
|---|---|
apiVersion | Constante 1 : version du contrat. |
openPreferences() | Ouvre les préférences ; met la demande en attente pendant loading, sans accorder de consentement. |
getConsent() | Nouvelle copie modifiable de six booléens ; necessary toujours true. |
canActivate(ruleId) | Condition positive d’une règle publiée ; inconnue, en pause ou indisponible donne false. |
onConsentChange(callback) | Callback immédiat avec copie et après application des préférences ; répétitions possibles. Renvoie unsubscribe et isole les exceptions. |
getStatus() | loading/ready/error de l’initialisation, pas la décision. |
whenReady() | Promise du snapshot initial figé, aussi pour les appels tardifs ; rejet après échec initial. |
getLastError() | Dernière erreur figée ou null ; un choix réussi ne supprime pas l’historique. |
Événements DOM et données
Écoute window avant le SDK. ready arrive une fois ; consentchange ajoute reason et error ajoute code/phase au snapshot. Ce sont des CustomEvent sans propagation ni annulation. Un écouteur tardif utilise whenReady/getConsent/getLastError. Début : état/GCM/interface → callbacks → ready → consentchange initial → adaptateurs. Changement : état → callbacks → consentchange → activation ou rechargement. Échec : refus facultatif → consentchange si changement → error ; pas de ready si le démarrage échoue. Snapshot et consents sont figés, sans ID de décision, valeur cookie, URL du visiteur ni exception brute. hasDecision distingue refus explicite et absence de choix ; métadonnées null avant validation. Une exception d’écouteur ne bloque pas l’application du choix ; un accusé d’audit ne répète pas l’événement.
W17 — biscotti:beforereload précède le reload/replace requis après un retrait. BeforeReloadDetail = SdkSnapshot + reason + navigation. Le code synchrone du gestionnaire sur window s’exécute avant la navigation. L’événement ne peut pas annuler la navigation ; le SDK n’attend pas les opérations asynchrones. Consulte l’ordre et l’exemple dans la section sur le retrait.
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';
};Applications SPA
Exécute l’exemple quand l’élément script du SDK existe déjà dans le DOM, avant ou après le chargement du fichier. Installe le SDK une fois dans la structure du document. Abonne-toi même si whenReady échoue. L’exemple met à jour un attribut DOM ; appelle disconnectBiscotti au démontage. whenReady conserve le snapshot initial ; utilise getConsent ou l’abonnement pour le choix actuel. La navigation SPA ne réinitialise pas le SDK et ne charge pas de nouvelle publication. Les nouveaux éléments inertes peuvent démarrer une fois par élément. Ne remplace pas window.Biscotti par une API provisoire ou une file de méthodes.
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();
}Adaptateurs de scripts inertes
Utilise type="text/plain", data-consent-category et data-consent-src au lieu de src pour les scripts externes. Remplace l’URL d’exemple. Les catégories facultatives sont refusées initialement ; chaque élément démarre une fois par document après consentement. Scripts classiques inline et HTTP(S) pris en charge ; nonce, integrity et crossorigin sont copiés. Modules, nomodule, iframes noscript, pixels arbitraires et cookies serveur sont hors contrat. Un adaptateur de catégorie est indépendant de la pause des règles ; canActivate vérifie la règle publiée sans lancer la balise. Vérifie les balises mixtes séparément.
<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>Catégories et Google Consent Mode
Les signaux facultatifs commencent à denied, security_storage à granted ; le tableau donne la correspondance. Il s’agit de Basic, sans installation automatique de GA/GTM ni mode Advanced. performance et unclassified n’ont aucun signal Google natif : applique leur catégorie ou une condition de règle publiée positive. Une absence de signal n’autorise rien. Les catégories désactivées ne sont pas accordées. GTM exige aussi les consentements supplémentaires et les conditions adaptées.
performance couvre les mesures techniques : vitesse de chargement et stabilité du site. Classe le trafic, le comportement des visiteurs, GA4 et Clarity dans analytics ; la mesure des campagnes et le remarketing dans advertising, même si l’outil mesure aussi la vitesse. Le classement dépend de la finalité réelle ; sépare les outils à plusieurs finalités ou exige tous les consentements correspondants. performance et unclassified n’ont aucun signal Google natif. performance seule n’accorde ni analytics_storage ni consentement publicitaire. Exige cette catégorie ou une condition positive de la règle publiée ; l’absence de signal n’est pas une autorisation. Dans GTM exige biscottiPerformance égal à true et, pour une règle, sa condition positive. N’invente pas performance_storage. Le sens des consentements enregistrés reste inchangé ; cette correction ne demande pas de nouvelle décision. Si tu modifies la finalité ou la portée, publie avec renouvellement des consentements.
| Catégorie | Comportement | Google Consent Mode |
|---|---|---|
necessary | Fonctions essentielles, sécurité et mémorisation de ta décision. Toujours actifs. | security_storage = granted |
functional | Fonctions supplémentaires et mémorisation des préférences du visiteur. | functionality_storage, personalization_storage |
analytics | Mesure du trafic et compréhension de l’utilisation du site. | analytics_storage |
advertising | Personnalisation des publicités et mesure de l’efficacité des campagnes. | ad_storage, ad_user_data, ad_personalization |
performance | Mesure de la vitesse, de la stabilité et des performances du site. | Aucun signal Google natif |
unclassified | Autres cookies dont la finalité reste à déterminer. | Aucun signal Google natif |
Domaines et tests
Une publication correspond à un hostname exact : example.com, www.example.com et shop.example.com sont différents. SDK et CORS vérifient cet hôte ; la clé ne contourne pas la vérification. Préférences host-only, sans partage automatique entre sous-domaines. Dev et production ont des données séparées. Pas encore d’exception localhost ni de staging associé dans une licence. Playground n’a aucun privilège ; localhost peut échouer à la vérification sur une plateforme hébergée. Utilise un hôte de test accessible avec une publication vérifiée. Une nouvelle publication est chargée dans un nouveau document.
Clé distincte pour localhost et staging. Les données de test sont exclues des rapports de production et de la facturation. Enregistre le brouillon et approuve les informations cookies d’abord. La copie utilise ces données et les dernières règles publiées (aucune avant publication). Chaque enregistrement renouvelle le consentement de test. Localhost, 127.0.0.1 et [::1] exigent le port exact. Staging exige HTTPS sur le port 443 et la vérification avec la clé de test. L’hôte de production est exclu.
Dans le panneau choisis Installation → Mode développeur → Enregistrer la configuration de test, ajoute http://localhost:5173 et copie le code dev_. Exécute l’exemple sur cette origine avec la plateforme Biscotti hébergée, sans installation locale de la plateforme. Les données de production et la clé site_ restent séparées. Pour staging ajoute l’origine HTTPS exacte, installe le code sur la page d’accueil et vérifie l’installation. La vérification ne contacte pas les adresses privées.
Préférences et file sont séparées par clé et origine, port compris. Les snapshots et événements ajoutent environment: development ; le bandeau indique le test. Désactiver, retirer une origine ou renouveler la clé bloque les requêtes suivantes ; recharge les documents ouverts. La clé est publique : Origin limite les navigateurs, sans authentifier les serveurs. Après consentement les adaptateurs exécutent des intégrations réelles : utilise des comptes de test. Aucun site supplémentaire sous licence ni staging lié n’est créé. Le renouvellement efface uniquement les données de test et exige de vérifier staging à nouveau.
Limites : 10 origines, 20 configurations, 1000 décisions et 1000 visites. Renouvelle la clé pour réinitialiser.
Staging public doit être un sous-domaine strict du domaine de production, par exemple staging.example.com pour example.com ou www.example.com (un seul préfixe www. initial est retiré) ; ajoute un site distinct pour tester sur un autre domaine.
<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>Modifier et retirer le consentement
Garde ce contrôle en pied de page. openPreferences ouvre les réglages sans accorder de consentement. Si des adaptateurs SDK ont été exécutés, même un retrait partiel nécessite de recharger le document pour supprimer leur code actif.
Écoute biscotti:beforereload sur window. Le BeforeReloadDetail figé contient le SdkSnapshot actuel, reason (choice, storage, expiry ou error) et navigation (reload ou replace). Pour un choix explicite, la sauvegarde, la mise à jour de Consent Mode, la fermeture des autorisations et consentchange précèdent cet événement. Le refus de secours refuse localement, tente de mettre à jour Consent Mode et de supprimer les préférences (la synchronisation ne supprime pas le choix d’un autre onglet), émet consentchange si nécessaire et un éventuel error, puis beforereload et replace avec refus forcé. Si Consent Mode échoue, les autorisations restent fermées et error signale la panne.
Enregistre l’état de l’application de façon synchrone, par exemple un identifiant de vue dans sessionStorage. Cet événement ne peut pas être annulé ; preventDefault, les exceptions des gestionnaires et les Promise renvoyées n’annulent pas la navigation. Le SDK n’attend pas les opérations asynchrones. Le code synchrone du gestionnaire s’exécute avant la navigation. Le signal couvre les changements locaux, un autre onglet, l’expiration et le refus de secours ; il est absent si aucun rechargement n’est nécessaire. Les cookies et traitements côté serveur nécessitent leurs propres contrôles. Un cookie non signé ne constitue pas une authentification.
Si tu choisis de rester dans le dialogue beforeunload du navigateur, un retrait ultérieur émet à nouveau le signal et retente la navigation.
<button type="button" data-biscotti-preferences>Paramètres des cookies</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 et intégrité
Autorise l’origine de plateforme dans script-src/connect-src, /brand/fonts dans font-src et tes intégrations. Les adaptateurs inline nécessitent un nonce/hash CSP ; le nonce du script est copié. Le SDK insère un style Shadow DOM sans transmettre de nonce de style : une politique stricte doit en tenir compte, le nonce du script ne suffit pas. Aucun CSP universel. CORS accepte l’hôte publié ; le SDK omet credentials et CORS n’authentifie pas les serveurs. Colle le code une seule fois. Les correctifs du script arrivent automatiquement, sans remplacer le code manuellement. Les installations existantes et WordPress fonctionnent de la même façon. Mises à jour automatiques (recommandé): /consent.js. Version fixe avec SRI (avancé): /sdk/<SHA-256>/consent.js, integrity SHA-384, crossorigin="anonymous". Le SDK public et les manifestes autorisent CORS *, mais l’API vérifie toujours l’hôte du site. SRI vérifie JavaScript, pas la configuration API, les polices ni les balises externes. /consent.js reste une URL modifiable pour les installations existantes et WordPress ; ne lui associe pas de hash SRI.
Le bandeau peut utiliser une configuration validée dans localStorage pendant 15 minutes, séparée par plateforme, clé et origine. Chaque document confirme la publication et l’hôte auprès du serveur ; ETag/304 évite de retransmettre une configuration identique. L’acceptation et les scripts facultatifs restent désactivés avant confirmation, tandis que le refus fonctionne immédiatement. Le refus pendant une panne efface l’accord local ; son audit nécessite la configuration actuelle. Une publication ou un changement de consentEpoch renvoie une nouvelle configuration ; retrait, hôte supprimé et erreurs effacent le cache et refusent les autorisations. Le cache ne retarde aucune autorisation dans un nouveau document ; après 8 secondes sans réponse, le refus est maintenu. Un document ouvert conserve sa copie jusqu’à la navigation, sans vérifications périodiques : aucun délai de propagation ne couvre un onglet toujours ouvert. La première visite sans cache attend le serveur. dev_ contourne le cache. Tu ne dois pas modifier le code d’installation.
Erreurs et vérification
Utilise code plutôt que Error.message. whenReady rejette avec BiscottiInitializationError en cas d’échec initial ; getLastError garde la dernière erreur même après un choix réussi. phase vaut initialization/runtime indépendamment du statut final. Les erreurs refusent les catégories facultatives. Gère l’échec de téléchargement sur script. Vérifie Network/Console, hôte, clé, CORS, CSP, stockage et publication. Teste première visite, refus, accord partiel/complet, retour, autre onglet, retrait et panne API/storage. Vérifie séparément les vraies balises GTM et extensions WordPress.
code | Comportement |
|---|---|
INVALID_SITE_KEY | data-site-key absent ou incorrect. |
CONFIGURATION_UNAVAILABLE | Réseau, timeout, taille ou réponse de configuration hors 2xx. |
INVALID_CONFIGURATION | JSON/schéma, clé ou hôte incorrects. |
STORAGE_UNAVAILABLE | Storage/cookie indisponible ou enveloppe endommagée. |
CONSENT_MODE_FAILED | Échec de mise à jour de dataLayer. |
ADAPTER_FAILED | Erreur ou timeout d’adaptateur. |
SYNC_FAILED | File d’audit en échec ou bloquée durablement ; une panne réseau temporaire garde seulement l’entrée en file. |
INITIALIZATION_FAILED | Autre erreur d’initialisation de l’interface ou des écouteurs. |
Versions et historique
API v1 de la version b0449f1, déployée le 2026-10-17. apiVersion identifie le contrat, publicationVersion la configuration et consentEpoch le renouvellement. Ce ne sont pas des URL immuables. Les ajouts conservent v1 ; supprimer une méthode ou changer son sens exige un nouveau contrat.
2026-10-17 — Disponibilité, statut, dernière erreur, trois événements DOM et snapshots figés ; méthodes antérieures conservées. Reprise SPA, phase explicite et nom BiscottiInitializationError vérifiés.
W16 — Mode développeur. Clé distincte pour localhost et staging. Les données de test sont exclues des rapports de production et de la facturation.
Mises à jour automatiques (recommandé): Colle le code une seule fois. Les correctifs du script arrivent automatiquement, sans remplacer le code manuellement. Les installations existantes et WordPress fonctionnent de la même façon. Version fixe avec SRI (avancé): Tu choisis une version précise du script. Elle ne reçoit aucun correctif automatique, y compris de sécurité. Pour la mettre à jour, tu dois remplacer le code manuellement. Les réglages publiés de la bannière sont récupérés automatiquement dans les deux modes.
W20 — Versions SDK et SRI. /sdk/manifest.json indique la version actuelle et les versions conservées. src est l’URL immuable, integrity son hash SHA-384 et bytes sa taille. Chaque version possède aussi un manifeste à côté du script. L’URL contient le SHA-256 du contenu et utilise un cache immutable d’un an ; la configuration du site ne la modifie pas.
Pour une version fixe avec SRI : avant une mise à jour, conserve le code précédent et remplace ensemble src et integrity depuis le panneau ou le manifeste. Garde la clé et crossorigin="anonymous". Teste disponibilité, refus, consentement et retrait sur localhost ou staging. Pour revenir, restaure l’ancienne paire src/integrity. Le build ne remplace ni ne supprime les versions conservées. Une version fixée demande des mises à jour manuelles, y compris de sécurité ; ne supprime pas integrity pour contourner une erreur SRI. Le hash n’est ni apiVersion, ni publicationVersion, ni consentEpoch. Le retour du script ne restaure pas publications ou données ; vérifie d’abord la compatibilité API.
W17 — biscotti:beforereload précède le reload/replace requis après un retrait. BeforeReloadDetail = SdkSnapshot + reason + navigation. Le code synchrone du gestionnaire sur window s’exécute avant la navigation. L’événement ne peut pas annuler la navigation ; le SDK n’attend pas les opérations asynchrones. Consulte l’ordre et l’exemple dans la section sur le retrait.
{
"apiVersion": 1,
"version": "9c2bc03275827be7431adcc709a295afb1f7778553dbaf3c3c4f8a2df233f702",
"src": "/sdk/9c2bc03275827be7431adcc709a295afb1f7778553dbaf3c3c4f8a2df233f702/consent.js",
"integrity": "sha384-VtJRmbHcw1tU2ZG0b1SkNpDBvF0Wk2fuFyZG/CNH7stj+z9FgY8pbYK6eyk5KqmD",
"bytes": 83837
}