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 避開命名衝突。

懶人版:用 Vibe Coding 請 AI 幫你做

上面五步驟手動做很快,但如果你習慣 Vibe Coding——用自然語言描述「我要什麼」,讓 AI 在專案裡找檔案、改設定、跑 build——整篇教學可以濃縮成幾輪對話。

Vibe Coding 不是魔法。 你還是要能看懂 diff、確認 tenantId 沒貼錯、最後自己留一則測試留言。差別在於:你不用背 shortcode 語法,也不必記得 eleventy.config.js 是 CJS 還是 ESM——把上下文丟給 AI,它會對照你 repo 現況補齊。

FastComments LLM Kit:官方給 AI 的說明書

若你打算讓 AI 幫忙整合,建議先裝 FastComments LLM Kit——這是官方給編碼助手(Claude、Cursor、ChatGPT 等)用的文件搜尋橋樑。AI 不必靠過時的訓練資料猜 shortcode 語法,而是能即時查官方說明,整合品質通常比「裸問」穩定。

做法: 在專案根目錄的 AGENTS.mdCLAUDE.md 貼上官方片段(英文原文即可,AI 看得懂):

## FastComments Integration

FastComments is an embeddable live commenting platform with libraries for many frontend and backend integrations, along with client and server-side SDKs and APIs.

When working with FastComments, you can search the FastComments documentation by calling this API:

https://docs-search.fastcomments.com/search?query=<search_query>&full=true&tenantId=demo

Replace `<search_query>` with your search terms (URL encoded). The API returns relevant documentation snippets to help with implementation.

貼好之後,你可以直接問:

  • 「怎麼在 11ty 安裝 FastComments?」
  • 「FastComments SSO 要怎麼設定?」
  • 「API 驗證有哪些選項?」

AI 會用上面的搜尋 API 拉回相關文件片段再回答。tenantId=demo 只是搜尋用的示範值,不影響你專案裡留言 widget 用的正式 tenantId

手動試搜尋 API(確認有回傳再交給 AI 也行):

https://docs-search.fastcomments.com/search?query=11ty%20eleventy&full=true&tenantId=demo

回傳是 JSON,內含 titleurlbody 等欄位——例如搜 11ty eleventy 會命中官方 11ty 指南的 Install、Shortcodes、Plugin Options 等段落。

MCP Server:讓 AI 直接呼叫 FastComments API(進階)

若你不只想「查文件」,還希望 AI 直接操作 FastComments(例如列出留言、改設定),可以用官方託管的 MCP Server。它依 OpenAPI 自動產生工具,REST API 能做的事,MCP 客戶端理論上也能做。

端點格式:

https://fastcomments.com/mcp?tenantId=YOUR_TENANT_ID&API_KEY=YOUR_API_KEY

也可用 HTTP header 傳 x-tenant-idx-api-key,適合不支援把金鑰寫進 URL 的客戶端。

Cursor 可在 MCP 設定檔(例如 ~/.cursor/mcp.json)加入:

{
  "mcpServers": {
    "fastcomments": {
      "type": "http",
      "url": "https://fastcomments.com/mcp?tenantId=YOUR_TENANT_ID&API_KEY=YOUR_API_KEY"
    }
  }
}

Claude Code 一行註冊:

claude mcp add --transport http fastcomments 'https://fastcomments.com/mcp?tenantId=YOUR_TENANT_ID&API_KEY=YOUR_API_KEY'

註冊後在 Claude Code 裡跑 /mcp,可確認連線與可用工具列表。

後台也有圖形化產生器:Integrate → MCP Server,或直接開 MCP 設定頁,選 API key 後複製現成片段——比手動拼 URL 不容易打錯。

安全提醒(很重要):

項目說明
tenantId可出現在頁面原始碼,屬公開識別碼
API key秘密。MCP URL 含 key,等同密碼——勿貼進公開聊天、截圖或 commit
外洩處理到後台 API Keys 頁輪替金鑰,舊 key 立即失效

個人部落格「文章頁加留言」通常 LLM Kit 就夠;MCP 比較適合要自動化後台、或把留言資料接進其他流程的進階用法。

開始前要準備什麼?

  1. Cursor、Claude Code、Copilot 等工具裡打開整個 11ty 專案(不是只貼一段 code 到聊天窗)。
  2. AGENTS.mdCLAUDE.md 貼上上文 LLM Kit 片段;若專案已有慣用 package manager(pnpm / npm)、模板路徑,一併寫在同檔,整合品質更好。
  3. FastComments 領好 tenantId,或先說「開發用 demo,上線前再換」。
  4. (可選)需要 AI 操作後台 API 時,再設定 MCP Server,並確認 API key 只存在本機設定、不進 git

第一輪:一次講清楚目標

把下面 prompt 貼進 AI 對話,把括號內容改成你的專案狀況:

我在用 Eleventy (11ty) 靜態部落格,想在每篇文章底部加上 FastComments 留言區。

請依照官方 fastcomments-11ty 外掛做法:
1. 安裝 fastcomments-11ty(用這個 repo 慣用的套件管理器)
2. 在 eleventy 設定檔註冊 fastcommentsPlugin(注意我是 CJS 還是 ESM)
3. 把 tenantId 集中放在 _data/(先用 "demo" 或我的正式 ID:[貼 tenantId])
4. 在文章 layout(例如 post.njk)正文  下方加留言 shortcode
5. 跑 build,確認沒有錯誤

改完請簡短列出動了哪些檔案,以及我要手動驗收什麼。

這一輪通常就涵蓋了本文的「安裝 → 註冊 → tenantId → 模板 → build」五步。AI 若發現你已有 eleventy.config.js.eleventy.js 兩個入口,理應只改其中一個——若沒有,第二輪補一句「外掛好像註冊了兩次,請檢查」。

第二輪:驗收與除錯

留言區沒出現、或 build 過了但頁面空白時,不要重貼整篇教學,改描述現象:

build 成功,但文章頁底部沒有留言 widget。
請打開瀏覽器開發者工具的角度幫我查:
- post 模板是否真的有輸出 fastcomments shortcode
- Network 有沒有請求 cdn.fastcomments.com
- 若網站有 Content-Security-Policy,是否需放行 FastComments 網域

修好後告訴我改了什麼。

若你用的是 Barba.js 或類似 SPA 換頁,記得加一句:「站內用 Barba 做 page transition,留言 widget 換頁後要重新 mount。」——否則 AI 可能只處理首次載入,忽略換頁後留言區消失的問題。

第三輪(可選):進階客製

對照上文「進階」一節,用 prompt 指定即可:

fastcomments-11ty 我只要 fastcomments 和 fastcommentsCommentCount 兩個 shortcode,
其餘不要註冊。shortcode 前綴改成 fc。

或在文章列表顯示「本篇已有 X 則留言」,用資料檔的 tenantId。

Vibe Coding 時別踩的坑

狀況建議
API key 貼進 prompt 或 commit MCP 設定tenantId 可公開;API key 絕對不要進聊天紀錄、截圖或 git
沒裝 LLM Kit 就怪 AI 答錯先貼 LLM Kit 片段,讓 AI 能搜官方文件
AI 改了一堆不相關檔案要求「只動留言整合必要的檔案」,並自己看 git diff
不跑 build 就說完成明講「請跑 npm run build 或專案的 build 指令確認」
上線還用 demo請 AI 把 _data/ 換成正式 tenantId,並提醒你在後台看得到測試留言

心法: 教學文給你地圖,Vibe Coding 讓 AI 當嚮導——你負責說目的地(「文章頁要有留言」)和驗票(build、留測試言、看後台)。兩條路最後都會到同一個留言區;選你當下比較順手的那條就好。

常見問題

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 錯在哪。

參考資料