靜態 SEO
審核並改善靜態 HTML 網站的 SEO 設定,涵蓋九個類別——head 元資料、結構化資料、內容品質、Open Graph 圖片、Sitemaps 與索引、代理程式發現、效能、重新導向以及 CI 驗證。作法為平台中立:使用原始 <meta> 標籤、原始 JSON-LD、手寫的 sitemap.xml、通用的 CI 工具。審核框架與 astro-seo 類似,但沒有 @jdevalk/astro-seo-graph 的核心架構。
程式碼作法存放在 AGENTS.md——當你需要實作特定修正時,請閱讀該檔案。這個檔案包含工作流程和審核檢查清單。
工作流程
- 檢測專案——確認這是靜態網站,識別建置工具,找出套用變更的位置。
- 審核——為九個類別評分,並產出可行的發現。
- 改善——產生或修改檔案以填補差距。作法詳見
AGENTS.md。 - 中繼資料檢查——對技能產生的每個短字串(標題、描述、Schema 的
description欄位、常見問題解答)呼叫metadata-check。 - 驗證——執行建置,驗證產出,提醒使用者有關非檔案任務(Search Console、Bing 網站管理員工具、IndexNow 金鑰提交)。
階段 0:檢測專案
在審核之前確認基本事項:
- 它確實是一個靜態網站。 尋找已建置的 HTML——repo 根目錄下的
index.html,或_site/(Jekyll)、public/(Hugo / 11ty / Gatsby)、dist/(Vite / Astro 靜態)、out/(使用output: export的 Next.js)目錄下。如果一切都是伺服器端渲染(Express、PHP、動態路由),則這個技能不適用——請指向 Astro 的astro-seo、WP 外掛頁面的wp-readme-optimizer,或建議進行通用 SEO 審核。 - 來源建置工具。 決定套用 head 元資料變更的位置:
_config.yml/_layouts/→ Jekyllconfig.toml/config.yaml/themes/→ Hugo.eleventy.js/_includes/→ 11tygatsby-config.js/src/components/SEO.*→ Gatsby- 使用
output: 'export'的next.config.js和pages/_document.tsx→ Next.js 靜態匯出 astro.config.mjs→ Astro(在這種情況下,請改用astro-seo)- 沒有建置設定,只有 HTML 檔案 → 手寫或爬取的(例如
wp-static-clone產出)。直接編輯 HTML 或使用後處理腳本。
- 標準網站 URL。 在 repo 中搜尋正式環境來源——通常位於
_config.yml、config.toml、astro.config,或硬編碼在版型中。如果缺少、為空或是localhost,請在執行任何其他操作之前將其標記為阻斷問題。 Canonicals、Sitemaps、OG 圖片 URL 和 JSON-LD 的@id值都由此衍生。 - 部署目標。 讀取
vercel.json、netlify.toml、wrangler.toml或public/_headers以確定主機。影響階段 2 中的重新導向和標頭語法。 - 網站是否為多語言? 檢查語言環境子目錄(
/en/、/nl/、/de/)或建置工具的 i18n 設定。如果是,則 hreflang 很重要;如果否,則跳過。 <head>中已經有什麼? 開啟一個已建置的 HTML 檔案並盤點:title、description、canonical、robots、Open Graph、Twitter Cards、JSON-LD、hreflang。如果能參考現有內容,階段 1 的審核會更快。
只詢問你無法檢測到的部分。
階段 1:審核
每個類別評分 0-10 分。針對每個類別,給出 2-4 個具體發現,並引用實際的 HTML、設定或範本。在每個類別中,檢查分為不同層級:
- Must——發布阻斷。失敗會導致明顯的 SEO 退步。
- Should——標準做法。跳過會損害觸及率。
- Nice——前瞻性或情境性。有用,但不是每個網站的基礎。
對於小型個人網站,跳過 Nice 檢查,除非使用者要求完整的處理。
1. Head 元資料 (/10)
- Must——每個頁面都有
<title>和<meta name="description">。 - Must——設定
<link rel="canonical">,並移除追蹤參數,從正式環境來源衍生。 - Must——當頁面是
noindex時,省略 canonical(根據 Google 的建議)。 - Must——
<title>長度 30-65 個字元,<meta name="description">長度 70-200 個字元(SERP 截斷範圍;與metadata-check預設值相同)。 - Should——
<meta name="robots">包含max-snippet:-1、max-image-preview:large、max-video-preview:-1。 - Should——每個頁面上都有 Open Graph(
og:title、og:description、og:image、og:url、og:type、og:site_name)。 - Should——當 Twitter Card 標籤(
twitter:card)與 Open Graph 重複時,將其抑制(Twitter 會自動回退)。 - Should——在多語言網站上使用
hreflang替代方案。如果是單語言,則跳過。 - Should——每個頁面只有一個
<meta name="robots">和一個og:image(舊版工具有時會產生重複)。
2. 結構化資料 / JSON-LD (/10)
- Must——每個重要頁面上至少有一個
<script type="application/ld+json">區塊。 - Should——使用連結的
@graph而非扁平化的Article物件——用@id引用連接實體,這樣BlogPosting可以指向其Person作者和WebPage父頁面。 - Should——在相關處呈現
WebSite、Blog/WebPage、Person/Organization、BlogPosting/Article、BreadcrumbList、ImageObject。 - Should——信任訊號:
publishingPrinciples、copyrightHolder、copyrightYear、knowsAbout、SearchAction。 - Must——在 Rich Results Test 和 ClassySchema 中驗證通過。
3. 內容品質 (/10)
- Must——每個頁面都有唯一的
<title>和<meta name="description">(網站上不能有重複的中繼資料)。 - Must——每個頁面只有一個
<h1>。 - Should——透過
metadata-check(階段 2.5)審核<title>和<meta name="description">,檢查前置加載、具體性和 SERP 契合度。 - Should——對於個別的長篇文章(不要大量審核),透過
readability-check審核正文散文。 - Should——每個
<img>都有alt屬性(或裝飾性圖片使用alt=""/role="presentation")。 - Should——內部連結使用根目錄相對路徑(
/foo/)而非絕對路徑(https://...)——在網域變更和預覽時仍有效。
4. Open Graph 圖片 (/10)
- Must——每個頁面都有 OG 圖片。
- Must——1200x675(Google Discover 最小寬度 1200px,16:9 比例)。
- Should——JPEG(社交平台無法可靠支援 OG 圖片的 WebP / AVIF 格式)。
- Should——在建置時產生(satori-cli、sharp、ImageMagick、Vercel OG、Bannerbear),而非手動為每個頁面上傳——防止內容漂移。
- Should——URL 根據 slug 確定性衍生(例如
/og/<slug>.jpg),以便新增頁面時自動獲得圖片。 - Should——正文內容中的每個
<img>都有alt屬性(或alt=""/role="presentation")。透過 CI 中的html-proofer或類似工具驗證。
5. Sitemaps 與索引 (/10)
- Must——
/sitemap.xml(或拆分 Sitemap 的/sitemap_index.xml)可存取、為有效的 XML、每個 URL 都回傳 200。 - Must——在網站根目錄存在
robots.txt,並引用 Sitemap。 - Must——存在 RSS Feed,透過
<link rel="alternate" type="application/rss+xml">宣傳,包含完整的文章內容(非截斷的摘要)。 - Should——如果網站有多個內容類型(
sitemap-posts.xml、sitemap-pages.xml),則按區塊拆分——更容易在 GSC 中除錯索引問題。 - Should——
<lastmod>從 git 提交時間戳(最準確)、建置時間戳(可接受)或 frontmatter 日期(最後手段)填入。來自 CI checkout 的檔案系統mtime是錯誤的——它是 checkout 日期,而非內容日期。 - Should——整合 IndexNow。驗證金鑰作為網站根目錄的靜態
/<key>.txt路由,以及一個建置或部署鉤子,用於將新 URL POST 到https://api.indexnow.org/IndexNow。將提交工作限制在正式環境主機上(例如CF_PAGES_BRANCH=main、VERCEL_ENV=production、CONTEXT=production)——無條件提交會從本地建置向端點發送正式環境主機尚未提供服務的 URL,導致金鑰被標記為無效 (403) 並強制輪換。
6. 代理程式發現 (/10)
- Should——Schema 端點(
/schema/<type>.json)針對每種內容類型公開整個語料庫的 JSON-LD。提交到 repo 的靜態 JSON 檔案,或由建置重新產生。 - Should——Schema 地圖(
/schemamap.xml)列出每個 Schema 端點,並在robots.txt中使用Schemamap:指令。 - Should——在網站根目錄提供
llms.txt,為 LLM 使用者列出頁面(標題 + 描述)。靜態文字檔案;每行一個頁面。 - Should——Markdown 替代 URL(
/blog/post.md與/blog/post/相鄰)提供帶有 YAML frontmatter 的乾淨 Markdown,以便 AI 代理程式無需 HTML 解析即可消費內容。可以提交.md兄弟檔案,或使用 Cloudflare Transform Rule +Vary: Accept進行內容協商(CF Pages 會剝離自訂的 Vary 標頭,因此僅使用 Transform Rule 的 URL 重寫——作法請見AGENTS.md)。 - Should——根據 RFC 9727,在
/.well-known/api-catalog提供 API 目錄,格式為application/linkset+json(RFC 9264)。列出 Schema 端點、Schemamap、RSS Feed 以及任何特定網站的 API。靜態 JSON 檔案。 - Should——在
robots.txt中使用 Content Signals 指令(Content-Signal: ai-train=yes, search=yes, ai-input=yes或你偏好的政策)。一行,IETF 草案,成本低。 - Should——在
/*上使用Link標頭指向發現檔案(sitemap、llms.txt、api-catalog、schemamap)。讀取回應標頭的代理程式無需解析 HTML 即可找到它們。特定於主機(Cloudflare Pages / Netlify 上使用_headers,Vercel 上使用vercel.json,其他平台使用伺服器設定)。 - Nice——MCP 伺服器卡片位於
/.well-known/mcp/server-card.json和/或 A2A 代理卡片位於/.well-known/agent-card.json。僅在網站公開 MCP 伺服器或 A2A 代理時相關。 - Nice——
<link rel="nlweb">指向對話式端點。NLWeb 的採用尚在早期;這個標籤只有一行,值得擁有,但在 2026 年不是評分阻斷因素。 - Nice——ARD(Agentic Resource Discovery)目錄位於
/.well-known/ai-catalog.json,列出網域提供的內容(MCP 伺服器、A2A 代理、OKF 套件、特定網站 API)。v0.9 草案,因此為選用——但它是 MCP / A2A 卡片和 OKF 套件得以發揮價值的發現層。兩個注意點:基礎規範(Agent-Card/ai-catalog)將媒體類型欄位命名為mediaType,而 ARD 層(ards-project/ard-spec)將其命名為type——請使用相同的值發出兩個鍵,以便條目在任一讀取下都能通過驗證(兩個規範都要求消費者忽略未知鍵)。ARD 還為每個條目新增了一個可選的representativeQueries陣列,包含範例提示。靜態 JSON 檔案。 - Nice——OKF(Open Knowledge Format)套件:一個由類型化 Markdown 概念檔案(每個頁面一個,路徑鏡像標準 URL)組成的樹狀結構,打包為單一
.tar.gz,中間包含索引檔案。提供服務和發現是 OKF 明確的非目標——這是 ARD 目錄條目的用途。v0.9 草案,選用。目前尚無已註冊的媒體類型,因此暫用字串為application/okf-bundle+gzip(追蹤於 knowledge-catalog#111 和 ard-spec#27);將其標記為暫用,可能會變更。最好從網站其餘部分所衍生的相同來源產生,而不是手動維護的副本。
7. 效能 (/10)
- Must——已雜湊的資源提供
Cache-Control: public, max-age=31536000, immutable(或等效設定),以便它們只下載一次。 - Should——主要網頁字體預先加載為
woff2,透過<link rel="preload" as="font" crossorigin>。 - Should——
No-Vary-Search回應標頭從快取鍵中移除 UTM 參數(這樣/?utm_source=x和/共享一個快取條目)。 - Should——首次繪製時沒有阻塞渲染的 JavaScript(對非關鍵腳本使用 defer 或 async)。
- Should——圖片使用現代格式(頁面內內容使用 WebP / AVIF;OG 卡片僅使用 JPEG)並在折疊線以下使用
loading="lazy"。 - Should——所有 Lighthouse / PageSpeed Core Web Vitals 均為綠色:LCP < 2.5s、INP < 200ms、CLS < 0.1。
8. 重新導向與錯誤處理 (/10)
- Must——為每個曾經存在且已移動的 URL 維護
_redirects/vercel.json/ 伺服器設定。 - Must——永久移動使用
301而非302。 - Must——
404.html(或等效檔案)回傳 404 狀態,而非 200。使用curl -I針對一個故意錯誤的 URL 進行驗證。 - Should——在 404 頁面上提供模糊比對建議("您是不是要找…?")以處理 URL 中的拼寫錯誤。靜態實作:預先建置一個有效 slug 的 JSON 索引,在客戶端進行模糊比對。
9. CI 驗證 (/10)
- Must——在 CI 中設定斷開連結檢查器。在每次推送影響內容時,使用 linkinator 或 lychee。內部連結和外部連結都檢查——內部連結可捕獲建置回歸,外部連結可捕獲連結腐爛。排程每週運行一次僅檢查外部連結的任務。
- Should——透過 html-proofer 或 W3C Validator 進行 HTML 驗證——捕獲可能破壞爬蟲的錯誤標記。
- Should——在每次推送時使用 Lighthouse CI,並設定分數閾值(例如 SEO ≥ 95、效能 ≥ 80)。
- Should——在 CI 中透過 Schema.org JSON-LD validator 驗證 JSON-LD(沒有官方的 CLI;透過一個 POST 到 API 的 Node 腳本進行)。
- Should——在 CI 中驗證標題和描述長度:一個小腳本,遍歷已建置的 HTML,擷取
<title>和<meta name="description">,標記任何超出範圍的內容