Небольшая поверхность, инфраструктурная основа.
WebmasterID — монорепозиторий на pnpm и Turborepo со строгим TypeScript повсюду. Каждая часть намеренно небольшая и заменяемая; никакой магии. Эта страница проходит систему от начала до конца.
Шесть компонентов.
Счётчик в браузере
Небольшой IIFE-скрипт (около 3 КБ в минифицированном виде), который загружается с /tracker.iife.min.js. Отправляет page_view при первой отрисовке, перехватывает history.pushState, replaceState и popstate для навигации в SPA и предоставляет типизированный API в window.WebmasterID.
API приёма данных
Fastify поверх функций Vercel. Проверяет события через Zod, классифицирует источник трафика, определяет ИИ- и поисковых ботов, анонимизирует IP и сохраняет в Postgres. Принимает и application/json, и text/plain.
PostgreSQL через Supabase
Схема Drizzle с отдельными таблицами events и bot_visits. Секретные ключи wmsk_ хранятся только в виде хешей SHA-256. Значение в открытом виде показывается один раз, при создании сайта, и больше никогда.
Определение ИИ- и поисковых ботов
Распознанные краулеры (GPTBot, ClaudeBot, PerplexityBot, Google-Extended, Applebot, Bingbot, Meta-ExternalAgent, CCBot и другие) попадают в bot_visits, но никогда в events. Агрегаты по людям остаются чистыми.
Панель оператора
Панель на Next.js с серверным рендерингом. Фильтр сайта и периода передаётся в параметрах URL.
API серверных событий
POST /api/server/events принимает события от сервера к серверу с Bearer-токеном wmsk_, который проверяется по его хешу SHA-256. Это позволяет записывать события, которые браузер никогда бы не увидел.
Незаметный сетевой путь.
Почему text/plain
navigator.sendBeacon с текстовым телом выставляет Content-Type в text/plain;charset=UTF-8 — MIME-тип из безопасного списка CORS. Без preflight, без поверхности CORS с учётными данными и без согласования со слоями CORS платформы.
Почему счётчик отдаётся с того же origin
Счётчик отдаётся с origin маркетингового сайта. Кто предпочитает, может разместить его у себя; фрагмент установки — один тег <script> с двумя атрибутами data-*.
Почему IP анонимизируется
Последний октет IPv4 обнуляется, IPv6 усекается до /48. Этого достаточно, чтобы заметить волны ботов и примерную географию, и недостаточно, чтобы опознать конкретного человека.
Почему нет cookies
В WebmasterID нет понятия вернувшегося посетителя между сайтами. Нет ничего, что продукт делал бы с помощью cookie и не мог бы без неё, — поэтому cookie нет.
Один тег script.
Установить WebmasterID — значит добавить тег <script> с двумя атрибутами данных: data-wmid (это site_id) и data-endpoint (URL приёма данных). Сайты, которые его устанавливают, по-прежнему отвечают за собственный процесс получения согласий; WebmasterID не оборачивает счётчик в SDK согласий по умолчанию.
Файл счётчика отдаётся с заголовком Cache-Control на пять минут и представляет собой тот же артефакт, что собирается из пакета packages/tracker-js этого монорепозитория.