Consent
Баннер cookie-согласия: платформенный, учитывающий тему, со скрытым узлом и рантаймом — по тому же паттерну, что
Dialog
. Спрашивает у посетителя разрешение на категории скриптов, вставок и счётчиков.
Баннеру элемент не нужен.
Страница, на которой есть что гейтить, получает стандартный баннер сама, на языке страницы. Элемент
Consent
задаёт свои тексты, ссылку на политику и край экрана.
Тип:
leaf
(скрытый узел + рантайм)
Только веб:
на Flutter-рендере элемент — no-op (чтения
$consent.*
отвечают «не дано», вызовы
consent.*
ничего не делают).
Consent position:bottom policyLabel:$strings.cookiesPolicy policyUrl:"/privacy"
Параметры
| Параметр | Тип | Default | Описание |
|---|---|---|---|
position
|
bottom
|
top
|
bottom
|
К какому краю прижат баннер |
policyLabel
,
policyUrl
|
string | — | Ссылка на политику конфиденциальности; показывается, когда заданы оба |
always
|
bool | false | Показывать баннер, даже когда в документе нет ничего, что ждёт согласия |
title
,
message
,
acceptLabel
,
rejectLabel
|
string /
$strings
|
на языке страницы | Заголовок, описание и подписи кнопок |
Категории
Фиксированные:
necessary
(всегда включена — выбор, о котором спрашивать не нужно),
analytics
,
marketing
. Свои категории завести нельзя: баннер обещает посетителю ровно эти три, и тег
requiresConsent
на
Script
/
HtmlEmbed
— то, что превращает обещание в поведение. Счётчики из
settings.analytics
всегда идут под
analytics
.
Посетитель отвечает одним из трёх способов: принять все, отклонить или «Настроить» — панель с переключателем на каждую категорию и кнопкой сохранения.
Когда баннер есть и когда он показывается
Есть
— на странице, где что-то ждёт согласия:
Script
или
HtmlEmbed
с
requiresConsent
на самой странице либо объявленное на весь сайт в
project.json
(счётчик в
settings.analytics
, запись
settings.scripts
с
requiresConsent
). И, разумеется, там, где написан элемент
Consent
.
Показывается сам
— только когда в документе лежит то, что согласие разбудит. На платформенных адресах гейтнутых вещей не существует вовсе, и баннер не спрашивает согласие «ни для чего».
always:true
отменяет это правило.
Рантайм
-
Выбор хранится в
localStorageбраузера под ключомreeel.consent.v1и действует год — потом баннер спрашивает снова. -
Состояние доступно разметке:
$consent.analytics,$consent.marketing. -
Действия:
consent.open()(показать баннер снова — ссылка «настройки cookies» в футере),consent.acceptAll(),consent.rejectAll()и по одной категории —consent.allow("analytics")/consent.deny("marketing"). - Согласие активирует инертные теги разрешённых категорий без перезагрузки страницы . Отзыв данного согласия страницу перезагружает: выполненный скрипт выгрузить нельзя, поэтому выбор записывается, и страница стартует заново уже без этой категории. Первый отказ ничего не перезагружает.
-
Авторскому JavaScript выбор виден без чтения хранилища:
window.reeel.consent—{necessary, analytics, marketing}, а наdocumentприходит событиеreeel:consentна каждое решение, включая отказ (detail:{categories, analytics, marketing}). К этому подключается Google Consent Mode.
Примеры
Баннер для аналитики
Script src:"https://cdn.example.com/pixel.js" requiresConsent:"marketing"
Consent position:bottom policyUrl:"/privacy"
Счётчики Метрики и Google Analytics элементом
Script
не подключают: их объявляют в
`settings.analytics`
, и они ждут согласия на
analytics
сами.
Свой баннер
Дайте
Consent
содержимое — оно и станет баннером. Когда его показать и спрятать, по-прежнему решает платформа; вид и слова — обычная вёрстка. Кнопки зовут
consent.acceptAll()
,
consent.rejectAll()
или
consent.allow("analytics")
.
Consent
Container
#decoration color:$theme.colors.surface
Row spacing:12
Text $strings.cookiesMessage
OutlinedButton onPressed:(){consent.rejectAll()}
Text $strings.cookiesNecessary
ElevatedButton onPressed:(){consent.acceptAll()}
Text $strings.cookiesAccept
Содержимое встаёт по центру у нижнего края окна (у верхнего — с
position:"top"
), в 16 px от него. Параметры-тексты (
title
,
message
, подписи кнопок, ссылка на политику) при своём содержимом показать некому — они пропускаются с предупреждением. В приложении содержимое не рисуется.
Баннер на странице один, поэтому свой баннер кладут в блок, который есть на каждой странице сайта, — обычно в футер.
Кнопка «настройки cookies» в футере
Text $strings.cookieSettings
onPressed:(){consent.open()}
Без
#web href:
— элемент с навигацией становится настоящей ссылкой, и её обработчик клика на вебе отбрасывается; здесь нужен именно обработчик.
Правила
-
SHOULD
Элемент
Consentпишется, только когда нужны свои тексты, ссылка на политику или верхний край; он один на страницу и живёт в общем компоненте хрома. Ради самого баннера его писать не нужно. -
MUST NOT
Не клейте баннер руками как
Positioned-накладку: этот паттерн остаётся для кастомного хрома (полоса прогресса скролла, дровер), а стандартное согласие — один элемент, и только он связан с рантаймом$consent.*. -
MUST NOT
Не помечайте
requiresConsentто, что не готово ждать: инертный тег не выполнится до согласия, и на платформенном адресе — никогда. -
MUST NOT
Не зовите
consent.*на странице сайта, где гейтить нечего и элементаConsentнет: баннера там нет, и вызов ничего не сделает (компилятор об этом предупреждает).