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:
@@ -16,6 +16,11 @@ S3_REGION="eu-central"
|
|||||||
NEXT_PUBLIC_TURNSTILE_SITE_KEY=""
|
NEXT_PUBLIC_TURNSTILE_SITE_KEY=""
|
||||||
TURNSTILE_SECRET_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
|
||||||
KINESCOPE_API_KEY=""
|
KINESCOPE_API_KEY=""
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import Link from "next/link";
|
|||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
|
ym?: (counterId: number, action: string, goal: string) => void;
|
||||||
turnstile?: {
|
turnstile?: {
|
||||||
render: (
|
render: (
|
||||||
container: HTMLElement,
|
container: HTMLElement,
|
||||||
@@ -161,6 +162,11 @@ export function RegisterForm({ showTermsCheckbox, privacyPolicyUrl, termsUrl, of
|
|||||||
return;
|
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);
|
setSuccess(true);
|
||||||
setLoading(false);
|
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).
|
// Server component, ДС-2 (Aubade).
|
||||||
|
|
||||||
|
import { GateViewTracker } from "./gate-view-tracker";
|
||||||
|
|
||||||
const TRIPWIRE_URL = "https://second-brain.ru/entrepreneur";
|
const TRIPWIRE_URL = "https://second-brain.ru/entrepreneur";
|
||||||
const FULL_COURSE_URL = "https://obsidian.second-brain.ru/";
|
const FULL_COURSE_URL = "https://obsidian.second-brain.ru/";
|
||||||
|
|
||||||
@@ -11,6 +13,7 @@ export function TripwireGateBanner() {
|
|||||||
className="card-aubade p-6 mt-10"
|
className="card-aubade p-6 mt-10"
|
||||||
style={{ background: "var(--accent)", boxShadow: "4px 4px 0 0 var(--foreground)" }}
|
style={{ background: "var(--accent)", boxShadow: "4px 4px 0 0 var(--foreground)" }}
|
||||||
>
|
>
|
||||||
|
<GateViewTracker />
|
||||||
<p
|
<p
|
||||||
className="text-xs font-bold uppercase tracking-widest mb-2"
|
className="text-xs font-bold uppercase tracking-widest mb-2"
|
||||||
style={{ color: "var(--muted-foreground)" }}
|
style={{ color: "var(--muted-foreground)" }}
|
||||||
|
|||||||
Reference in New Issue
Block a user