commit
51a610eae3
@ -9,6 +9,7 @@ import { hasLocale, NextIntlClientProvider } from "next-intl";
|
||||
import { getMessages } from "next-intl/server";
|
||||
import clsx from "clsx";
|
||||
|
||||
import YandexMetrika from "@/components/analytics/YandexMetrika";
|
||||
import { loadUser, loadUserId } from "@/entities/user/loaders";
|
||||
import { routing } from "@/i18n/routing";
|
||||
import { AppUiStoreProvider } from "@/providers/app-ui-store-provider";
|
||||
@ -63,6 +64,7 @@ export default async function RootLayout({
|
||||
return (
|
||||
<html lang={locale}>
|
||||
<body className={clsx(inter.variable, styles.body)}>
|
||||
<YandexMetrika />
|
||||
<NextIntlClientProvider messages={messages}>
|
||||
<UserProvider user={user}>
|
||||
<SocketProvider userId={userId}>
|
||||
|
||||
83
src/components/analytics/YandexMetrika/YandexMetrika.tsx
Normal file
83
src/components/analytics/YandexMetrika/YandexMetrika.tsx
Normal file
@ -0,0 +1,83 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import Script from "next/script";
|
||||
|
||||
const YANDEX_METRIKA_ID = 103412914;
|
||||
|
||||
export default function YandexMetrika() {
|
||||
useEffect(() => {
|
||||
// Initialize Yandex.Metrika after script loads
|
||||
const initializeYandexMetrika = () => {
|
||||
if (typeof window.ym === "function") {
|
||||
try {
|
||||
window.ym(YANDEX_METRIKA_ID, "init", {
|
||||
webvisor: true,
|
||||
clickmap: true,
|
||||
accurateTrackBounce: true,
|
||||
trackLinks: true,
|
||||
});
|
||||
} catch {
|
||||
// Silently handle initialization errors
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Check if ym is already available or wait for it
|
||||
if (typeof window.ym === "function") {
|
||||
initializeYandexMetrika();
|
||||
} else {
|
||||
// Wait for script to load
|
||||
const checkYm = setInterval(() => {
|
||||
if (typeof window.ym === "function") {
|
||||
initializeYandexMetrika();
|
||||
clearInterval(checkYm);
|
||||
}
|
||||
}, 100);
|
||||
|
||||
// Cleanup interval after 10 seconds
|
||||
setTimeout(() => {
|
||||
clearInterval(checkYm);
|
||||
}, 10000);
|
||||
|
||||
return () => clearInterval(checkYm);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Yandex.Metrika counter */}
|
||||
<Script
|
||||
id="yandex-metrika-site-wide"
|
||||
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();
|
||||
for (var j = 0; j < document.scripts.length; j++) {
|
||||
if (document.scripts[j].src === r) { return; }
|
||||
}
|
||||
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');
|
||||
`,
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Noscript fallback */}
|
||||
<noscript>
|
||||
<div>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
src={`https://mc.yandex.ru/watch/${YANDEX_METRIKA_ID}`}
|
||||
style={{
|
||||
position: "absolute",
|
||||
left: "-9999px",
|
||||
}}
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
</noscript>
|
||||
</>
|
||||
);
|
||||
}
|
||||
1
src/components/analytics/YandexMetrika/index.ts
Normal file
1
src/components/analytics/YandexMetrika/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { default } from "./YandexMetrika";
|
||||
Loading…
Reference in New Issue
Block a user