Coolkid mascot CoolkidLab Build in Public. Level up together.
首頁新手教學免費工具AI 新聞GitHub 精選陪跑服務關於

SEO 菜鳥成長史 · #5

GA4 自訂事件實作:7 個事件看誰是真讀者

閱讀
摘要

GA4(Google 流量分析)的增強測量夠用嗎,要不要加自訂事件?裝好就有增強測量,自動收 page_view、捲動 90%、外連點擊、檔案下載,但這些都是通用事件,追不到你自己定義的意圖,像是諮詢 CTA、訂閱、主題切換,捲動也只有 90% 沒有 50%。我加了 7 個自訂事件補這一塊,事件怎麼選比數量重要。

先講一件我一開始也搞錯的事。GA4 裝好不是只追 page_view。

它預設就有自動收集加增強測量,連捲動到 90%、外連點擊、檔案下載都會自動收集。

但這些都是通用事件。它答不出「他點到我的諮詢 CTA 沒、訂電子報沒、停超過 1 分鐘沒」這種我自己定義的行為。

這篇紀錄我在 site.js 加 7 個自訂事件的完整實作。

選哪些事件、怎麼寫 JS、為什麼要用 typeof gtag 守衛、怎麼在 GA4 後台標示為主要事件、怎麼用 Realtime 驗證有沒有真的送出。

這是 #4 預告過的續集。

終於把監視器升級成能告訴你誰是真讀者、誰只是路過的版本。

1. 為什麼這篇值得寫

GA4 自訂事件教學一抓一大把,但 90% 的文章只給你三件事:

問題是,該追哪 7 到 10 個事件?該怎麼選?捲動要不要限制頻率?外連怎麼判斷?萬一 GA 沒載入會不會炸?

這些真正要下手時的決策,幾乎沒人寫。

這篇給你的是個人站跟小型內容站的具體選法,不是給電商或 SaaS 用的完整分類體系。

2. 為什麼 GA4 內建事件不夠看?(增強測量收了什麼、漏了什麼)

你只裝 gtag、沒加自訂事件的時候,GA4 收的其實不只 page_view,分成兩層。

第一層是自動收集事件,page_view、session_start、first_visit、user_engagement(互動超過 10 秒)。

第二層是增強測量,建立網頁串流時通常預設開啟,收的是捲動到 90%、外連點擊、站內搜尋、檔案下載,還有影片與表單互動。

看起來增強測量好像都收了,但有兩個缺口。

第一個是顆粒度不夠。捲動只有 90% 一個門檻,分不出「點開就關」跟「看了一半」。

第二個是追不到你自己定義的意圖訊號。像下面這幾個問題,它答不到,或是答得不夠細:

這些行為訊號,才是判斷誰是真讀者的關鍵。要回答上面這 4 個問題,至少要自訂 7 個事件。

3. GA4 該追蹤哪 7 個自訂事件?(選擇邏輯)

GA4 的自訂事件上限是 50 個,看起來很多,但每加一個就多一份維護成本。對個人內容站來說,這 7 個夠用:

事件名觸發為什麼追
scroll_50滑到 50%區分「點開就關」vs「至少看一半」
scroll_90滑到 90%真讀者(讀到底)
dwell_60s停 60 秒真讀者 vs 路過(10 秒 user_engagement 太寬)
service_cta_click點諮詢 CTA1on1 漏斗最頂端的意圖訊號
outbound_click點站外連結看讀者跳到哪、引用哪些工具
subscribe_submit訂閱 form 成功送出Email 收集漏斗末端
theme_toggle切淺/深色視覺設計決策依據(多少人真的會切)

這 7 個分成三類,閱讀深度(scroll 跟 dwell)、意圖訊號(cta 跟 subscribe)、行為觀察(outbound 跟 theme)。每一類至少要有 2 個,才能交叉看。

誠實揭露一下。這 7 個裡面,scroll_90 跟 outbound_click 其實跟 GA4 增強測量本來就會收的 scroll 和 click 重疊。

我還是自己送,有兩個原因。我要 scroll_50 這個中間門檻,增強測量只有 90%,乾脆 50 跟 90 一起自己控。自己送外連也能拿到乾淨的 link_domain 維度,順便截斷過長的網址。

如果你不需要這兩點,直接用增強測量本來就有的版本就好,不用重做一次。

4. GA4 自訂事件怎麼用 site.js 實作?(最小可用 pattern)

我整站只有一個 assets/site.js,已經被 page_shell 引入所有頁面。所以加事件邏輯只要改一個檔,全站生效。

(1)為什麼一律先 typeof gtag === 'function'

GA 載入的過程可能被擋,廣告封鎖外掛、CSP 漏配、網路問題都有可能。

如果 gtag 沒定義,呼叫它會丟出 ReferenceError,整個 script 就掛了,後面的功能也跟著死。

// ❌ 直接呼叫
gtag('event', 'theme_toggle', { mode: cur });

// ✅ 先檢查
if (typeof gtag === 'function') {
  gtag('event', 'theme_toggle', { mode: cur });
}

前者在 GA 沒載入的時候會炸。後者 GA 沒載就安靜跳過,網站功能完全不受影響。

追蹤程式碼不該擋在網站的關鍵路徑上。

(2)scroll 要 throttle(不然會卡)

捲動事件一秒可以觸發幾百次。如果每次捲動都跑一輪「算百分比、比對里程碑、呼叫 gtag」,畫面會明顯卡。

所以要用 requestAnimationFrame 限制觸發頻率:

const fired = new Set();
let ticking = false;
function checkScroll() {
  ticking = false;
  const pct = (window.scrollY + window.innerHeight)
              / document.documentElement.scrollHeight * 100;
  for (const m of [50, 90]) {
    if (pct >= m && !fired.has(m)) {
      fired.add(m);
      gtag('event', 'scroll_' + m, { page_path: location.pathname });
    }
  }
}
window.addEventListener('scroll', () => {
  if (!ticking) { requestAnimationFrame(checkScroll); ticking = true; }
}, { passive: true });

兩個重點。fired 這個 Set 確保每頁只送一次,同一個里程碑不會重送。passive: true 讓瀏覽器不等你的 listener 就先捲動,畫面更順。

還有一個邊界要處理。頁面比視窗還短的時候,捲動百分比永遠到不了 50 或 90。

所以要在初始化的時候補一次「短頁直接記 90」,否則短文章的閱讀深度資料會全部是空的。

(3)click delegation:一個 listener 處理所有連結

要追 service CTA 跟外連兩種點擊,不要對每個 a 標籤都掛 listener。頁面有幾十個連結的時候,記憶體會吃緊。

document.addEventListener('click', (e) => {
  const a = e.target.closest('a');
  if (!a) return;
  const href = a.getAttribute('href') || '';
  // Service CTA
  if (href.includes('contact.html')
      && href.includes('topic=consultation')) {
    gtag('event', 'service_cta_click', {
      page_path: location.pathname,
      link_text: (a.textContent || '').trim().slice(0, 60),
    });
  }
  // Outbound
  try {
    const url = new URL(a.href, location.href);
    if (url.host && url.host !== location.host) {
      gtag('event', 'outbound_click', {
        link_domain: url.host,
        link_url: url.href.slice(0, 200),
      });
    }
  } catch (_) {}
});

重點:

(4)dwell 一行解決

setTimeout(() => gtag('event', 'dwell_60s', {
  page_path: location.pathname
}), 60_000);

60 秒後送一次。讀者中途離開頁面也沒關係,GA4 預設會把排隊中的事件在頁面卸載時送出,不會掉。

這一條是七個裡面最簡單的。

5. 第四步:GA4 後台「標示為主要事件」

程式碼上線後 GA4 會自動收事件,但那只是「事件」。要轉成「主要事件」,也就是轉換,才會進報表的轉換欄。

路徑是 GA4 管理 → 資料顯示欄 → 事件 → 找到事件名 → 切換右側的「標示為主要事件」。

我這 7 個事件的標示策略:

策略比清單本身重要。

事件標示為主要事件?
service_cta_click✅ 主要事件(=潛在客戶)
subscribe_submit✅ 主要事件(=Email 取得)
scroll_90✅ 主要事件(=完讀,作為內容品質訊號)
scroll_50 / dwell_60s❌ 當「參與訊號」,不算轉換
outbound_click / theme_toggle❌ 當「行為觀察」,純資料

重點是不要把所有事件都標成主要事件。標太多會讓 GA4 的轉換報表失焦,看不出哪一個才值得追。

標 3 個就夠了。

6. 第五步:驗證(GA4 Realtime)

GA4 自訂事件最麻煩的地方,是你看不到事件有沒有真的送出,要等 24 小時後標準報表才有資料。

但 Realtime 面板會即時顯示,可以當場驗證。

  1. 推 site.js 上線(Vercel 部署完約 1-2 分鐘)
  2. 新分頁打開 coolkidlab.com
  3. GA4 後台 → 報表 → 即時 → 「過去 30 分鐘事件」widget
  4. 回到網站做事件:點 theme toggle → 滑到底 → 等 60 秒 → 點服務 CTA → 切換 GA4 即時面板看
  5. 事件應該在 5-15 秒內陸續出現:theme_toggle、scroll_50、scroll_90、dwell_60s、service_cta_click

如果某個事件沒出現,開 F12 console,輸入 typeof gtag。

如果回傳 function 但事件沒送,那是 listener 沒掛上。如果回傳 undefined,那是 GA 根本沒載入,廣告封鎖、CSP 擋掉、網路失敗,三選一。

7. 戰績 + 我學到什麼

指標做之前做之後
自訂事件數07 ✅
主要事件(轉換)03 ✅
能回答「誰是真讀者」
site.js 增加行數約 +60 行
cache buster bump舊 hash自動(asset_hash 偵測內容變化)

我從這個過程學到三件事:

有一件事我事後才想通。

  1. 「該追哪些事件」是內容策略題,不是技術題。技術只是把策略翻譯成 code。先想清楚「我要回答什麼問題」再寫 listener。
  2. Event tracking 不該影響網站可用性。每個 gtag 呼叫前都要 typeof 檢查——GA 沒載入時網站要還能正常運作。
  3. 事件少而精勝過事件多而亂。7 個事件 + 3 個主要事件,比 30 個事件全部標主要事件好用幾倍。

8. 給跟我一樣從 0 開始的人:5 步驟 checklist

  1. 列出 5-10 個「想回答的問題」(誰是真讀者?哪些頁有人點 CTA?訂閱漏斗哪一段掉?)
  2. 每個問題對應 1-2 個事件(scroll / dwell / click / submit),不要追動詞太重複的
  3. 在 site.js(或你的全站 JS)加 listener,每個 gtag 呼叫一律 typeof 檢查
  4. Push 上線後,回 GA4 Realtime 面板手動驗證每個事件都送出
  5. 在 GA4 後台只把「跟轉換有關」的 2-3 個事件標主要事件,其他純資料留著
Coolkid AI Lab GA4 過去 7 天統計:31 位活躍使用者、363 次事件、台灣 17 / 美國 7 / 香港 2
事件裝完 7 天的實際數據:31 個活躍使用者 / 363 次事件 / 31 個新使用者。沒這 7 個自訂事件,363 這個數字就只會是 31 個 page_view,全部白看。事件少而精,數據才有訊號。

9. 下一步

GA4 自訂事件裝完,監視器就升級成看得出誰是真讀者的版本。

但事件收進來只是能看,不是能用。真正要用得起來還有兩步:

  1. 等 7-14 天累積資料量(個人站每天才 10-50 個訪客,太短沒統計意義)
  2. 在 GA4「探索」報表設兩個自訂分析:(a) 每篇文章的 scroll_90 完讀率排名 (b) service_cta_click 的來源頁面分布

白老鼠實驗下一篇 #6 會回到 GSC,看一週後的索引曲線。

強送配額分散送之後,曲線會不會變平緩、未索引的頁有沒有自然進索引、第一個搜尋查詢出現了沒。

名詞解釋

GA4(Google Analytics 4)
Google 的流量分析工具:訪客從哪來、看了什麼、停多久。GSC 管「搜尋結果上的表現」,GA4 管「進站後的行為」。
SEO(搜尋引擎優化)
讓網站在 Google 搜尋結果排得更前面的一整套方法,涵蓋技術體質、內容品質、連結結構三層。
GSC(Google Search Console)
Google 給網站主的免費後台:看自己網站在搜尋的曝光、點擊、排名跟索引狀態。做 SEO 的人天天開的儀表板。
Threads
Meta 旗下的文字社群平台。本站的社群引流主戰場之一,相關自動發文流程有整篇教學。
曝光(impression)
你的頁面出現在搜尋結果裡被看到的次數,不管有沒有被點擊。
自然流量(organic traffic)
從搜尋結果免費點進來的流量,相對於買廣告來的流量。
點閱率(CTR, Click-Through Rate)
看到你的搜尋結果的人裡,實際點進來的比例。曝光 100 次、被點 5 次,CTR 就是 5%。
跳出率(bounce rate)
進站後只看一頁、沒有任何互動就離開的訪客比例。GA4 的算法跟舊版 GA 不同,比較時要對齊定義。
GEO(生成式引擎優化)
讓 ChatGPT、Perplexity 這類 AI 在回答問題時引用你網站內容的優化方法,是 SEO 在 AI 時代的延伸戰場。
行動呼籲(CTA, Call to Action)
頁面上引導你做下一步的元素,像「訂閱」「立即開始」那顆按鈕。
引薦流量(referral)
從其他網站的連結點進來的流量。ChatGPT 引用你的內容帶來的點擊就屬於這一類。
搜尋結果頁(SERP)
在 Google 搜一個詞之後出現的那一整頁結果,包含一般結果、精選摘要、AI 摘要等版位。

全站名詞表 · 161 條 →

看完這篇之前先確認:

適合你
  • GA4 已部署但只看到 page_view
  • 想追 CTA click / scroll 深度
  • 想用 GA4 取代付費分析工具
不適合
  • 連 GA4 都還沒裝的人
  • 想用 GTM UI 點點點不寫 code 的人
  • 結構複雜的電商(建議直接上 GTM)

不想錯過 Lab 的新文章?
訂閱後有新文章上線,就寄信通知你,
點有興趣的進來看就好。

填 email 就完成訂閱(信由 Substack 代寄)、隨時取消、不轉賣 email。

如果內容對你有用就太好了
隨喜斗內

Buy Me a Coffee at ko-fi.com
NEXT CHAPTER ▸ #3 GA4 + GSC 終於裝完:CSP 把 GA 擋掉的踩雷

相關閱讀

這篇背後的真實開發過程記錄在 Build Log。 搜尋標籤:ga4eventsconversionsite-js

本篇為個人學習與實驗紀錄。GA4 介面與事件 API 持續變動,本文 code 範例不保證在你的網站環境完全相同,請依自身狀況實驗驗證。本站不接 YMYL 高風險站、不做 PBN、不做品牌矩陣 SEO。

← 回 SEO 菜鳥成長史

⚠ 本站所有內容僅供教育與研究用途,不構成投資建議,不保證任何獲利。投資有風險,使用者須自行判斷並承擔結果。
TAO 道 · Hikari Zen YouTube ↗
音樂透過 YouTube 播放
♪ TAO 道 · Hikari Zen — Japanese Zen Music(YouTube)