diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 9f0be8d..c038553 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -5,6 +5,7 @@ import { Suspense } from "react";
import { AdDialogSlot } from "@/components/ad/ad-dialog-slot";
import { AddressDialogSlot } from "@/components/address/address-dialog-slot";
import { AgeGateDialogHost } from "@/components/age-gate/age-gate-dialog";
+import { SiteAnalytics } from "@/components/analytics/site-analytics";
import { RequestHeadersPrime } from "@/components/api/request-headers-prime";
import { AuthUnauthorizedBridge } from "@/components/auth/auth-unauthorized-bridge";
import { GuestAuthBootstrap } from "@/components/auth/guest-auth-bootstrap";
@@ -92,6 +93,9 @@ export default function RootLayout({ children }: LayoutProps<"/">) {
+
+
+
{children}
diff --git a/src/components/analytics/site-analytics.tsx b/src/components/analytics/site-analytics.tsx
new file mode 100644
index 0000000..68f0543
--- /dev/null
+++ b/src/components/analytics/site-analytics.tsx
@@ -0,0 +1,66 @@
+"use client";
+
+import { usePathname, useSearchParams } from "next/navigation";
+import Script from "next/script";
+import { useEffect, useRef } from "react";
+
+/** Google Analytics 4 */
+const GA_ID = "G-5XKDE5QPTF";
+/** Yandex.Metrika 计数器 */
+const YM_ID = 113808100;
+
+declare global {
+ interface Window {
+ ym?: (id: number, action: string, ...args: unknown[]) => void;
+ }
+}
+
+/**
+ * 站点统计:GA4 + Yandex.Metrika。
+ * GA4 增强型衡量会按浏览器历史变化自动记录浏览量;
+ * Metrika 在客户端路由切换时需手动发送 hit(首屏由 init 统计,不重复发)。
+ */
+export function SiteAnalytics() {
+ const pathname = usePathname();
+ const searchParams = useSearchParams();
+ const lastUrl = useRef(null);
+
+ useEffect(() => {
+ const query = searchParams.toString();
+ const url = `${pathname}${query ? `?${query}` : ""}`;
+ if (lastUrl.current === null) {
+ lastUrl.current = url;
+ return;
+ }
+ if (lastUrl.current === url) return;
+ const referer = new URL(lastUrl.current, location.origin).href;
+ lastUrl.current = url;
+ window.ym?.(YM_ID, "hit", location.href, { referer, title: document.title });
+ }, [pathname, searchParams]);
+
+ return (
+ <>
+
+
+
+
+ >
+ );
+}