Files
anotherreflections-website-v2/src/components/CookieConsent.astro
striker 6f2cfdd63d feat: счётчики с consent, политика, фиксы дизайна
Дизайн-фиксы:
- Перенесены картинки из старого WP в public/wp-content/uploads/
  (header_bg.gif + 3 размера NY-baner.png 2014/12). migrate-wp.mjs
  обновлён: корректно обрабатывает <a><img></a>, переписывает абсолютные
  URL anotherreflections.ru/wp-content/... в относительные
- Description в frontmatter теперь чистый plain text — без markdown-разметки
- Слаги 11/95/152 → kto-my, s-23-fevralya-2011, s-nastupayushhim-novym-2012-godom
- Hero-метрика: «N лет онлайн» → «с 2006 года» (последний пост 2015,
  активной жизни «20 лет» нет)
- Drop cap (буквица) — только для постов длиннее 240 символов
  (короткие посты раньше выглядели обрезанными)

Аналитика и конфиденциальность:
- Яндекс.Метрика (counter 13938862, webvisor) и Google gtag (GT-PH39R3X)
  перенесены со старого WP
- Cookie consent banner — самописный, без зависимостей: счётчики грузятся
  только после явного «Принять». Выбор хранится в localStorage + cookie
  ar-consent на 12 месяцев. Уведомление в духе 152-ФЗ
- /privacy/ — полная политика конфиденциальности: что собираем (через
  Метрику и GA), для чего, как cookies устроены, права пользователя,
  контакт для запросов на удаление
- В футере добавлены ссылки «Политика конфиденциальности» и «Контакты»
- sitemap.txt + llms.txt включают /privacy/
2026-05-21 02:07:08 +03:00

74 lines
2.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
// Минимальный self-hosted cookie consent под 152-ФЗ:
// — баннер показывается до явного выбора (cookie `ar-consent`)
// — «Принять» → активирует все <script type="text/plain" data-cookieconsent="statistics">
// — «Только необходимые» → ничего не активирует, баннер исчезает
// — выбор хранится в localStorage и cookie на 12 месяцев
---
<div id="cookie-consent" class="cookie-consent" hidden>
<div class="cookie-text">
<p>
Мы используем cookies и сервисы статистики (Яндекс.Метрика, Google Analytics),
чтобы понимать, как вы пользуетесь сайтом, и делать его лучше.
Подробнее — в <a href="/privacy/">политике конфиденциальности</a>.
</p>
</div>
<div class="cookie-actions">
<button type="button" class="cookie-btn cookie-btn-secondary" data-cc-deny>Только необходимые</button>
<button type="button" class="cookie-btn cookie-btn-primary" data-cc-accept>Принять</button>
</div>
</div>
<script is:inline>
(function () {
const KEY = 'ar-consent';
const banner = document.getElementById('cookie-consent');
if (!banner) return;
const activate = () => {
document.querySelectorAll('script[type="text/plain"][data-cookieconsent="statistics"]').forEach((tpl) => {
const s = document.createElement('script');
for (const a of tpl.attributes) {
if (a.name === 'type' || a.name === 'data-cookieconsent') continue;
s.setAttribute(a.name, a.value);
}
s.text = tpl.textContent || '';
tpl.parentNode.insertBefore(s, tpl);
tpl.parentNode.removeChild(tpl);
});
};
const setConsent = (value) => {
try { localStorage.setItem(KEY, value); } catch {}
const exp = new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toUTCString();
document.cookie = `${KEY}=${value}; expires=${exp}; path=/; SameSite=Lax`;
};
const current = (() => {
try {
const ls = localStorage.getItem(KEY);
if (ls) return ls;
} catch {}
const m = document.cookie.match(/(?:^|; )ar-consent=([^;]+)/);
return m ? decodeURIComponent(m[1]) : null;
})();
if (current === 'accept') {
activate();
} else if (current === 'deny') {
// ничего не делаем — статистика не активируется
} else {
banner.hidden = false;
}
banner.querySelector('[data-cc-accept]')?.addEventListener('click', () => {
setConsent('accept');
banner.hidden = true;
activate();
});
banner.querySelector('[data-cc-deny]')?.addEventListener('click', () => {
setConsent('deny');
banner.hidden = true;
});
})();
</script>