如何指南:在 React Router v7 Framework 模式下,設定 Google Analytics (gtag)
時隔一年後再度嘗試,發現可以在 React Router v7 的 Framework 模式順利以原生 script 標籤啟動 Google Analytics (gtag) 了 去年到底是發生了什麼呢。總之紀錄並分享一下做法。
順帶確認了可以在 clientAction
中派送 GA 事件——終於,我們可以優雅地滿足那些「我需要在購買成功、api 呼叫成功後派送 XX 成功的 GA 事件 🥺」需求了。
安裝方式
步驟:
- 以環境變數
VITE_GA_TRACKING_ID
傳遞 GA 的啟動碼 - 開啟
<你的專案>/app/root.tsx
並在function Layout
貼上 gtag.js 提供的範例(如下);我追加了一行官方文件沒有列出的參數debug_mode
(開啟後,可以在 GA 後台透過 Admin > DebugView 即時查看被派送的事件)
<>
<script
async
src={`https://www.googletagmanager.com/gtag/js?id=${import.meta.env.VITE_GA_TRACKING_ID}`}
/>
<script
async
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${import.meta.env.VITE_GA_TRACKING_ID}', {
debug_mode: ${import.meta.env.DEV ? "true" : "false"},
});
`,
}}
/>
</>;
新增 script 後的 function Layout
會長得像這樣:
export function Layout({ children }: { children: React.ReactNode }) {
return (
<html lang="zh-Hant">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<body className="bg-gray-1">
{children}
<ScrollRestoration />
<Scripts />
<script
async
src={`https://www.googletagmanager.com/gtag/js?id=${import.meta.env.VITE_GA_TRACKING_ID}`}
/>
<script
async
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${import.meta.env.VITE_GA_TRACKING_ID}', {
debug_mode: ${import.meta.env.DEV ? "true" : "false"},
});
`,
}}
/>
</body>
</html>
);
}
完成。就這樣。你可以在整個 React Router v7 app 中透過 gtag('event', '<event_name>', {<event_params>})
派送 GA 事件了。
在 clientAction 派送 GA 事件
在 clientAction
派送事件的話,可以避免重整畫面造成的重複派送,也能運用 action
回傳的資料。可參考以下範例。
import { type ActionFunctionArgs, type ClientActionFunctionArgs, Form, redirect } from 'react-router';
export async function loader() {
return null;
}
export async function action({ request }: ActionFunctionArgs) {
const form = await request.formData();
const test = form.get('test') as string;
// do something...
const result = await db.doSomething({ ...test });
return { test, result };
}
export async function clientAction({ serverAction }: ClientActionFunctionArgs) {
const data = await serverAction<typeof action>();
window.gtag('event', 'some_ga_event', { ...data });
return redirect('/test-b');
}
export default function TestA() {
return (
<Form method="post">
<input type="text" name="test" />
<button type="submit">Submit</button>
</Form>
);
}
這段程式碼在做的事情是:
- 當使用者送出表單後,在
action
階段進行一些處理 - 接下來,透過
clientAction
的serverAction
參數取得action
階段取得的資料——這些資料會成為 GA 事件的參數 - 透過
window.gtag('event', 'some_ga_event', { ...data })
派送事件 - 將使用者導向路由
/test-b