Документація для інтеграторів
Установи Biscotti та поєднай інтеграції з вибором відвідувача. Опис розгорнутого API v1.
Установлення HTML
Додай точний хост, установи код, перевір установлення та опублікуй конфігурацію. Скопіюй код із розділу встановлення. Заміни YOUR_SITE_KEY публічним ключем і вкажи адресу платформи: https://biscotti.dev для продукції або окрему https://dev.biscotti.dev для dev. Ключ не надає адміністративного доступу. Додай один SDK у head перед інтеграціями; використовуй один спосіб на документ. Звичайні активні скрипти можуть запуститися до відкладеного SDK, тому познач їх як неактивні. Залиш постійні налаштування cookie у футері.
Автоматичні оновлення (рекомендовано)
Встав код один раз. Виправлення скрипту надходять автоматично, без ручної заміни коду. Наявні встановлення та WordPress працюють так само.
<script id="biscotti-sdk" src="https://biscotti.dev/consent.js" data-site-key="YOUR_SITE_KEY" defer></script>Закріплена версія із SRI (розширені)
Ти обираєш конкретну версію скрипту. Автоматичних виправлень, зокрема безпеки, не буде. Для оновлення потрібно вручну замінити код. Опубліковані налаштування банера завантажуються автоматично в обох режимах.
<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
Завантаж ZIP, установи й активуй плагін. У Biscotti → Встановлення → WordPress скопіюй URL платформи та публічний ключ у плагін. Адміністратор створює тимчасовий одноразовий код підключення. Не додавай коди й облікові дані до HTML. Підключи точний хост, опублікуй конфігурацію та прибери дублікати SDK. Підключення й імпорт не публікують чернетку та не блокують усі інші плагіни. Перевір справжні скрипти теми й плагінів.
Завантажити · WordPressGoogle Tag Manager — Basic
Установи Biscotti поза контейнером. Видали звичайний код GTM та iframe noscript. Додай завантажувач після SDK, замінивши GTM-XXXXXXX. Він чекає аналітичної згоди; змішаний контейнер потребує правил кожного тега. Встав завантажений шаблон у Код власного шаблону GTM, не Custom HTML. Дозволь access_consent write для семи сигналів, access_globals виконання Biscotti.onConsentChange, Biscotti.canActivate і dataLayer.push, читання/запис dataLayer. Використай Consent Initialization – All Pages і додаткові вимоги згоди тегів. Перевір Preview / Tag Assistant. biscotti_consent_update у dataLayer відрізняється від DOM biscotti:consentchange. Правилам потрібна додатна умова canActivate. Шаблону немає в 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>Завантажити · GTMAPI та готовність
Наявність window.Biscotti чи load не означає готовність. Конфігурація починає завантажуватися до DOMContentLoaded; UI чекає на DOM. Ready означає перевірену публікацію, визначені налаштування, UI, дозволи, Consent Mode та слухачі іншої вкладки. Відсутність вибору й збережена відмова є коректними. Готовність не чекає аудиту, переглядів, шрифтів чи зовнішніх тегів. Відновлені адаптери стартують після початкових подій; Promise callback може виконатись після синхронного адаптера. ready/error — кінцеві стани ініціалізації. Помилка виконання не змінює ready. Після помилки запуску новий вибір далі надсилає зміни, але whenReady залишається відхиленим.
| Метод | Поведінка |
|---|---|
apiVersion | Константа 1: версія контракту. |
openPreferences() | Відкриває налаштування; у loading ставить запит у чергу, без надання згоди. |
getConsent() | Нова змінювана копія шести boolean; necessary завжди true. |
canActivate(ruleId) | Додатний дозвіл опублікованого правила; невідоме, призупинене чи недоступне дає false. |
onConsentChange(callback) | Callback одразу з копією і після застосування налаштувань; може повторювати стан. Повертає unsubscribe, ізолює винятки. |
getStatus() | loading/ready/error ініціалізації, не рішення. |
whenReady() | Promise замороженого початкового знімка також для пізніх слухачів; відхиляється при помилці запуску. |
getLastError() | Остання заморожена помилка або null; успішний вибір не стирає історію. |
Події DOM і дані
Слухай window до завантаження SDK. ready надходить раз; consentchange додає reason, error — code/phase до знімка. Це CustomEvent без поширення та скасування. Пізні слухачі використовують whenReady/getConsent/getLastError. Запуск: стан/GCM/UI → callbacks → ready → початковий consentchange → адаптери. Зміна: стан → callbacks → consentchange → активація або reload. Помилка: відмова необов’язкових → consentchange за зміни → error; помилка запуску не дає ready. Знімок і consents заморожені, без ID рішення, cookie, URL відвідувача та винятків. hasDecision розрізняє відмову й відсутність вибору; до перевірки метадані null. Виняток слухача не зупиняє застосування згоди; підтвердження аудиту не дублює події.
W17 — biscotti:beforereload передує потрібному reload/replace після відкликання згоди. BeforeReloadDetail = SdkSnapshot + reason + navigation. Синхронний код обробника на window виконується перед навігацією. Подія не скасовує навігацію; SDK не чекає асинхронних операцій. Порядок і приклад є в розділі про відкликання.
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';
};Застосунки SPA
Запусти приклад, коли елемент script SDK вже існує в DOM, до завершення завантаження файлу або після нього. Установи SDK раз в оболонці документа. Підписуйся незалежно від успіху whenReady. Приклад оновлює атрибут DOM; під час демонтажу виклич disconnectBiscotti. whenReady завжди повертає початковий знімок; поточний вибір отримуй через getConsent чи підписку. Навігація SPA не запускає ініціалізацію та не завантажує нову публікацію. Новий неактивний елемент можна активувати один раз. Не замінюй window.Biscotti заглушкою або чергою методів.
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();
}Адаптери неактивних скриптів
Використай type="text/plain", data-consent-category, а для зовнішнього скрипту — data-consent-src замість src. Заміни приклад URL. Необов’язкові категорії початково вимкнені; елемент запускається раз у документі після згоди. Підтримуються класичні inline та HTTP(S) скрипти з копіюванням nonce, integrity і crossorigin. Модулі, nomodule, iframe noscript, довільні пікселі й серверні cookie поза контрактом. Адаптер категорії не залежить від паузи правил; canActivate перевіряє опубліковане правило без запуску тега. Змішані теги перевір окремо.
<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>Категорії та Google Consent Mode
Необов’язкові сигнали починаються з denied, security_storage — granted; оновлюються за таблицею. Це Basic, без автоматичного встановлення GA/GTM чи Advanced. performance та unclassified не мають власного Google-сигналу: застосовуй категорію або додатний дозвіл правила. Відсутність сигналу не дає права запуску. Вимкнені категорії не надаються. Для GTM потрібні також додаткові вимоги згоди й відповідні умови правил.
performance охоплює технічні вимірювання: швидкість завантаження та стабільність сайту. Вимірювання трафіку, поведінки відвідувачів, GA4 і Clarity віднеси до analytics; вимірювання кампаній і ремаркетинг — до advertising, навіть якщо інструмент також вимірює швидкість. Враховуй фактичну мету; розділи інструмент із кількома цілями або вимагай усі відповідні згоди. performance та unclassified не мають власного сигналу Google. Лише performance не надає analytics_storage чи рекламних згод. Для скриптів вимагай цю категорію або додатний дозвіл опублікованого правила; відсутність сигналу не є дозволом. У GTM вимагай biscottiPerformance дорівнює true, а для правила також його додатний дозвіл. Не створюй performance_storage. Значення збережених згод не змінюється; ця правка не потребує нового рішення. Якщо змінюєш мету чи обсяг, публікуй з оновленням згод.
| Категорія | Поведінка | Google Consent Mode |
|---|---|---|
necessary | Основні функції сайту, безпека та збереження рішення. Завжди активні. | security_storage = granted |
functional | Додаткові функції та збереження налаштувань відвідувача. | functionality_storage, personalization_storage |
analytics | Вимірювання трафіку та аналіз використання сайту. | analytics_storage |
advertising | Персоналізація реклами та вимірювання ефективності кампаній. | ad_storage, ad_user_data, ad_personalization |
performance | Вимірювання швидкості, стабільності та продуктивності сайту. | Немає власного сигналу Google |
unclassified | Інші файли cookie, призначення яких ще потрібно визначити. | Немає власного сигналу Google |
Домени й тестування
Публікація відповідає точному hostname: example.com, www.example.com і shop.example.com різні. SDK та CORS перевіряють хост; ключ не обходить перевірку. Налаштування host-only, без автоматичного поширення між субдоменами. Dev і продукція мають окремі дані. Винятку localhost і пов’язаного staging в одній ліцензії ще немає. Playground не має особливих дозволів; localhost на хостованій платформі може не пройти перевірку. Використай доступний тестовий хост із перевіреною публікацією. Нова публікація завантажується в новому документі.
Окремий ключ для localhost і staging. Тестові дані не входять до виробничих звітів і розрахунків. Спочатку збережіть чернетку та затвердьте інформацію про cookies. Копія використовує ці дані й останні опубліковані правила (до публікації — жодних). Кожне збереження поновлює тестову згоду. Localhost, 127.0.0.1 і [::1] потребують точного порту. Staging потребує HTTPS на порту 443 і перевірки встановлення з тестовим ключем. Виробничий хост виключено.
У панелі виберіть Встановлення → Режим розробника → Зберегти тестову конфігурацію, додайте http://localhost:5173 і скопіюйте код dev_. Запустіть приклад на цьому origin із розміщеною платформою Biscotti, без локального встановлення платформи. Виробничі дані та ключ site_ залишаються окремими. Для staging додайте точний HTTPS origin, встановіть код на головній сторінці та перевірте встановлення. Перевірка не звертається до приватних адрес.
Налаштування та черга відокремлені ключем і origin, включно з портом. Знімки та події додають environment: development; банер позначає тест. Вимкнення, видалення origin чи оновлення ключа блокує подальші запити; відкриті документи перезавантажте. Ключ публічний: Origin обмежує браузери, не автентифікує сервери. Адаптери після згоди запускають справжні інтеграції: використовуйте тестові облікові записи. Додатковий ліцензований сайт чи пов’язаний staging не створюється. Оновлення видаляє лише тестові дані та потребує повторної перевірки staging.
Обмеження: 10 origin, 20 конфігурацій, 1000 рішень і 1000 переглядів. Оновіть ключ для скидання.
Публічний staging має бути власним піддоменом виробничого домену, наприклад staging.example.com для example.com або www.example.com (відкидається лише один початковий префікс www.); для тестів на іншому домені додай окремий сайт.
<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>Зміна та відкликання згоди
Залиш цей елемент у підвалі сайту. openPreferences відкриває налаштування без надання згоди. Якщо SDK запустив адаптери, навіть часткове відкликання потребує перезавантаження документа для видалення їхнього активного коду.
Слухай biscotti:beforereload на window. Заморожений BeforeReloadDetail містить поточний SdkSnapshot, reason (choice, storage, expiry або error) та navigation (reload або replace). За явного вибору перед подією відбуваються збереження налаштувань, оновлення Consent Mode, закриття шлюзів і consentchange. Аварійна відмова спершу відмовляє локально, намагається оновити Consent Mode й видалити налаштування (синхронізація вкладок не видаляє вибір іншої вкладки), надсилає consentchange за зміни та можливий error, потім beforereload і replace з примусовою відмовою. Якщо Consent Mode не працює, шлюзи залишаються закритими, а error повідомляє про збій.
Збережи стан застосунку синхронно, наприклад ідентифікатор подання у sessionStorage. Подію неможливо скасувати; preventDefault, виняток обробника та повернений Promise не скасовують навігацію. SDK не чекає асинхронних операцій. Синхронний код обробника виконується перед навігацією. Сигнал охоплює локальні зміни, іншу вкладку, завершення строку та аварійну відмову; без потреби перезавантаження його немає. Серверні cookies й обробка потребують власних перевірок. Непідписаний cookie не є автентифікацією.
Якщо залишишся на сторінці через діалог beforeunload браузера, наступне відкликання знову надішле сигнал і повторить навігацію.
<button type="button" data-biscotti-preferences>Налаштування 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 і цілісність
Дозволь origin платформи в script-src/connect-src, /brand/fonts у font-src та потрібні інтеграції. Inline адаптери потребують CSP nonce/hash; nonce скрипту копіюється. SDK вставляє стиль у Shadow DOM без nonce стилю: сувора політика має це враховувати, nonce скрипту недостатньо. Універсального CSP немає. CORS допускає хост публікації; SDK пропускає credentials, а CORS не автентифікує сервери. Встав код один раз. Виправлення скрипту надходять автоматично, без ручної заміни коду. Наявні встановлення та WordPress працюють так само. Автоматичні оновлення (рекомендовано): /consent.js. Закріплена версія із SRI (розширені): /sdk/<SHA-256>/consent.js, integrity SHA-384, crossorigin="anonymous". Публічний SDK та маніфести дозволяють CORS *, але API далі перевіряє хост сайту. SRI перевіряє JavaScript, а не конфігурацію API, шрифти чи зовнішні теги. /consent.js залишається змінною адресою для наявних установлень і WordPress; не закріплюй SRI для неї.
Банер може 15 хвилин використовувати перевірену конфігурацію в localStorage, окремо для платформи, ключа й origin. Кожен документ перевіряє поточну публікацію та хост на сервері; ETag/304 усуває повторне передавання незмінної конфігурації. Прийняття й необов’язкові скрипти вимкнені до перевірки, а відмова працює одразу. Відмова під час збою скасовує локальну згоду; запис аудиту потребує актуальної конфігурації. Публікація або зміна consentEpoch повертає нову конфігурацію; відкликання публікації, видалення хоста й помилки очищають кеш та забороняють дозволи. Кеш не затримує перевірку дозволів у новому документі; після 8 секунд без відповіді залишається відмова. Відкритий документ зберігає знімок до нового завантаження без періодичних запитів, тому для постійно відкритої вкладки немає строку поширення змін. Перший візит без кешу чекає на сервер. dev_ оминає кеш. Інсталяційний код змінювати не потрібно.
Помилки та перевірка
Використовуй стабільний code, не Error.message. При помилці запуску whenReady відхиляється з BiscottiInitializationError; getLastError зберігає останню помилку навіть після успішного вибору. phase — initialization/runtime незалежно від кінцевого стану. Помилка вимикає необов’язкові категорії. Помилку завантаження SDK обробляй на script. У DevTools перевір Network/Console, хост, ключ, CORS, CSP, сховище й публікацію. Перевір перший візит, відмову, часткову/повну згоду, повернення, іншу вкладку, відкликання, недоступність API/storage. Реальні GTM теги й плагіни WordPress перевір окремо.
code | Поведінка |
|---|---|
INVALID_SITE_KEY | Відсутній або неправильний data-site-key. |
CONFIGURATION_UNAVAILABLE | Мережа, timeout, розмір або конфігурація поза 2xx. |
INVALID_CONFIGURATION | Неправильний JSON/схема, ключ або хост. |
STORAGE_UNAVAILABLE | Недоступні storage/cookie чи пошкоджена структура. |
CONSENT_MODE_FAILED | Не вдалося оновити dataLayer. |
ADAPTER_FAILED | Помилка або timeout адаптера. |
SYNC_FAILED | Помилка чи постійне блокування черги аудиту; тимчасова мережева помилка лише залишає запис у черзі. |
INITIALIZATION_FAILED | Інша помилка ініціалізації UI або слухачів. |
Версії та історія
API v1 із випуску b0449f1, розгорнутого 2026-10-17. apiVersion — контракт, publicationVersion — конфігурація, consentEpoch — поновлення налаштувань. Це не незмінні URL скрипту. Доповнення зберігають v1; видалення методу чи зміна значення потребує нового контракту.
2026-10-17 — Готовність, стан, остання помилка, три DOM-події та заморожені знімки; попередні методи збережено. Перевірено відновлення SPA, явну фазу та назву BiscottiInitializationError.
W16 — Режим розробника. Окремий ключ для localhost і staging. Тестові дані не входять до виробничих звітів і розрахунків.
Автоматичні оновлення (рекомендовано): Встав код один раз. Виправлення скрипту надходять автоматично, без ручної заміни коду. Наявні встановлення та WordPress працюють так само. Закріплена версія із SRI (розширені): Ти обираєш конкретну версію скрипту. Автоматичних виправлень, зокрема безпеки, не буде. Для оновлення потрібно вручну замінити код. Опубліковані налаштування банера завантажуються автоматично в обох режимах.
W20 — Випуски SDK і SRI. /sdk/manifest.json містить поточний і збережені випуски. src — незмінна адреса, integrity — її хеш SHA-384, bytes — розмір файлу. Кожен випуск має маніфест поряд зі скриптом. Адреса містить SHA-256 вмісту й кешується на рік як immutable; зміна конфігурації її не змінює.
Для закріпленої версії із SRI: для оновлення збережи попередній код і заміни разом src та integrity з панелі або маніфесту. Залиш ключ і crossorigin="anonymous". На localhost або staging перевір готовність, відмову, згоду та відкликання. Для повернення віднови попередню пару src/integrity. Build не перезаписує й не видаляє старі випуски. Закріплені випуски потребують ручного оновлення, також для безпеки; не обходь помилку SRI видаленням integrity. Хеш не є apiVersion, publicationVersion чи consentEpoch. Повернення скрипту не повертає публікації чи дані; спершу перевір сумісність API.
W17 — biscotti:beforereload передує потрібному reload/replace після відкликання згоди. BeforeReloadDetail = SdkSnapshot + reason + navigation. Синхронний код обробника на window виконується перед навігацією. Подія не скасовує навігацію; SDK не чекає асинхронних операцій. Порядок і приклад є в розділі про відкликання.
{
"apiVersion": 1,
"version": "9c2bc03275827be7431adcc709a295afb1f7778553dbaf3c3c4f8a2df233f702",
"src": "/sdk/9c2bc03275827be7431adcc709a295afb1f7778553dbaf3c3c4f8a2df233f702/consent.js",
"integrity": "sha384-VtJRmbHcw1tU2ZG0b1SkNpDBvF0Wk2fuFyZG/CNH7stj+z9FgY8pbYK6eyk5KqmD",
"bytes": 83837
}