在 React SPA 中使用 Google Analytics 4 跟踪页面浏览量
Source: Dev.to

将 Google Analytics(GA4)添加到普通的 HTML 网站非常简单:把跟踪代码粘贴到 <head> 中即可。每当用户点击链接时,浏览器会请求一个新的 HTML 页面,GA 就会记录一次页面浏览。
但如果你使用 React、Vite 和 React Router 构建单页应用(SPA),这种开箱即用的行为就会失效。
在 React SPA 中,点击链接不会触发页面重新加载。React 只会卸载旧组件并挂载新组件,同时操作浏览器的 URL 历史。由于页面实际上没有重新加载,Google Analytics 无法记录新的 URL,你的分析数据会显示用户似乎永远停留在首页。
下面是一套我在个人作品集站点中使用的逐步解决方案。
1. 环境设置
避免在源代码中硬编码跟踪 ID。将您的测量 ID(在 GA 仪表板中找到,通常以 G-XXXXXXXXXX 开头)添加到 .env 文件中:
VITE_GA_TRACKING_ID=G-**********
2. 初始 HTML 代码片段(已修改)
在 index.html 中加入基础的 Google Analytics 跟踪代码,但 禁用自动的 page_view 跟踪 以防止重复计数。
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){ dataLayer.push(arguments); }
gtag('js', new Date());
// IMPORTANT: Disable the default page_view tracking here!
gtag('config', '%VITE_GA_TRACKING_ID%', { send_page_view: false });
</script>
关于 Vite: %VITE_GA_TRACKING_ID% 在构建时注入环境变量。
3. 创建路由监听组件
创建一个轻量、不可见的组件,使用 react-router-dom 的 useLocation 监听 URL 变化。
src/components/Analytics.tsx
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
// Extend window object for TypeScript
declare global {
interface Window {
gtag: (...args: any[]) => void;
}
}
export const Analytics = () => {
const location = useLocation();
useEffect(() => {
const GA_MEASUREMENT_ID = import.meta.env.VITE_GA_TRACKING_ID;
if (GA_MEASUREMENT_ID && typeof window.gtag === 'function') {
window.gtag('config', GA_MEASUREMENT_ID, {
page_path: location.pathname + location.search,
});
}
}, [location]);
return null; // Invisible component
};
4. 将其连接到 Router
在 <BrowserRouter> 内部、<Routes> 块 外部 挂载 <Analytics />。
src/index.tsx
import { Analytics } from './components/Analytics';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import { HelmetProvider } from 'react-helmet-async';
import { Suspense } from 'react';
import ScrollToTop from './components/ScrollToTop';
import LoadingFallback from './components/LoadingFallback';
import HomePage from './pages/HomePage';
import AboutPage from './pages/AboutPage';
// ...other imports
const App = () => {
return (
<HelmetProvider>
<BrowserRouter>
{/* Place the listener here! */}
<Analytics />
<ScrollToTop />
<Suspense fallback={<LoadingFallback />}>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/about" element={<AboutPage />} />
{/* ... other routes */}
</Routes>
</Suspense>
</BrowserRouter>
</HelmetProvider>
);
};
export default App;
5. 结果
- 当用户访问
vicentereyes.org时,GA 脚本加载。 - React 启动,挂载路由器,
<Analytics />组件触发对/的页面浏览事件。 - 随后导航(例如点击 “Projects”)会更新 URL,触发
<Analytics />中的useEffect,并发送对/projects的干净页面浏览事件。
这提供了精确的 SPA 跟踪,而无需使用庞大的外部库。