Coolkid mascot CoolkidLab Build in Public. Level up together.

SEO 菜鳥成長史 · #3

閱讀

GA4 + GSC 終於裝完:CSP 把 Google Analytics 擋掉的踩雷全紀錄

先講重點

GA4(Google 流量分析)裝好卻收不到數據怎麼辦?最常見元兇是 CSP(內容安全政策)把 Google Analytics 網域擋掉。我這站因為半個月前自己埋的 CSP,28 個頁面的 GA 一起啞掉。解法:在 script-src / connect-src 補上 googletagmanager.com 與 google-analytics.com。

從 v0.3 上架到今天剛好第 5 天。終於把 GA4 + GSC 都裝上去。

原本以為是「複製貼上 5 分鐘」的小事。實際做完才發現中間有個讓我笑出來的鍋——是我自己半個月前埋的。

這篇紀錄整套裝 GA4 + GSC 的步驟、踩到的 CSP 陷阱、以及這個陷阱怎麼讓 28 個頁面的 GA 一起啞掉。

1. 為什麼這篇值得寫

GA4 安裝教學一抓一大把,但 95% 的文章只講三件事:

對於用 WordPress + 外掛的人,這樣確實 5 分鐘就好。但靜態站、自己 build、又有資安潔癖鎖了 CSP 的人——你會發現貼進去之後 console 一片紅,GA 完全沒反應,然後查半天還以為是自己貼錯位置。

這篇的核心不是「怎麼貼 GA」,是「為什麼貼了 GA 卻沒反應」、以及「GA + GSC 的整套裝法」。

2. 第一刀:GA4 帳戶開到拿 G ID(10 分鐘)

GA4 後台流程乾淨,跟著走基本不會出錯:

  1. 進 analytics.google.com → 建立帳戶 → 帳戶名稱填品牌名
  2. 建立資源 → 屬性名稱填品牌名(不要塞 URL 或「GA4」字樣,這是給自己之後辨識用的標籤)
  3. 時區選台灣、貨幣選新台幣
  4. 業務目標問你想看什麼,按需求勾
  5. 資料串流選「網站」→ 填 URL 跟串流名稱

走完會拿到一組 G-XXXXXXXXXX 開頭的 Measurement ID,這個 ID 一輩子不會變,複製存好。

後台會跳一個 modal 給你 gtag.js 的安裝程式碼。這段才是真正的戰場。

3. 為什麼 GA4 裝了卻收不到數據?(CSP 把 GA 擋掉的鍋)

我這站的 head 不是手動寫每一頁,是有 build.py 一次注入所有頁面。所以「貼程式碼」實際上是改 page_shell() 函式裡 head 的 template。

把 GA4 的 ID 拉成常數放檔頂,head template 在 </head> 之前加兩段:

GA4_ID = "G-XXXXXXXXXX"

# 在 page_shell() 的 </head> 之前
<script async src="https://www.googletagmanager.com/gtag/js?id={GA4_ID}"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '{GA4_ID}');
</script>

跑 python build.py,28 個 html 全部重生,每頁都帶 G ID。git push,Vercel 自動部署。回 GA4 後台等資料。

等了 5 分鐘——還是 0。打開網站,按 F12 開 console,畫面一片紅:

Refused to load the script
'https://www.googletagmanager.com/gtag/js?id=G-XXXX'
because it violates the following Content Security Policy directive:
"script-src 'self' 'unsafe-inline'"

兇手就很明顯了。是我半個月前在 vercel.json 鎖的 CSP(資安潔癖的鍋)。當時的 script-src 只允許「來自自家站」跟「inline」兩種來源,googletagmanager.com 不在白名單裡,瀏覽器直接拒載。

(1)什麼是 CSP

Content-Security-Policy 是 HTTP header,告訴瀏覽器「這個網站只准載入哪些來源的 script / style / 圖 / 字體 / 連線」。鎖緊了能擋掉 XSS 攻擊跟惡意第三方腳本,但鎖太死自己想用的服務也會被鎖在門外。

vercel.json 裡的 CSP 大概長這樣(節選):

"Content-Security-Policy":
  "default-src 'self';
   script-src 'self' 'unsafe-inline';
   ... (其他 directives)"

GA 要載 gtag.js(外部 script)、又要把資料 POST 回 google-analytics.com(外部 connect),這兩個權限都要顯式開放。

(2)正確的 CSP 修法

丟給 agent 一次改完 vercel.json,把兩個 directive 加上 GA 相關的網域:

script-src 'self' 'unsafe-inline'
  https://www.googletagmanager.com;

connect-src 'self'
  https://*.supabase.co
  https://www.google-analytics.com
  https://*.analytics.google.com
  https://*.googletagmanager.com;

重點:

重新 commit、push。Vercel 部署完,回網站重整、F12 console 一片乾淨。GA4 後台「過去 30 分鐘活躍使用者」終於亮 1——那 1 個就是我自己。

事後查證,這不是 edge case:Google Tag Platform 官方 CSP 指南就明列 GA4 要在 CSP 放行 www.googletagmanager.com(script-src/img-src)+ google-analytics.com(connect-src)。GA 的端點較分散,官方建議逐一列出這幾個指定網域(CSP 本身支援萬用字元,但這裡逐一列較精確)。我等於手動撞出官方早就寫好的設定。

4. GA4 怎麼串接 GSC + 提交 sitemap + 設定資料保留?

GA 跑起來只是第一塊。要看到「有人從 Google 搜尋什麼進站」要把 GSC 串進來。三件小事一次做:

(1)GA4 ↔ GSC 串接

GA4 後台 → 管理(左下齒輪)→ 產品連結 → Search Console 連結 → 選 GSC 資源 → 選網站串流 → 提交。

串完之後,GA 報表會多兩塊:「探索 → 範本庫 → Search Console 報表」可以看查詢字、CTR、平均排名;「獲客 → 流量獲取」會多一條 google / organic 細分到具體搜尋查詢。

為什麼一定要串:原本 GSC 只能看「誰找到我」,GA 只能看「進來之後幹嘛」,兩邊資料各看各的。串接後接在一起——找到我的查詢字,配上他進站後的停留 / 互動 / 轉換——這才是 SEO 真正能拿來判斷的數字。

(2)GSC 提交 sitemap

GSC 後台 → 索引 → Sitemap → 加新的 sitemap → 輸入「sitemap.xml」→ 提交。一次解掉「Google 知不知道我的站有哪些頁」這個問題。

提醒:sitemap 提交不等於「立刻被收錄」。GSC 會跟你說「成功讀取」就好,實際進索引還要等幾天到幾週。這個我之前 #1 那篇有寫過完整流程。

(3)資料保留改 14 個月

GA4 預設「事件層級資料」只保留 2 個月。對個人站等於每兩個月就洗掉一次歷史,看不到趨勢。

GA4 後台 → 管理 → 資源設定 → 資料保留 → 改 14 個月(免費上限)。這個沒成本沒副作用,所有人都該開到滿。

5. 最終戰績

項目做完前做完後
GA4 安裝未裝 ❌28 頁全帶 ✅
GSC 串接未串 ❌已串 ✅
Sitemap 提交未提交 ❌已提交 ✅
資料保留2 個月(預設)14 個月 ✅
CSP whitelist太緊 ❌正確開放 GA 端點 ✅

6. 我從這個過程學到什麼

三件事:

  1. 「複製貼上 5 分鐘」的教學文,前提是「跟教學文寫的環境一樣」。我有自己的 build 系統 + 自己鎖過的 CSP,原本的範本就會卡。
  2. 出問題第一步打開 F12 console。瀏覽器幾乎一定會把擋掉的請求印出來告訴你原因,不用猜。
  3. 同一次 commit 修兩個檔(build.py + vercel.json)才能上線。少改一個 push 上去 GA 就裝了等於沒裝,浪費一次部署。

這跟我做交易學到的東西一樣:訊號出現不代表能直接下單,要看跟你的部位 / 環境合不合。一個普世的 setup,遇到自己的特殊環境一樣會卡。

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

如果你的站也準備裝 GA4 + GSC,按這個順序走:

  1. GA4 後台建立資源、拿到 G-XXXXXXXXXX
  2. 把 gtag.js script 加到網站 (靜態站找你的 head template / build script,不要每個 html 手貼)
  3. 如果有設 CSP,script-src 加 https://www.googletagmanager.com、connect-src 加三個 GA 端點
  4. Push 上線,回 GA4 後台「過去 30 分鐘」看自己有沒有亮起來;沒亮就 F12 看 console 找原因
  5. GA4 ↔ GSC 串接、GSC 提交 sitemap、資料保留改 14 個月,三件事一次做完
  6. 確認 robots.txt 沒擋 Googlebot、sitemap.xml URL 都是 200

整套順利做完大概 30 分鐘。我這次因為踩了 CSP 鍋,多花了大概 20 分鐘。但下一次任何站都不會再被同一個鍋打到。

8. 下一步

GA + GSC 裝完只是「裝好監視器」。GA4 內建事件(含增強測量)收的是通用行為,看得到「有沒有人來、滑沒滑到底」,但看不到「他有沒有點到我自己定義的關鍵動作」。下一篇加自訂事件補這塊。

白老鼠實驗下一篇 #4 會做自訂事件 + 轉換追蹤:定義「滑到底」「點 CTA」「停留 60 秒以上」這些行為訊號,再標哪些算重要事件、哪些算轉換。等於把監視器升級成「能告訴你誰是真讀者、誰只是路過」的版本。

名詞解釋

GA4(Google Analytics 4)
Google 的流量分析工具:訪客從哪來、看了什麼、停多久。GSC 管「搜尋結果上的表現」,GA4 管「進站後的行為」。
GSC(Google Search Console)
Google 給網站主的免費後台:看自己網站在搜尋的曝光、點擊、排名跟索引狀態。做 SEO 的人天天開的儀表板。
內容安全政策(CSP, Content Security Policy)
網站的白名單防火牆:只允許指定來源的程式跟資源執行,用來擋惡意注入。設太嚴會誤殺自己要用的工具。
網站地圖(sitemap)
列出網站所有頁面跟最後更新日的清單檔(sitemap.xml),交給搜尋引擎加速發現與重抓你的頁面。
部署(deploy)
把做好的網站或程式「推上線」讓所有人用得到的動作。
Vercel
把網站免費發佈到網路上的服務:接上 GitHub 後,每次推程式碼就自動更新網站,個人專案免費方案就夠用。
索引(index)
搜尋引擎把你的頁面收進資料庫、開始能被搜到的狀態。「先被索引」是「有排名」的前提。
robots.txt
放在網站根目錄的「爬蟲守則」:告訴搜尋引擎跟 AI 爬蟲哪些頁面可以抓、哪些不要碰。

看完這篇之前先確認:

適合你
  • 剛裝 GA4 但 console 一片紅的人
  • 用 Vercel + 自己鎖 CSP 的靜態站
  • GA + GSC 想一次到位的人
不適合
  • 完全還沒裝 GA4 的人(先看 #0 gsc-basics)
  • 用 Plausible / Umami 等替代分析的人
  • WordPress + 外掛全自動的人
最常踩
  • 只開 google.com 忘了 googletagmanager.com
  • 改完 vercel.json 沒重新 deploy
  • 漏掉 fonts.googleapis.com / gstatic.com

這篇是收斂後寫的版本。
我每兩週寄一封電子報,講「正在做但還沒寫成文章」的東西——
包含每月幫你過濾值得花時間的新 AI 工具,
以及 Lab 新文的個人版(你會比公開版早一週收到)。

→ 訂閱(雙週一封,第一封自動寄起步清單)

跳轉 Substack、隨時取消、不轉賣 email。

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

Buy Me a Coffee at ko-fi.com
NEXT CHAPTER ▸ #0 GSC 是什麼?非工程師 5 分鐘看懂 Google Search Console

相關閱讀

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

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

← 回 SEO 菜鳥成長史

⚠ 本站所有內容僅供教育與研究用途,不構成投資建議,不保證任何獲利。投資有風險,使用者須自行判斷並承擔結果。