Eleventy 站蓋好了,文章也寫完了,然後你對著空蕩蕩的文章底部發呆:留言要放哪?

靜態站沒有 PHP、沒有資料庫,不能像 WordPress 那樣裝個外掛就結束——它 build 完就是一堆 HTML,不會自己幫你收留言。最直覺的做法是接託管留言服務:讀者在你的頁面打字,資料存在第三方雲端,你不用自己維護留言後端。(咖啡還是要自己泡,這部分 AI 暫時幫不了。)

直接回答: 用 FastComments 官方外掛 fastcomments-11ty,在 eleventy.config.js 註冊一次、模板貼一行 shortcode,大約 10 分鐘就能在文章頁看到留言區。下面會走完整五步驟,文末還有一張決策表,幫你在 FastComments、Giscus、Disqus 之間選型。

靜態站要留言,為什麼不自己寫後端?

白話講:Eleventy 像印報機——你給它 Markdown,它印出一疊 HTML。印完就下班了,不會在旁邊站一個服務員幫你記留言。

所以要「動態功能」(留言、即時搜尋、聊天),通常兩條路:

  • 手動貼第三方 <script> — 可行,但每個模板複製貼上,改 tenantId 容易漏一頁。
  • 用外掛包成 shortcode — 設定檔註冊一次,模板寫 fastcomments shortcode(見下方範例),像貼便利貼,而不是重寫整面牆。

FastComments 走第二條。它把留言 widget 包成 Nunjucks/Liquid shortcode,比較適合:

  • 讀者是一般大眾(不必有 GitHub 帳號)
  • 你從 WordPress 遷到 11ty,想保留「路過也能留一句」的體驗
  • 不想碰後端,也不想自己架 Remark42 那類自架方案

若讀者幾乎都是工程師、本來就在 GitHub 上混,文末決策表會建議改看 Giscus——沒有誰比較高級,差在受眾習慣

動手前要準備什麼?

項目要求
Node.js與你的 Eleventy 專案一致(建議 18+)
Eleventy>= 2.0.0(外掛 peer dependency)
FastComments 帳號fastcomments.com 註冊,取得正式 tenantId
文章模板已有 post.njk 或類似 layout,能在正文 content 變數下方加一區

怎麼安裝 fastcomments-11ty?

在 11ty 專案根目錄:

npm install fastcomments-11ty

截至 2026-05,npm 最新版為 1.0.2,MIT 授權。完整 API 見 官方 11ty 指南

怎麼在 Eleventy 設定檔註冊外掛?

CommonJS 或 ESM 擇一就好。

CommonJS.eleventy.jseleventy.config.cjs):

const { fastcommentsPlugin } = require('fastcomments-11ty');

module.exports = function (eleventyConfig) {
  eleventyConfig.addPlugin(fastcommentsPlugin);
};

ESMeleventy.config.jspackage.json"type": "module"):

import { fastcommentsPlugin } from 'fastcomments-11ty';

export default function (eleventyConfig) {
  eleventyConfig.addPlugin(fastcommentsPlugin);
};

若專案同時有 eleventy.config.js.eleventy.js,只留一個設定入口——外掛註冊兩次,留言區不會變兩倍好笑,只會變兩倍困惑。

tenantId 是什麼?要放哪裡?

tenantId 像你家留言箱的門牌號:公開在頁面原始碼沒關係,不是 API key 那種秘密。真正不能外洩的是後台 API key

取得步驟:

  1. 登入 FastComments 後台。
  2. Comment Widget 程式碼片段API credentials 頁面 找到 tenantId(字串,例如 aKa2Z4Q=)。
  3. 開發可先用官方示範值 "demo" 試 UI;上線前務必換成自己的 ID,否則留言會進示範租戶——等於幫別人收信。

建議集中放在 _data/fastcomments.json

{
  "tenantId": "你的-tenantId"
}

模板用 fastcomments.tenantId 資料檔欄位引用,之後換帳號只改一個檔。

怎麼在文章模板加上留言區?

post.njk_includes 的文章區塊底部,正文輸出之後:

Nunjucks(最常見):

<article>
  {{ content | safe }}
</article>

<section class="comments" aria-label="留言區">
  {% fastcomments { tenantId: fastcomments.tenantId } %}
</section>

暫時寫死也可以:

{% fastcomments { tenantId: "你的-tenantId" } %}

Liquid.liquid 模板):

{% fastcomments tenantId: "你的-tenantId" %}

可選:文章列表顯示留言數

<p>本篇已有 {% fastcommentsCommentCount { tenantId: fastcomments.tenantId } %} 則留言</p>

個人部落格通常只要 fastcommentsfastcommentsCommentCount;即時聊天、圖片標註留言等進階功能,需要時再查官方文件。

怎麼驗收 build 有沒有成功?

npm run build
npm run serve

打開任一文章頁,依序確認:

  • 留言 widget 有載入(開發者工具 Network 看得到 cdn.fastcomments.com 請求)
  • 用測試帳號留一則言,FastComments 後台看得到
  • 若網站有設 Content-Security-Policy,至少把 https://cdn.fastcomments.com 加入 script-srcconnect-src 通常還需允許 https://fastcomments.com*.fastcomments.com
  • 有歐盟讀者時,帳號可能要改在 eu.fastcomments.com 註冊

第三方腳本會影響效能分數;若你也在意 PageSpeed 與 Core Web Vitals,留言 widget 上線後記得重測一次,別讓 LCP 偷偷變慢。

FastComments、Giscus、Disqus 要選哪個?

裝好只是第一步。還在猶豫的話,這張表先對照三個常見方案:

維度FastCommentsGiscusDisqus
架構託管 SaaS;留言在 FastComments 雲端開源 widget;留言存 GitHub Discussions託管 SaaS;留言在 Disqus
11ty 整合官方 fastcomments-11ty shortcode手動貼 giscus.app 產生的 <script>手動貼 Disqus embed snippet
讀者登入Email/社群等多種(依後台設定)必須有 GitHub 帳號多種社群帳號
效能官方標榜輕量(單一 async script);仍為第三方 JS腳本很小,對 Core Web Vitals 友善腳本重、常拖慢載入
廣告無廣告無廣告免費版常注入廣告
GDPR/隱私標榜 GDPR 合規;EU 資料駐留需用 eu 站註冊無追蹤廣告;資料在 GitHub免費版追蹤與 Cookie 議題多
費用30 天免費試用+付費(Creators 約 $5.99/月或 Flex 用量計費;無永久免費層)免費(GitHub 免費方案內)免費版有廣告;去廣告要付費
維護成本低:管後台+外掛版本中:要維護公開 repo + 開 Discussions低設定,但長期要處理效能/隱私客訴
適合誰一般讀者部落格、聯盟站、不想碰後端技術向、讀者本來就用 GitHub舊站遷移、可接受廣告與追蹤

實務建議:

  • 讀者是一般大眾、從 WordPress 遷移想保留「任何人都能留言」→ FastComments(或付費去廣告的替代 SaaS)
  • 開源/工程師部落格、留言要進 Git 流程 → Giscus
  • 新站 不建議 再選 Disqus 免費版,除非你有舊留言要匯入且接受效能與隱私取捨

進階:只想用部分 shortcode,或想改名字?

外掛預設會註冊十幾個 shortcode。若只要留言區和留言數:

eleventyConfig.addPlugin(fastcommentsPlugin, {
  shortcodes: ['fastcomments', 'fastcommentsCommentCount'],
  prefix: 'fc', // 變成 fcFastcomments shortcode
});

或不用外掛、手動註冊,自己取名:

const { fastcomments, commentCount } = require('fastcomments-11ty');

eleventyConfig.addShortcode('comments', fastcomments);
eleventyConfig.addShortcode('commentCount', commentCount);

模板改為自訂的 comments shortcode——適合跟既有 shortcode 避開命名衝突。

常見問題

demo tenantId 可以上線嗎?

不行,僅供試玩。正式環境一定要換成自己帳號的 ID。

每篇文章留言會分開嗎?

會。FastComments 依頁面 URL(urlId)區分討論串;靜態站每篇文章有獨立 permalink,就會各自一串。

外掛很久沒發新版,是不是壞了?

不一定。官方說明:wrapper 包的是核心 VanillaJS 元件,bug 修復可能只更新 CDN 腳本、不一定要發 npm 新版;重大 API 變更才會 bump 外掛版本。

台灣站、沒有 GDPR 壓力也要管嗎?

沒有歐盟訪客壓力較小,但第三方腳本仍建議在隱私權政策裡揭露。若預期有 EU 流量,帳號與資料駐留要另外評估。

下一步可以做什麼?

在個人站工作流裡,留言通常排在內容管線跑通之後——先讓文章能 build、能部署、能搜尋(例如用 Pagefind 做站內搜尋),再在 post layout 底部加一個 shortcode 區塊,不必改 build 核心。

若照這篇做完,可以:

  1. FastComments 註冊,領 30 天試用,把 tenantId 換成正式值
  2. 留一則測試留言,確認後台與前台都正常
  3. 讀者偏技術的話,回頭對照上文決策表評估 Giscus

留言上線後,靜態站就多了一條「發文 → 有人回」的閉環。沒有一杯咖啡解決不了的 deploy;如果有,至少留言區可以讓讀者幫你吐槽 build 錯在哪。

參考資料