diff --git a/package.json b/package.json index 8ab1a33..5d021dc 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "vite-react-typescript-starter", "private": true, - "version": "1.1.0", + "version": "1.1.1", "type": "module", "scripts": { "dev": "vite", diff --git a/src/App.tsx b/src/App.tsx index 0ed1e27..229c621 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -13,6 +13,7 @@ import { BookmarksPage } from './pages/BookmarksPage'; import { Footer } from './components/Footer'; import { AuthGuard } from './components/AuthGuard'; import { ImportArticlesPage } from "./pages/ImportArticlesPage"; +import YandexMetrika from "./components/YandexMetrika"; const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:5000'; @@ -46,6 +47,7 @@ function App() {
+ } /> } /> diff --git a/src/components/YandexMetrika.tsx b/src/components/YandexMetrika.tsx new file mode 100644 index 0000000..b60d001 --- /dev/null +++ b/src/components/YandexMetrika.tsx @@ -0,0 +1,79 @@ +// src/components/YandexMetrika.tsx +import { useEffect } from 'react'; +import { useLocation } from 'react-router-dom'; + + +// ⚙️ Мой ID счётчика Метрики +const YANDEX_METRIKA_ID = 104768935; // мой ID + +declare global { + interface Window { + ym?: ((id: number, method: string, ...params: unknown[]) => void) & { + a?: unknown[]; + }; + } +} + +export default function YandexMetrika() { + const location = useLocation(); + + useEffect(() => { + // 🧩 Не инициализируем Метрику в dev-режиме + if (import.meta.env.MODE !== 'production') { + return; + } + + // 🧩 Подключаем скрипт Метрики, если его ещё нет + if (!document.getElementById('ym-script')) { + const script = document.createElement('script'); + script.id = 'ym-script'; + script.src = 'https://mc.yandex.ru/metrika/tag.js'; + script.async = true; + document.head.appendChild(script); + } + + // 🧩 Инициализация + window.ym = + window.ym || + function (...args: unknown[]) { + (window.ym!.a = window.ym!.a || []).push(args); + }; + + window.ym(YANDEX_METRIKA_ID, 'init', { + clickmap: true, + trackLinks: true, + accurateTrackBounce: true, + webvisor: true, + }); + + // 🧩 Обработчик переходов + const handleRouteChange = () => { + const path = location.pathname; + + // 🚫 Игнорируем внутренние маршруты CRM / админки + const ignoredPaths = ['/login', '/admin']; + + if (ignoredPaths.some(prefix => path.startsWith(prefix))) { + return; // не отправляем hit + } + + // ✅ Отправляем hit для публичных страниц + window.ym?.(YANDEX_METRIKA_ID, 'hit', path + location.search); + }; + + handleRouteChange(); + }, [location]); + + // 🧩 Поддержка noscript (Яндекс требует для полной валидации) + return ( + + ); +}