Интеграция JavaScript SDK (Client)
HashEntry CMP SDK — это скрипт без зависимостей, который показывает баннер cookie, блокирует помеченные вами скрипты до тех пор, пока посетитель их не разрешит, и записывает каждое решение на сервере HashEntry. Он также может записывать одобрения документов (условия, договоры, политики) — см. Одобрение и подписание документов.
На этой странице описано, что SDK делает на сегодняшний день. Там, где поведение зависит от настройки в панели управления или от вашей собственной разметки, это указано.
Быстрый старт
Заголовок раздела «Быстрый старт»<head> <script src="https://tool.hashentry.com/cmp.js" data-site="YOUR_SITE_API_KEY" async ></script></head>SDK загружает с сервера конфигурацию, привязанную к вашему API-ключу (дизайн баннера, тексты, категории, документы, настройки поведения), и решает, нужен ли баннер этому посетителю.
Чтобы решение о cookie могло быть записано на сервере, должны быть выполнены два условия:
- Сайт подтверждён в панели управления. Запросы для неподтверждённого сайта отклоняются с
403 SITE_NOT_VERIFIED. - К сайту прикреплён документ политики cookie. См. следующий раздел.
Документ политики cookie обязателен
Заголовок раздела «Документ политики cookie обязателен»Согласие на cookie записывается только в том случае, если оно ссылается на точную активную версию документа типа cookie_policy, прикреплённого к сайту. Принятая версия политики является частью доказательства, поэтому SDK не смягчает это правило.
- Если к сайту не прикреплена опубликованная политика cookie, SDK не показывает баннер (а также виджет и ссылку «Do Not Sell») и во всех регионах оставляет заблокированными все помеченные необязательные скрипты: выбор, который нельзя сохранить как доказательство, не собирается. События
consent:errorиerrorсрабатывают сcode: "COOKIE_POLICY_MISSING", а ошибка выводится в консоль браузера.CMP.accept()/CMP.reject()завершаются сsuccess: false,error.code = "COOKIE_POLICY_MISSING"иpending_sync: false; ничего не сохраняется, не применяется и не ставится в очередь. Как только политика будет прикреплена, баннер появится при следующей загрузке страницы, и посетитель примет решение по этой версии. Согласие, записанное в то время, когда политика была прикреплена, остаётся действительным. - Решение никогда не удерживается, чтобы позже быть отправленным с версией политики, которую посетитель не видел. Если предыдущая версия SDK оставила такое решение в локальной очереди, оно отбрасывается (
consent:errorсfinal: true,reprompt: true), и посетителя спрашивают снова. - Единственное исключение — режим
localбезdata-site: на сервер ничего не отправляется, поэтому баннер показывается, а решения остаются в браузере (local_only: true). - Если согласие ссылается на версию, которая не является активной, сервер отвечает
409 CONFIG_OUTDATED. См. Повторное согласие и изменившиеся версии документов.
Что вам нужно сделать: создайте в панели управления документ политики cookie, опубликуйте версию на каждом языке, который использует ваш баннер, и прикрепите документ к сайту.
Блокировка скриптов до согласия
Заголовок раздела «Блокировка скриптов до согласия»Блокируются только те скрипты, которые вы пометили. SDK не сканирует страницу в поисках трекеров и не перехватывает скрипты, которые вы оставили без изменений: обычный тег <script> выполняется сразу, с согласием или без него.
Чтобы придержать скрипт, измените его type на text/plain и укажите его категорию:
<!-- Встроенный скрипт: выполняется только после того, как разрешена категория "analytics" --><script type="text/plain" data-cookie-category="analytics"> /* фрагмент кода аналитики */</script>
<!-- Внешний скрипт: используйте data-src вместо src --><script type="text/plain" data-cookie-category="marketing" data-src="https://connect.facebook.net/en_US/fbevents.js"></script>- Названия категорий должны совпадать с ключами категорий вашего баннера (
analytics,marketing,preferencesили ваши собственные ключи). Скрипты с пометкойnecessaryактивируются сразу, до загрузки конфигурации. - Помеченные скрипты, которые добавляются на страницу позже (навигация в SPA, внедрение тегов), также обрабатываются.
- Скрипт, который уже выполнился, остановить нельзя. Когда посетитель отзывает категорию, скрипты которой выполнились на текущей странице, SDK удаляет известные cookie этой категории и по умолчанию перезагружает страницу (см.
reload_on_revoke). - При отзыве категории SDK удаляет cookie и записи хранилища, перечисленные для этой категории в конфигурации вашего баннера, а также небольшой встроенный список широко известных имён. Cookie, о которых он не знает, не удаляются, а сторонние cookie на других доменах удалить с вашей страницы невозможно.
Атрибуты тега скрипта
Заголовок раздела «Атрибуты тега скрипта»| Атрибут | По умолчанию | Описание |
|---|---|---|
data-site | — | API-ключ сайта. Обязателен в режиме remote; в остальных режимах он также нужен, чтобы решения записывались на сервере. |
data-mode | local-fallback | Источник конфигурации: remote, local, local-fallback. См. Режимы работы. |
data-language | auto | Язык баннера. auto использует <html lang>, затем язык браузера. |
data-region | auto | Принудительно задаёт регион или правовой режим (DE, US, gdpr, ccpa, none, …) вместо определения. Это регион соответствия (каким правилам следует баннер); он не определяет, где хранятся данные и какой хост API вызывается. |
data-config | — | Встроенная JSON-конфигурация (для local / local-fallback). |
data-debug | false | true выводит отладочные сообщения. Ошибки и предупреждения всегда выводятся в консоль. |
data-headless | false | true не отображает никакого интерфейса (баннер, виджет, ссылка «Do Not Sell»). См. Режим headless. |
data-consent-mode | настройка панели управления | true / false принудительно включает или выключает Google Consent Mode v2. См. Google Consent Mode v2. |
data-reload-on-revoke | настройка панели управления | true / false переопределяет флаг поведения reload_on_revoke. |
data-modules | — | Модули, которые нужно загрузить заранее, например documents, preferences. См. Файлы сборки и модули по требованию. |
data-module-base | папка самого скрипта | Базовый URL, с которого загружаются файлы модулей. Нужен только тогда, когда они размещены не рядом с cmp.js. |
data-api-url | API HashEntry | Базовый URL API для first-party прокси или собственного домена. Если у региона данных вашей учётной записи есть собственный хост API, ответ конфигурации сообщает его (api_base_url), и SDK использует его для всех последующих вызовов; код установки, сформированный в панели, уже содержит соответствующий data-api-url. Значение, заданное вами здесь, всегда имеет приоритет. |
JavaScript API (window.CMP)
Заголовок раздела «JavaScript API (window.CMP)»window.CMP существует сразу после выполнения скрипта. Методы, которые что-либо записывают, возвращают промис с объектом результата; они не выбрасывают исключений.
CMP.ready(() => { /* конфигурация загружена, состояние согласия определено */ });
// БаннерCMP.show(); // открыть баннер (например, по ссылке в подвале)CMP.hide();
// Решения — каждый метод возвращает Promise<ConsentResult>CMP.accept(); // разрешить все категорииCMP.accept({ marketing: false }); // разрешить все, кроме marketingCMP.reject(); // только необходимыеCMP.withdraw(); // отозвать сохранённое согласие
// СостояниеCMP.getConsent(); // ConsentState или nullCMP.hasConsent('analytics'); // boolean ("necessary" всегда true)
// ЯзыкCMP.setLanguage('de');CMP.getLanguage();CMP.setLocale('de', { ccpa: { optOut: 'Widersprechen' } }); // тексты для одного языка
// Метаданные: добавляются к каждому согласию и одобрению, записанному после этогоCMP.setMetadata({ order_id: 'ORD-54321' });CMP.setMetadata('customer_id', 'CUST-999');CMP.getMetadata();
// Переопределение региона, тема, URL API, локальная конфигурацияCMP.setRegion('DE');CMP.setTheme({ primaryColor: '#0F766E' });CMP.setApiUrl('/hashentry-api');CMP.getApiUrl();CMP.setConfig({ banner_config: { /* … */ } });
// СобытияCMP.on('consent:given', (payload) => {});CMP.off('consent:given', handler);
// Документы (загружаются по требованию — см. «Одобрение и подписание документов»)CMP.showDocumentApproval('terms-of-service', { language: 'en' });CMP.approveDocument('terms-of-service', { /* … */ });CMP.withdraw()
Заголовок раздела «CMP.withdraw()»Отзыв выключает все необязательные категории, удаляет известные cookie этих категорий, переводит Google Consent Mode в denied, отправляет на сервер решение withdrawn (если согласие было сохранено), удаляет сохранённое согласие из браузера и — в регионах с моделью opt-in — снова показывает баннер. Если скрипты отозванной категории уже выполнились на странице, страница перезагружается, если только reload_on_revoke не выключен.
CMP.setLanguage(lang)
Заголовок раздела «CMP.setLanguage(lang)»Меняет язык открытого баннера и заново загружает конфигурацию для этого языка, поскольку версии документов привязаны к языку: последующие согласия будут ссылаться на версию политики cookie для нового языка. Если у баннера нет перевода на этот язык, используется язык баннера по умолчанию.
CMP.setMetadata(...)
Заголовок раздела «CMP.setMetadata(...)»Значения объединяются и отправляются как metadata с каждым последующим решением о cookie и одобрением документа. Сервер принимает не более 30 ключей и примерно 16 КБ метаданных на запись.
Вызов API до загрузки скрипта
Заголовок раздела «Вызов API до загрузки скрипта»<script> window.__CMP_QUEUE = window.__CMP_QUEUE || []; window.__CMP_QUEUE.push(['setLanguage', 'de']); window.__CMP_QUEUE.push(['setMetadata', { order_id: 'ORD-12345' }]); window.__CMP_QUEUE.push(['on', 'consent:given', (p) => console.log(p)]);</script>Вызовы из очереди выполняются по порядку при запуске SDK. Язык, заданный таким способом, не переопределяется автоматическим определением.
Объекты результата
Заголовок раздела «Объекты результата»ConsentResult (accept, reject, withdraw)
Заголовок раздела «ConsentResult (accept, reject, withdraw)»{ success: true, consent_token: 'ct_…', proof_hash: '…', // 64 шестнадцатеричных символа created_at: '2026-10-10T10:00:00+00:00', idempotency_key: '…' // один UUID на действие пользователя, используется повторно при каждой повторной попытке}success равен true только тогда, когда сервер принял запись. В противном случае:
{ success: false, consent_token: '', proof_hash: '', created_at: '…', error: { code: 'NETWORK_ERROR', status: 0, message: '…' }, pending_sync: true, // хранится в локальной очереди, отправка будет повторена idempotency_key: '…'}error.code— это машинный код сервера или один из кодов SDK, перечисленных ниже;error.status— HTTP-статус (0, если ответ не был получен).pending_sync: trueозначает, что решение применено в браузере и ожидает в локальной очереди (localStorage). Отправка повторяется при следующей загрузке страницы, когда вкладка снова становится видимой и когда браузер снова выходит в сеть, всегда с тем жеidempotency_key, в течение не более 7 дней или 12 попыток.local_only: trueпоявляется, когда отправлять нечего (например, режимlocalбезdata-site).
Выбор посетителя в любом случае применяется в браузере немедленно; результат сообщает вам, есть ли запись о нём на сервере. Исключение — COOKIE_POLICY_MISSING: решение не сохраняется и не применяется.
DocumentApprovalResult
Заголовок раздела «DocumentApprovalResult»{ success: true, decision: 'accepted', consent_token: 'ct_…', proof_hash: '…', slug: 'terms-of-service', version: '2.0.0' }{ success: false, slug: 'terms-of-service', version: '2.0.0', error: { code: 'DOCUMENT_VERSION_CHANGED', status: 409, message: '…' } }Одобрения документов никогда не ставятся в очередь на потом: если success не равен true, одобрение не записано.
События
Заголовок раздела «События»| Событие | Данные события | Когда |
|---|---|---|
ready | {} | Запуск завершён (в том числе когда конфигурацию не удалось загрузить). |
banner:shown | { type } или { headless: true, reason, config } | Баннер был показан или — в режиме headless — должен быть показан вами. |
banner:hidden | { reason } или { headless: true } | Баннер был закрыт. |
consent:given | { decision, categories, source } | Решение, отличное от «отклонить все», сохранено локально. |
consent:rejected | { decision, categories, source } | Решение «отклонить все» сохранено локально. |
consent:changed | { oldCategories, newCategories } | Решение заменило более раннее. |
consent:withdrawn | { categories, cleanedCookies } | Был вызван CMP.withdraw(). |
consent:synced | { consent_token, idempotency_key } | Сервер принял запись (сразу или из очереди). |
consent:error | { code, status, message, idempotency_key, pending_sync, final?, reprompt? } | Запись не удалось доставить. final: true означает, что она была отброшена. |
document:approved | { slug, version, consentId } | Одобрение документа было записано. |
document:rejected | { slug, version } | Посетитель отклонил документ. |
document:error | { slug, version, code, status, message } | Документ не удалось загрузить или одобрение не было записано. |
scripts:activated | { category, count } | Помеченные скрипты категории были активированы. |
config:updated | { content_hash } | Более новая конфигурация заменила кешированную. |
language:changed | { from, to } | Язык изменился. |
error | { scope, code, status, message, … } | Любая из перечисленных выше ошибок; scope принимает значения config, consent, module или document. |
consent:given / consent:rejected срабатывают, когда решение сохранено в браузере. Используйте consent:synced (или результат промиса), когда вам нужно знать, что оно есть на сервере.
Коды ошибок
Заголовок раздела «Коды ошибок»Коды, которые формирует сам SDK:
| Код | Значение |
|---|---|
NOT_READY | Метод принятия решения был вызван до загрузки конфигурации. Вызывайте его внутри CMP.ready(). |
COOKIE_POLICY_MISSING | К сайту не прикреплён опубликованный документ политики cookie. Баннер не показывается, необязательные скрипты остаются заблокированными, а решение не сохраняется и не ставится в очередь. |
NETWORK_ERROR, TIMEOUT | Нет ответа от API (тайм-аут: 5 с на попытку). |
HTTP_<status> | Сервер ответил ошибкой, не содержащей машинного кода. |
DOCUMENT_VERSION_CHANGED | Указанная версия документа больше не является активной; запись была отброшена. |
PENDING_EXPIRED | Решение из очереди не удалось доставить в течение 7 дней, и оно было отброшено. |
MODULE_LOAD_FAILED | Не удалось загрузить файл модуля (documents или preferences). Также сообщается через событие error с scope: "module". |
APPROVAL_TOKEN_REQUIRED | Документ требует одноразового токена одобрения, а токен не был передан (этот код возвращает и сервер). |
CONFIG_UNAVAILABLE | Конфигурацию не удалось загрузить (сообщается через событие error). |
UNEXPECTED_ERROR | Всё остальное. |
Коды, возвращаемые сервером, передаются без изменений. Наиболее важные из них перечислены на странице REST API — например, CONFIG_OUTDATED, SITE_NOT_VERIFIED, ORIGIN_NOT_ALLOWED, RATE_LIMIT_EXCEEDED, CONSENT_LIMIT_EXCEEDED, APPROVAL_TOKEN_INVALID.
Временные ответы сервера. 503 (API_KEY_LOOKUP_UNAVAILABLE, ADMISSION_UNAVAILABLE, QUEUE_OVERLOADED) и 429 RATE_LIMIT_EXCEEDED автоматически повторяются с тем же idempotency_key; SDK ожидает время, указанное в заголовке Retry-After. Если это время превышает 5 секунд, SDK не ждёт на странице: решение остаётся в локальной очереди (pending_sync: true) и отправляется позже. После 429 TOO_MANY_INVALID_API_KEYS SDK не отправляет других запросов в течение этого просмотра страницы, а решения в очереди сохраняются; проверьте значение data-site. Ни один из этих ответов не влияет на вашу страницу: срабатывает событие error, а обратные вызовы CMP.ready() всё равно выполняются.
Заголовок раздела «Временные ответы сервера. 503 (API_KEY_LOOKUP_UNAVAILABLE, ADMISSION_UNAVAILABLE, QUEUE_OVERLOADED) и 429 RATE_LIMIT_EXCEEDED автоматически повторяются с тем же idempotency_key; SDK ожидает время, указанное в заголовке Retry-After. Если это время превышает 5 секунд, SDK не ждёт на странице: решение остаётся в локальной очереди (pending_sync: true) и отправляется позже. После 429 TOO_MANY_INVALID_API_KEYS SDK не отправляет других запросов в течение этого просмотра страницы, а решения в очереди сохраняются; проверьте значение data-site. Ни один из этих ответов не влияет на вашу страницу: срабатывает событие error, а обратные вызовы CMP.ready() всё равно выполняются.»Повторное согласие и изменившиеся версии документов
Заголовок раздела «Повторное согласие и изменившиеся версии документов»Когда баннер показывается снова. Сохранённое согласие запоминает хеш содержимого конфигурации баннера, для которой оно было дано. Баннер показывается снова, когда:
- срок действия согласия истёк (срок действия задаётся в панели управления),
- изменилась структура категорий / cookie баннера или
- была опубликована новая версия прикреплённого документа — если только настройка баннера
reconsent_on_doc_changeне выключена; в этом случае повторное согласие запрашивается только при изменениях структуры.
Пока в регионе с моделью opt-in ожидается повторное согласие, предыдущий выбор посетителя остаётся в силе до тех пор, пока он не примет решение снова.
Ожидающие решения и изменившаяся версия документа. Если решение не удалось доставить (нет сети, страница закрыта, ошибка сервера) и при повторной отправке версия документа, на которую оно ссылается, уже не является активной, SDK:
- запрашивает у сервера текущую конфигурацию в обход кеша;
- если версия не изменилась (ответ 409 был вызван холодным кешем сервера), отправляет ту же запись ещё один раз;
- если версия изменилась, отбрасывает запись, удаляет локально сохранённое согласие и снова показывает баннер (
consent:errorсcode: "DOCUMENT_VERSION_CHANGED",final: true,reprompt: true).
Ожидающая запись никогда не отправляется повторно с другой версией документа: посетитель этой версии не видел.
Регионы, профили регулирования и флаги поведения
Заголовок раздела «Регионы, профили регулирования и флаги поведения»Регион посетителя определяется в следующем порядке: CMP.setRegion() → data-region → результат GeoIP сервера в ответе с конфигурацией (detected_region) → оценка по часовому поясу браузера → фиксированный режим регулирования баннера → самые строгие правила (GDPR). SDK никогда не обращается к сторонним сервисам геолокации.
| Регион | Правовой режим | Модель | Поведение |
|---|---|---|---|
| ЕС / ЕЭЗ, Швейцария | gdpr | opt-in | Баннер; помеченные скрипты заблокированы, пока не разрешены. |
| Турция | kvkk | opt-in | Так же, как для GDPR. |
| Великобритания | uk_gdpr | opt-in | Так же, как для GDPR (см. uk_analytics_exemption). |
| Бразилия | lgpd | opt-in | Так же, как для GDPR. |
| ЮАР, Канада, Китай, Южная Корея | popia, pipeda, pipl, pipa | opt-in | Применяются правила баннера GDPR. |
| США | ccpa — только если включено, иначе gdpr | opt-out / opt-in | См. ccpa_opt_out_enabled. |
| Неизвестно | gdpr | opt-in | Самые строгие правила. |
none (явно) | none | — | Без баннера; все скрипты выполняются. |
В каждом профиле opt-in у баннера всегда есть кнопка «Отклонить» с тем же визуальным весом, что и у кнопки «Принять», и ни одна необязательная категория не выбрана заранее — независимо от того, что задано в дизайне баннера.
Это поведение меняют три флага поведения (баннер → настройки поведения в панели управления, banner_config.behavior в локальной конфигурации):
| Флаг | По умолчанию | Эффект |
|---|---|---|
uk_analytics_exemption | выключен | Только для посетителей из Великобритании: скрипты с пометкой analytics могут выполняться до принятия решения. Для любой другой категории согласие по-прежнему необходимо, а после того как посетитель принял решение, применяется его решение. |
ccpa_opt_out_enabled | выключен | Посетители, определённые как находящиеся в США, получают модель opt-out: скрипты выполняются по умолчанию, показывается ссылка «Do Not Sell or Share My Personal Information», а сигнал Global Privacy Control применяется один раз как opt-out (consent_type: do_not_sell_opt_out). Когда флаг выключен, посетители из США получают баннер opt-in. |
reload_on_revoke | включён | Перезагружать страницу, когда посетитель отзывает категорию, скрипты которой уже выполнились на этой странице. Выключайте его, только если ваши теги сами реагируют на изменения согласия. |
Google Consent Mode v2
Заголовок раздела «Google Consent Mode v2»Когда Consent Mode включён, SDK создаёт window.dataLayer и функцию gtag, если их ещё нет, и отправляет:
gtag('consent', 'default', { …all denied…, wait_for_update: 500 })во время запуска,gtag('consent', 'update', { … })после каждого решения и при каждой загрузке страницы с сохранённым согласием.
| Сигнал | Получает значение granted, когда разрешена эта категория |
|---|---|
ad_storage, ad_user_data, ad_personalization | marketing |
analytics_storage | analytics |
functionality_storage, personalization_storage | preferences |
security_storage | всегда |
SDK также отправляет в data layer события hashentry_consent_default и hashentry_consent_update.
Настройка:
- Включите Google Consent Mode для баннера в панели управления или добавьте
data-consent-mode="true"в тег скрипта. - Разместите тег скрипта HashEntry выше вашего тега Google / фрагмента GTM.
- Если команда
defaultдолжна предшествовать тегам Google при самом первом просмотре страницы посетителем, используйтеdata-consent-mode="true"и загружайтеcmp.jsбезasync. Настройка панели управления приходит вместе с конфигурацией, которая при первом посещении загружается асинхронно; при последующих посещениях она читается из кешированной конфигурации во время запуска.
Consent Mode только отправляет сигналы. Теги, которые не управляются Consent Mode, по-прежнему нужно помечать для блокировки, как описано выше.
Режим headless
Заголовок раздела «Режим headless»С data-headless="true" SDK ничего не отображает. Он по-прежнему загружает конфигурацию, блокирует помеченные скрипты, обновляет Consent Mode и записывает решения.
CMP.on('banner:shown', ({ headless, reason, config }) => { if (headless) openMyBanner(config); // reason: no_consent | expired | reconsent | withdrawn | api | opt_out});
myAcceptButton.onclick = async () => { const result = await CMP.accept({ analytics: true, marketing: false }); if (!result.success && !result.pending_sync) showError(result.error);};Режимы работы
Заголовок раздела «Режимы работы»| Режим | Источник конфигурации |
|---|---|
remote | Только сервер. data-site обязателен. |
local | Только страница (CMP.setConfig, data-config или <script type="application/json" id="cmp-config">). |
local-fallback (по умолчанию) | Сервер; если он недоступен — конфигурация страницы. |
Режим определяет только то, откуда берётся конфигурация. Решения отправляются на сервер в любом режиме, пока задан data-site. В режиме local без data-site решения хранятся только в браузере (local_only: true).
Локальная конфигурация имеет ту же структуру, что и ответ сервера:
<script type="application/json" id="cmp-config">{ "banner_config": { "layout": "bottom_bar", "theme": { "primary_color": "#2563EB", "font_family": "system", "theme_mode": "auto" }, "behavior": { "show_widget": true, "show_reject_button": true, "show_settings_button": true }, "categories": [ { "key": "necessary", "required": true, "default": true }, { "key": "analytics", "required": false, "default": false, "cookies": [{ "name": "_ga", "provider": "Google", "type": "cookie", "duration": "2 years" }] } ], "languages": { "default": "en", "translations": { "en": { "title": "Cookie preferences", "description": "We use cookies to measure how the site is used.", "accept_button_text": "Accept all", "reject_button_text": "Reject all", "settings_button_text": "Manage preferences", "save_selected_text": "Save selection", "modal_title": "Cookie settings", "always_active_text": "Always active", "categories": { "necessary": { "label": "Necessary", "description": "Required for the site to work." }, "analytics": { "label": "Analytics", "description": "Visitor statistics." } } } } } }}</script><script src="https://tool.hashentry.com/cmp.js" data-site="YOUR_SITE_API_KEY" data-mode="local" async></script>Если задан data-site, SDK при запуске один раз запрашивает у сервера документ политики cookie, поскольку согласие должно ссылаться на его версию. Если политика не прикреплена, баннер не показывается (COOKIE_POLICY_MISSING). Чтобы показывать баннер даже при недоступности сервера, включите documents (политику cookie и её версию) в конфигурацию на странице.
Языки и тексты
Заголовок раздела «Языки и тексты»Все тексты баннера (заголовок, описание, кнопки, названия категорий) берутся из конфигурации баннера — они не являются частью скрипта.
SDK поставляется с небольшим встроенным словарём, только на английском и турецком языках, для текстов, относящихся к его собственному интерфейсу: диалог «Do Not Sell», кнопки и строка ошибки одобрения документа, заголовки таблицы cookie и кнопка закрытия. На любом другом языке эти тексты отображаются на английском, если вы не зададите их сами:
CMP.setLocale('de', { document: { approve: 'Ich stimme zu', reject: 'Ablehnen', saving: 'Wird gespeichert…', error: 'Ihre Zustimmung konnte nicht gespeichert werden. Bitte versuchen Sie es erneut.' }, ccpa: { link: '…', description: '…', cancel: 'Abbrechen', optOut: 'Widersprechen' }, cookies: { name: 'Name', provider: 'Anbieter', type: 'Typ', duration: 'Dauer', purpose: 'Zweck', category: 'Kategorie', count: '{n} Cookies', empty: 'Keine Cookies registriert.' }});Конфигурация может содержать те же ключи для каждого языка в languages.translations.<lang>.sdk_texts.
Файлы сборки и модули по требованию
Заголовок раздела «Файлы сборки и модули по требованию»| Файл | Содержимое | Чем загружается |
|---|---|---|
cmp.js | Ядро и согласие на cookie | Вашим тегом скрипта. |
cmp-documents.<hash>.js | Одобрение документов (showDocumentApproval, approveDocument) | Скриптом cmp.js, при первом вызове одного из этих методов. |
cmp-preferences.<hash>.js | Центр настроек, таблица сведений о cookie, диалог подтверждения «Do Not Sell» | Скриптом cmp.js, когда посетитель впервые открывает одно из них. |
Вы никогда не добавляете второй тег скрипта. Сайт, который использует только баннер cookie, никогда не скачивает модуль документов.
- Файл модуля запрашивается из того же расположения, что и
cmp.js(оно определяется поsrcскрипта). - Чтобы избежать короткой задержки при первом вызове, загрузите модуль заранее:
data-modules="documents". - Вызовы, сделанные до того, как модуль загрузился, просто ожидают его. Если модуль не удаётся загрузить, метод завершается с
success: falseиerror.code = "MODULE_LOAD_FAILED"; следующий вызов предпринимает новую попытку. - Если модуль
preferencesне удаётся загрузить, баннер остаётся на экране с кнопками принятия и отклонения, срабатывает событиеerrorсscope: "module"иcode: "MODULE_LOAD_FAILED", а следующий клик предпринимает новую попытку. Чтобы центр настроек открывался без задержки, загрузите модуль заранее:data-modules="preferences". - Имя файла содержит хеш содержимого, который встраивается в
cmp.jsво время сборки, поэтомуcmp.jsвсегда запрашивает модуль, собранный вместе с ним.
Content Security Policy. Модуль загружается с помощью элемента <script> с того же источника (origin), что и cmp.js; SDK не использует ни eval, ни встроенные скрипты. Для скриптов достаточно указать источник SDK:
script-src https://tool.hashentry.com;connect-src https://system.hashentry.com;- SDK оформляет свой интерфейс с помощью элементов
<style>внутри собственного shadow root. Если ваша политика ограничиваетstyle-src, либо разрешите'unsafe-inline'для стилей, либо используйте nonce: укажите nonce в тегеcmp.js(<script nonce="…" …>), и SDK скопирует его в элементы стилей и в создаваемый им тег скрипта модуля. - При
script-src 'strict-dynamic'и nonce в тегеcmp.jsскрипт модуля разрешается без указания источника в списке. - Диалог одобрения документа отображает документ в изолированном (sandboxed)
iframeбезsrc; скрипты внутри документа не выполняются.
Subresource Integrity. https://tool.hashentry.com/cmp.js обновляется по тому же адресу при выходе новой версии SDK, поэтому атрибут integrity для этого URL перестал бы работать при следующем релизе. Если вам нужен SRI, разместите проверенную копию cmp.js вместе с файлами cmp-documents.*.js / cmp-preferences.*.js той же сборки на собственном источнике и задайте integrity в своём теге.
Самостоятельный хостинг. Скопируйте cmp.js, cmp-documents.<hash>.js, cmp-preferences.<hash>.js, cmp-preferences.js и cmp-documents.js из одной и той же сборки в одну папку. Если файлы модулей находятся в другом месте, задайте data-module-base.
First-party прокси
Заголовок раздела «First-party прокси»Чтобы отправлять запросы API через собственный домен, задайте в data-api-url (или через CMP.setApiUrl) путь или URL на вашей стороне и перенаправляйте его на API HashEntry, не изменяя путь после префикса:
<script src="https://tool.hashentry.com/cmp.js" data-site="YOUR_SITE_API_KEY" data-api-url="/hashentry-api" async></script># /hashentry-api/tool/v1/consents → https://system.hashentry.com/tool/v1/consentslocation /hashentry-api/ { proxy_pass https://system.hashentry.com/; proxy_set_header Host system.hashentry.com; proxy_ssl_server_name on; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}Подпись запроса охватывает путь /tool/v1/..., поэтому запрос к вышестоящему серверу должен прийти именно с этим путём. Записанный IP-адрес — это тот адрес, который видит HashEntry; будет ли адрес посетителя взят из X-Forwarded-For, зависит от того, считается ли прокси доверенным на стороне HashEntry, — уточните это в службе поддержки, прежде чем на это полагаться.
Что SDK хранит в браузере
Заголовок раздела «Что SDK хранит в браузере»| Имя | Где | Назначение |
|---|---|---|
_he_consent | first-party cookie | Решение посетителя (категории, метки времени, серверный токен). |
he_consent_token | localStorage | Копия того же решения. |
he_config_cache | localStorage | Кешированная конфигурация (до 7 дней, повторно проверяется в фоне при каждой загрузке). |
he_pending_consents | localStorage | Решения, ещё не принятые сервером (удаляются после доставки; отбрасываются через 7 дней). |
he_gpc_applied | localStorage | Отмечает, что opt-out по сигналу GPC был применён один раз. |
he_sdk_reload | sessionStorage | Защищает самообновление SDK от циклов перезагрузки. |
SDK не загружает шрифты и какие-либо другие ресурсы у третьих сторон.