深色模式
建好站台之後就在想要不要幫部落格加個留言功能。 畢竟技術文章有時候真的需要跟讀者討論交流,但又不想搞得太複雜。 考慮過幾個方案後,最後選擇了 Waline,這篇文章就來聊聊為什麼選它,以及實際整合的過程。
在決定用哪套留言系統之前,我其實看了好幾個選項:
Disqus 雖然老牌但太重了,而且免費版有廣告,隱私問題也讓人不太放心。
Giscus 基於 GitHub Discussions,對技術部落格來說很棒,但問題是不是每個讀者都有 GitHub 帳號。 我自己寫的內容有技術文也有生活隨筆,如果只有 GitHub 用戶能留言,感覺門檻有點高。
最後選了 Waline 的原因很簡單:
首先要把 Waline 的用戶端套件裝起來。
我的專案用的是 pnpm:
pnpm add @waline/client
如果你用 npm 或 yarn:
npm install @waline/client # or yarn add @waline/client
接下來要建立一個 Vue 元件來包裝 Waline。
在 VitePress 專案中,我把它放在 docs/.vitepress/theme/components/WalineComment.vue:
docs/.vitepress/theme/components/WalineComment.vue
<script setup lang="ts"> import { onMounted, onUnmounted, watch, ref } from 'vue' import { useRoute, useData } from 'vitepress' import { init } from '@waline/client' import '@waline/client/style' const route = useRoute() const { isDark } = useData() const walineInstance = ref<any>(null) // Waline 設定 const walineOptions = { el: '#waline-comments', serverURL: 'https://your-waline-server.vercel.app', // 替換成你的後端 URL lang: 'zh-TW', locale: { placeholder: '留下你的想法...', // ... 其他繁體中文翻譯 }, dark: isDark.value ? 'html.dark' : 'auto', meta: ['nick', 'mail', 'link'], requiredMeta: ['nick'], pageSize: 10, emoji: [ 'https://cdn.jsdelivr.net/npm/@waline/emojis@1.2.0/weibo', 'https://cdn.jsdelivr.net/npm/@waline/emojis@1.2.0/bilibili', ], pageview: true, comment: true, } // 初始化 onMounted(() => { walineInstance.value = init(walineOptions) }) // 路由變化時更新留言 watch(() => route.path, () => { if (walineInstance.value) { walineInstance.value.update() } }) // 深色模式切換 watch(isDark, (newValue) => { if (walineInstance.value) { walineInstance.value.update({ dark: newValue ? 'html.dark' : 'auto', }) } }) // 清理 onUnmounted(() => { if (walineInstance.value) { walineInstance.value.destroy() } }) </script> <template> <div class="waline-wrapper"> <div class="waline-container"> <h2 class="waline-title">💬 留言討論</h2> <div id="waline-comments"></div> </div> </div> </template>
這個元件做了幾件重要的事:
lang: 'zh-TW'
locale
isDark
在 docs/.vitepress/theme/index.ts 中註冊這個元件:
docs/.vitepress/theme/index.ts
import WalineComment from './components/WalineComment.vue' export default { extends: DefaultTheme, Layout, enhanceApp({ app }) { app.component('WalineComment', WalineComment) // ... 其他元件 } }
接著要在文章頁面底部加上留言區。
我的做法是修改 docs/.vitepress/theme/Layout.vue,使用 VitePress 的 #doc-after slot:
docs/.vitepress/theme/Layout.vue
#doc-after
<template> <Layout> <template #doc-after> <!-- 只在文章頁面顯示留言 --> <WalineComment v-if="isArticlePage && frontmatter.comment !== false" /> </template> </Layout> </template> <script setup lang="ts"> import { useData } from 'vitepress' import { computed } from 'vue' const { page, frontmatter } = useData() // 判斷是否為文章頁面 const isArticlePage = computed(() => { return (frontmatter.value.date || frontmatter.value.tags) && !page.value.relativePath.includes('index.md') }) </script>
這樣做的好處是:
comment: false
Waline 預設的樣式可能跟你的主題不太搭,可以加一些 CSS 調整:
.waline-wrapper { margin-top: 4rem; padding-top: 2rem; border-top: 1px solid var(--vp-c-divider); } /* 深色模式適配 */ html.dark .wl-card { background-color: var(--vp-c-bg-soft); color: var(--vp-c-text-1); } html.dark .wl-editor { background-color: var(--vp-c-bg-soft); border-color: var(--vp-c-divider); } /* 按鈕樣式與主題一致 */ .wl-btn { background-color: var(--vp-c-brand-1) !important; } .wl-btn:hover { background-color: var(--vp-c-brand-2) !important; } /* 統一操作按鈕顏色 */ .wl-login-btn, .wl-logout-btn, .wl-refresh { color: var(--vp-c-brand-1) !important; }
前端整合完成後,還需要部署 Waline 的後端服務。
最簡單的方式是用 Vercel:
點擊以下連結直接部署(會自動建立正確的範本倉庫):
https://vercel.com/new/clone?repository-url=https://github.com/walinejs/waline/tree/main/example
重要提醒:不要直接 fork Waline 主專案再部署,那樣會因為包含完整原始碼而導致構建失敗。使用上面的一鍵部署連結,Vercel 會自動從 example 目錄建立正確的範本。
example
在 LeanCloud 國際版 註冊並建立應用,取得以下憑證:
回到 Vercel 專案,進入 Settings → Environment Variables,新增:
LEAN_ID=your_leancloud_app_id LEAN_KEY=your_leancloud_app_key LEAN_MASTER_KEY=your_leancloud_master_key LEAN_SERVER=https://your_app_id.api.lncldglobal.com
說明:
LEAN_SERVER
https://前8碼.api.lncldglobal.com
設定完成後,點擊 Redeploy 重新部署。
部署完成後,你會得到一個 Vercel URL(例如:https://your-waline.vercel.app),把它填到前面元件的 serverURL 設定裡就完成了。
https://your-waline.vercel.app
serverURL
整合過程中遇到幾個小問題,記錄一下:
一開始發現切換深色模式時,Waline 的主題沒有跟著變。後來發現要用 watch 監聽 isDark 變化,然後呼叫 update() 方法更新主題。
watch
update()
在 VitePress 中切換文章時是用戶端路由,Waline 不會自動更新。需要監聽 route.path 變化,手動觸發 update()。
route.path
如果沒有在 onUnmounted 清理 Waline 實體,會有記憶體洩漏的風險,特別是在頻繁切換頁面時。
onUnmounted
Waline 還有一些好用的進階功能:
可以設定當有新留言或被回覆時,自動發送郵件通知。
在 Vercel 環境變數中設定:
SMTP_SERVICE=Gmail SMTP_USER=your_email@gmail.com SMTP_PASS=your_app_password SITE_NAME=你的部落格名稱 SITE_URL=https://yourblog.com
整合 Akismet 來過濾垃圾留言:
AKISMET_KEY=your_akismet_key
瀏覽 https://your-waline-server.vercel.app/ui 可以進入管理後台,審核和管理留言。
https://your-waline-server.vercel.app/ui
整合 Waline 到 VitePress 其實沒想像中複雜,主要就是:
使用 Waline 後,留言系統變得輕量又好用,對技術部落格來說非常合適。 部署在 Vercel 也省去了維護後端的麻煩,跟部落格用同一個平台,感覺很一致。 包括你正在看的這篇文章底下的留言區,就是用 Waline 實作的!
如果你也在找適合技術部落格的留言系統,Waline 真的是個不錯的選擇。
為 VitePress 部落格加上 Waline 留言系統
建好站台之後就在想要不要幫部落格加個留言功能。 畢竟技術文章有時候真的需要跟讀者討論交流,但又不想搞得太複雜。 考慮過幾個方案後,最後選擇了 Waline,這篇文章就來聊聊為什麼選它,以及實際整合的過程。
為什麼選 Waline?
在決定用哪套留言系統之前,我其實看了好幾個選項:
Disqus 雖然老牌但太重了,而且免費版有廣告,隱私問題也讓人不太放心。
Giscus 基於 GitHub Discussions,對技術部落格來說很棒,但問題是不是每個讀者都有 GitHub 帳號。 我自己寫的內容有技術文也有生活隨筆,如果只有 GitHub 用戶能留言,感覺門檻有點高。
最後選了 Waline 的原因很簡單:
實作步驟
第一步:安裝 Waline 用戶端套件
首先要把 Waline 的用戶端套件裝起來。
我的專案用的是 pnpm:
如果你用 npm 或 yarn:
2
3
第二步:建立 Waline Vue 元件
接下來要建立一個 Vue 元件來包裝 Waline。
在 VitePress 專案中,我把它放在
docs/.vitepress/theme/components/WalineComment.vue: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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
這個元件做了幾件重要的事:
lang: 'zh-TW'和locale物件確保介面是繁中isDark狀態,自動切換佈景主題第三步:註冊元件
在
docs/.vitepress/theme/index.ts中註冊這個元件:2
3
4
5
6
7
8
9
10
第四步:整合到文章頁面
接著要在文章頁面底部加上留言區。
我的做法是修改
docs/.vitepress/theme/Layout.vue,使用 VitePress 的#doc-afterslot:2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
這樣做的好處是:
comment: false就行第五步:樣式調整
Waline 預設的樣式可能跟你的主題不太搭,可以加一些 CSS 調整:
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
後端部署(Vercel)
前端整合完成後,還需要部署 Waline 的後端服務。
最簡單的方式是用 Vercel:
1. 一鍵部署到 Vercel
點擊以下連結直接部署(會自動建立正確的範本倉庫):
重要提醒:不要直接 fork Waline 主專案再部署,那樣會因為包含完整原始碼而導致構建失敗。使用上面的一鍵部署連結,Vercel 會自動從
example目錄建立正確的範本。2. 註冊 LeanCloud 資料庫
在 LeanCloud 國際版 註冊並建立應用,取得以下憑證:
3. 設定 Vercel 環境變數
回到 Vercel 專案,進入 Settings → Environment Variables,新增:
2
3
4
說明:
LEAN_SERVER是 LeanCloud 的 API 端點地址,通常格式為https://前8碼.api.lncldglobal.com設定完成後,點擊 Redeploy 重新部署。
4. 更新前端設定
部署完成後,你會得到一個 Vercel URL(例如:
https://your-waline.vercel.app),把它填到前面元件的serverURL設定裡就完成了。踩過的坑
整合過程中遇到幾個小問題,記錄一下:
1. 深色模式不會自動切換
一開始發現切換深色模式時,Waline 的主題沒有跟著變。後來發現要用
watch監聽isDark變化,然後呼叫update()方法更新主題。2. 路由切換時留言沒更新
在 VitePress 中切換文章時是用戶端路由,Waline 不會自動更新。需要監聽
route.path變化,手動觸發update()。3. 別忘了清理實體
如果沒有在
onUnmounted清理 Waline 實體,會有記憶體洩漏的風險,特別是在頻繁切換頁面時。進階功能
Waline 還有一些好用的進階功能:
郵件通知 (如果有 SMTP)
可以設定當有新留言或被回覆時,自動發送郵件通知。
在 Vercel 環境變數中設定:
2
3
4
5
整合 Akismet 反垃圾留言
整合 Akismet 來過濾垃圾留言:
管理後台
瀏覽
https://your-waline-server.vercel.app/ui可以進入管理後台,審核和管理留言。總結
整合 Waline 到 VitePress 其實沒想像中複雜,主要就是:
使用 Waline 後,留言系統變得輕量又好用,對技術部落格來說非常合適。 部署在 Vercel 也省去了維護後端的麻煩,跟部落格用同一個平台,感覺很一致。 包括你正在看的這篇文章底下的留言區,就是用 Waline 實作的!
如果你也在找適合技術部落格的留言系統,Waline 真的是個不錯的選擇。