Add Яндекс.Метрика funnel goals: signup_free + gate_view (env-driven counter)

- window.ym reachGoal 'signup_free' on registration success
- GateViewTracker client component fires 'gate_view' on tripwire gate mount
- counter id via NEXT_PUBLIC_METRIKA_COUNTER_ID (build-time)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-23 12:13:32 +05:00
parent 7bf3935c81
commit 0e67a53122
4 changed files with 34 additions and 0 deletions
+5
View File
@@ -16,6 +16,11 @@ S3_REGION="eu-central"
NEXT_PUBLIC_TURNSTILE_SITE_KEY=""
TURNSTILE_SECRET_KEY=""
# Яндекс.Метрика — ID счётчика school.second-brain.ru (цели signup_free/gate_view).
# Build-time (NEXT_PUBLIC_*) — передавать через --build-arg при сборке. Сам счётчик
# (ym init snippet) ставится в admin → Settings → headCode, отдельно от этого ID.
NEXT_PUBLIC_METRIKA_COUNTER_ID=""
# Kinescope API
KINESCOPE_API_KEY=""
@@ -5,6 +5,7 @@ import Link from "next/link";
declare global {
interface Window {
ym?: (counterId: number, action: string, goal: string) => void;
turnstile?: {
render: (
container: HTMLElement,
@@ -161,6 +162,11 @@ export function RegisterForm({ showTermsCheckbox, privacyPolicyUrl, termsUrl, of
return;
}
// Яндекс.Метрика: цель «бесплатная регистрация»
const mc = Number(process.env.NEXT_PUBLIC_METRIKA_COUNTER_ID);
if (mc && typeof window !== "undefined" && typeof window.ym === "function") {
window.ym(mc, "reachGoal", "signup_free");
}
setSuccess(true);
setLoading(false);
}
@@ -0,0 +1,20 @@
"use client";
import { useEffect } from "react";
declare global {
interface Window {
ym?: (counterId: number, action: string, goal: string) => void;
}
}
// Фиксирует показ gate-лестницы в Яндекс.Метрике (цель gate_view).
export function GateViewTracker() {
useEffect(() => {
const c = Number(process.env.NEXT_PUBLIC_METRIKA_COUNTER_ID);
if (c && typeof window !== "undefined" && typeof window.ym === "function") {
window.ym(c, "reachGoal", "gate_view");
}
}, []);
return null;
}
@@ -2,6 +2,8 @@
// основной — трипвайр «Второй мозг для предпринимателя», вторичный — полный курс.
// Server component, ДС-2 (Aubade).
import { GateViewTracker } from "./gate-view-tracker";
const TRIPWIRE_URL = "https://second-brain.ru/entrepreneur";
const FULL_COURSE_URL = "https://obsidian.second-brain.ru/";
@@ -11,6 +13,7 @@ export function TripwireGateBanner() {
className="card-aubade p-6 mt-10"
style={{ background: "var(--accent)", boxShadow: "4px 4px 0 0 var(--foreground)" }}
>
<GateViewTracker />
<p
className="text-xs font-bold uppercase tracking-widest mb-2"
style={{ color: "var(--muted-foreground)" }}