Как получить API Secret для GA4 (Инструкция)
Чтобы настроить Measurement Protocol, вам понадобится секретный ключ (API Secret). Без него серверы Google отклонят любые входящие HTTP-запросы от вашего Web Worker.
- Откройте панель Google Analytics и выберите ваш ресурс GA4.
- В левом нижнем углу нажмите на шестеренку Администратор (Admin).
- В столбце параметров ресурса выберите пункт Потоки данных (Data Streams) и кликните на ваш текущий Веб-поток.
- В открывшемся окне настроек потока прокрутите вниз до блока Дополнительные настройки и выберите Секретные ключи Measurement Protocol (Measurement Protocol API secrets).
- Нажмите кнопку Создать (Create), задайте для ключа понятное имя (например,
web-worker-prod) и скопируйте сгенерированное буквенно-цифровое значение.
⚠️ Важно: Храните этот ключ в секрете. В кодовой базе воркера рекомендуется подставлять его через переменные окружения на этапе сборки проекта, чтобы не «светить» в публичном репозитории.
Миграция данных: Маппинг параметров из Universal Analytics в GA4
В старом Universal Analytics (UA) все кастомные события жестко загонялись в иерархию трех параметров: Категория (Event Category), Действие (Event Action) и Ярлык (Event Label). В Google Analytics 4 эта концепция полностью упразднена. Теперь модель данных стала событийно-ориентированной (Event-driven): существует просто имя события и плоский объект с любым количеством кастомных параметров.
Вот как выглядит маппинг старой структуры под новый формат GA4 при передаче через Web Worker:
| Параметр в UA (v1) | Обозначение в UA | Эквивалент в GA4 | Описание в новой концепции |
|---|---|---|---|
| Event Action | ea | Имя события (Event Name) | Становится главным идентификатором действия (например, generate_lead, click_podcast). |
| Event Category | ec | Кастомный параметр | Переносится внутрь параметров (например, traffic_type или event_category). |
| Event Label | el | Плоские ключи | Больше не нужно упаковывать данные в JSON-строку. Любые контекстные данные (ID статьи, поисковый запрос) передаются отдельными свойствами. |
Пример трансформации кода
Раньше в воркере приходилось склеивать параметры в строку или отправлять фиксированные ключи. Теперь мы раскладываем объект params напрямую в тело JSON, избавляясь от JSON.stringify:
// Было (Universal Analytics v1):
const eventParams = {
v: '1',
tid: currentGaId,
t: 'event',
ea: payload.action, // Event Action -> Имя действия
ec: 'Рантайм Блога', // Event Category -> Категория
el: JSON.stringify(payload.params) // Event Label -> Сжатый JSON-строкой контекст
};
// Стало (Google Analytics 4):
const ga4Payload = {
client_id: payload.clientId,
events: [{
name: payload.action, // Имя события теперь на верхнем уровне
params: {
...payload.params, // Плоский объект параметров (например, { search_term: "next.js" })
event_category: 'Рантайм Блога' // Бывшая категория передается обычным свойством
}
}]
};Такой подход позволяет строить гибкие воронки и отчеты в интерфейсе GA4, оперируя понятными бизнес-метриками, а не пытаясь вспомнить, что именно было зашито в «Ярлык события».
Локальная отладка и валидация событий
Поскольку в режиме no-cors браузер скрывает статус-коды и ответы от серверов Google Analytics 4, разработчик не видит, если в параметрах события допущена опечатка. Google просто молча проигнорирует хит.
Для решения этой проблемы у Google есть специальный валидационный эндпоинт — /debug/mp/collect. В отличие от «боевого», он полностью поддерживает CORS-запросы. Это позволяет нам переключать воркер в режим отладки на локальной машине и видеть детальный JSON-ответ с описанием всех ошибок прямо в консоли браузера.
1. Модификация Web Worker
Добавим в воркер флаг isDebug. Если он включен, воркер переключается на mode: 'cors', меняет эндпоинт и выводит ответ валидатора Google в консоль:
public/analytics/analytics-worker.js
function sendGA4Event(bodyObject, isDebug = false) {
if (!currentGaId) return;
// Если включен дебаг, используем валидационный путь, иначе боевой
const path = isDebug ? '/debug/mp/collect' : '/mp/collect';
const url = new URL(path, 'https://google-analytics.com');
url.searchParams.set('measurement_id', currentGaId);
url.searchParams.set('api_secret', API_SECRET);
const endpoint = url.toString();
// Настройки fetch меняются в зависимости от режима окружения
const fetchOptions = {
method: 'POST',
body: isDebug ? JSON.stringify(bodyObject) : new Blob([JSON.stringify(bodyObject)], { type: 'text/plain;charset=UTF-8' }),
mode: isDebug ? 'cors' : 'no-cors' // В дебаге CORS разрешен серверами Google
};
if (isDebug) {
// Выставляем заголовок JSON, так как в режиме cors браузер его не заблокирует
fetchOptions.headers = { 'Content-Type': 'application/json' };
}
fetch(endpoint, fetchOptions)
.then(res => {
if (isDebug && res.ok) {
return res.json();
}
})
.then(validationData => {
if (isDebug && validationData) {
const messages = validationData.validationMessages || [];
if (messages.length === 0) {
console.log('✅ [GA4 Валидатор]: Событие успешно прошло проверку!', bodyObject.events[0].name);
} else {
console.warn('❌ [GA4 Валидатор]: Ошибка в структуре события:', messages);
}
}
})
.catch(err => console.error('❌ Ошибка отправки из воркера:', err));
}2. Как передать флаг из Next.js
Чтобы воркер знал, в какой среде он запущен, передайте флаг isDebug во время инициализации (init) из основного потока вашего приложения:
pages/_app.tsx
// Внутри useEffect в файле _app.tsx
const isDevelopment = process.env.NODE_ENV === 'development';
// Инициализируем воркер токеном и флагом окружения
worker.postMessage({
type: 'init',
payload: {
gaId: GA_ID,
isDebug: isDevelopment // true при локальной разработке (npm run dev)
}
});Не забудьте обновить обработчик case 'init' внутри самого воркера, чтобы он сохранял этот флаг в глобальную переменную:
let isDebugMode = false;
// Внутри switch (type)
case 'init':
if (payload && payload.gaId) {
currentGaId = payload.gaId;
isDebugMode = !!payload.isDebug;
console.log(`📡 [Analytics Worker]: Инициализирован. Режим отладки: ${isDebugMode}`);
}
break;Теперь при отправке события функция будет вызываться с актуальным контекстом: sendGA4Event(payload, isDebugMode). Если вы случайно передадите неподдерживаемый параметр или забудете client_id, Google вернет развернутый массив ошибок прямо в Console вашего браузера.
