prod-site/src/widgets/yandex-metrika/ui/YandexMetrika.tsx
2026-09-24 14:04:36 +05:00

87 lines
2.2 KiB
TypeScript

"use client";
import { useEffect, useRef, useState } from "react";
import { usePathname } from "next/navigation";
import Script from "next/script";
import {
COOKIE_CONSENT_EVENT,
COOKIE_CONSENT_KEY,
} from "@/widgets/cookie-consent";
declare global {
interface Window {
ym?: (
counterId: number,
action: "init" | "hit",
options?: Record<string, unknown> | string
) => void;
}
}
const counterId =
Number(process.env.NEXT_PUBLIC_YANDEX_METRIKA_ID) || 111930174;
const YandexMetrika = () => {
const pathname = usePathname();
const [accepted, setAccepted] = useState(false);
const previousUrl = useRef<string | null>(null);
useEffect(() => {
const timer = window.setTimeout(() => {
setAccepted(window.localStorage.getItem(COOKIE_CONSENT_KEY) === "accepted");
}, 0);
const onAccepted = () => setAccepted(true);
window.addEventListener(COOKIE_CONSENT_EVENT, onAccepted);
return () => {
window.clearTimeout(timer);
window.removeEventListener(COOKIE_CONSENT_EVENT, onAccepted);
};
}, []);
useEffect(() => {
if (!accepted || !counterId || !window.ym) return;
const url = window.location.href;
if (previousUrl.current === null) {
previousUrl.current = url;
return;
}
if (previousUrl.current === url) return;
previousUrl.current = url;
window.ym(counterId, "hit", url);
}, [accepted, pathname]);
if (!accepted || !counterId) return null;
return (
<Script
id="yandex-metrika"
strategy="afterInteractive"
dangerouslySetInnerHTML={{
__html: `
(function(m,e,t,r,i,k,a){
m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
m[i].l=1*new Date();
k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)
})(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
ym(${counterId}, "init", {
accurateTrackBounce: true,
clickmap: true,
defer: true,
ecommerce: "dataLayer",
trackLinks: true,
webvisor: true
});
`,
}}
/>
);
};
export default YandexMetrika;