本篇重點 如何修改 Icarus 主題、新增自訂插件 Icarus 主題串接 Google Analytics 顯示網站 PV 和 UV 使用 forgetfulengineer/google-analytics-data-api-netlify
API 顯示網站數據 使用 countUp.js 建立數字的動畫效果 Icarus 主題原生僅支援不蒜子 提供的 PV 計數功能,無法串接 Google Analytics 的瀏覽數據。為了顯示來自 GA 的數據,我建立了 forgetfulengineer/google-analytics-data-api-netlify
作為 API 接口,並修改 Icarus 主題,使其能透過該 API 顯示網站數據。本文紀錄如何修改 Icarus 主題、新增自訂插件,並串接 API 顯示網站的 PV 與 UV。
1. 架設網站 PV/UV 查詢 API fork forgetfulengineer/google-analytics-data-api-netlify
並部署到 Netlify,建立一個可查詢網站 PV/UV 的 API,詳細部屬流程請查看【API】使用 Google Analytics Data API 架設網站 PV/UV 查詢 API 。
2. 添加自定義插件 Icarus 主題大部分的通用布局文件已被移至 repository hexo-component-inferno
,因此可以在不影響主題更新的情況下添加自定義插件,布局文件的詳細說明可查看官方文件 。
建立 ga_count 的 schema 新增 icarus 設定檔參數的概要
檔案路徑 1 2 3 4 5 6 7 8 themes/ ├── icarus/ │ └── include/ │ └── schema/ │ └── plugin/ │ └── ga_count.json ← 新增參數概要 │ └── common/ │ └── plugins.json ← 增加引用路徑
新增參數概要
/include/schema/plugin/ga_count.json 查看 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 { "$schema" : "http://json-schema.org/draft-07/schema#" , "$id" : "/plugin/ga_count.json" , "description" : "Ga count plugin" , "type" : "object" , "properties" : { "ga_count_api" : { "type" : "string" , "description" : "Google Analytics Data API" , "nullable" : true , "examples" : [ "https://ga-api-demo.netlify.app/.netlify/functions/pageview" ] } } , "required" : [ "ga_count_api" ] }
增加引用路徑
/include/schema/common/plugins.json 查看 1 2 3 4 5 { ... "ga_count" : "plugin/ga_count.json" ... }
主題設定啟用 ga_count 填入 API 路徑 https://{your-site}.netlify.app/.netlify/functions/pageview
_config.icarus.yml 1 2 3 plugins: ga_count: ga_count_api: https://ga-api-demo.netlify.app/.netlify/functions/pageview
建立 ga_count 元件 新增 /layout/plugin/ga_count.jsx
作為 Hexo 客製化插件,用於前端呼叫 GA API,並顯示瀏覽數。
jsx 查看 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 const { Component , Fragment } = require ('inferno' );const { cacheComponent } = require ('hexo-component-inferno/lib/util/cache' );class GACount extends Component { render ( ) { const { head, apiUrl, countUpJs } = this .props ; if (head) return null ; let gaCountJs = `(function() { var url = "${apiUrl} "; fetch(url, { method: 'get' }) .then(response => response.json()) .then(json => { var sitePvElement = document.getElementById('ga_value_site_pv'); var siteUvElement = document.getElementById('ga_value_site_uv'); var pvElement = document.getElementById('ga_value_page_pv'); if (sitePvElement) { const sitePv = new countUp.CountUp('ga_value_site_pv', json.pv, { enableScrollSpy: true, scrollSpyOnce: true }); } if (siteUvElement) { const siteUv = new countUp.CountUp('ga_value_site_uv', json.uv, { enableScrollSpy: true, scrollSpyOnce: true }); } if (pvElement) { const pagePv = new countUp.CountUp('ga_value_page_pv', json.pageViews, { enableScrollSpy: true, scrollSpyOnce: true }); } }); })();` ; return <Fragment > <script src ={countUpJs} > </script > <script dangerouslySetInnerHTML ={{ __html: gaCountJs }}> </script > </Fragment > ; } } GACount .Cacheable = cacheComponent (GACount , 'plugin.ga_count' , props => { const { helper, head, page, plugin } = props; const { url_for, cdn } = helper; const apiBase = plugin.ga_count_api ; const path = url_for (page.path ); const apiUrl = (page.layout == 'post' ) ? `${apiBase} ?path=${encodeURIComponent (path)} ` : apiBase; const countUpJs = cdn ('countup.js' , '2.9.0' , 'dist/countUp.umd.js' ); return { head, apiUrl, countUpJs }; }); module .exports = GACount ;
元件快取機制 cacheComponent
: Icarus 主題特有的效能優化方式,避免不必要的重複渲染,每個組件會依據頁面內容快取。
API 路徑動態處理: 根據是否為文章頁,決定是否要加上 ?path=
查詢字串,讓後端能計算單篇 PV。
jsx 查看 1 const apiUrl = (page.layout == 'post' ) ? `${apiBase} ?path=${encodeURIComponent (path)} ` : apiBase;
使用 countUp.js
呈現數字動畫: 利用 cdn()
方法載入 CountUp 套件 ,再透過 enableScrollSpy
與 scrollSpyOnce
讓動畫僅在畫面滾動到數字時觸發一次。
jsx 查看 1 new countUp.CountUp ('ga_value_page_pv' , json.pageViews , { enableScrollSpy : true , scrollSpyOnce : true })
plugin 載入處理: Icarus 主題中,layout/common/head.jsx
和 layout/common/scripts.jsx
都會載入 plugin,但 ga_count.jsx
只需載入一次,且必須等頁面元素渲染完成後再執行,避免抓不到 PV 元素,因此加入判斷,當處於 <head>
區塊時跳過渲染:
jsx 查看 資料顯示區塊: 透過 getElementById
取得 3 個容器(site PV、site UV、單篇 PV),再用 CountUp 顯示動畫數字。
3. 修改模板:顯示 PV / UV 數字 修改 article.jsx
(文章 PV) 在文章內容(layout/common/article.jsx
)中新增顯示該篇文章瀏覽數(PV)的區塊。
jsx 查看 1 2 3 4 5 6 7 8 {} {!index && plugins && plugins.ga_count .ga_count_api ? ( <span class ="level-item" id ="ga_container_page_pv" > <i class ="far fa-eye" > </i > <span id ="ga_value_page_pv" > -</span > </span > ) : null ; }
在頁尾(layout/common/footer.jsx
)中新增顯示全站瀏覽及訪客數(PV/UV)的區塊。
取得 ga_count
設定並修改瀏覽數據顯示內容
jsx 查看 1 2 3 4 - showVisitorCounter: plugins && plugins.busuanzi === true, - visitorCounterTitle: _p('plugin.visitor_count', '<span id="busuanzi_value_site_uv">0</span>') + showVisitorCounter: plugins && plugins.ga_count.ga_count_api, + visitorCounterTitle: '<i class="far fa-eye"></i>總瀏覽數:<span id="ga_value_site_pv">-</span> <i class="fa-solid fa-person-walking"></i>總訪客數:<span id="ga_value_site_uv">-</span>'
將原本 Busuanzi 使用的容器 ID 改為 GA 專用的容器
jsx 查看 1 2 - {showVisitorCounter ? <span id="busuanzi_container_site_uv" + {showVisitorCounter ? <span id="ga_container_site_pvuv"
結論 透過修改 Icarus 主題與串接 forgetfulengineer/google-analytics-data-api-netlify
,就能在網站中顯示來自 Google Analytics 的瀏覽數據,即時掌握網站的流量情況。
如果在串接過程中遇到問題,或有任何建議,歡迎留言讓我知道~接下來計畫新增「熱門文章排行榜」,敬請期待!
延伸閱讀