說明 原文內容非常精簡,僅包含一篇以 Jekyll 格式儲存的部落格文章,重點線索包括:多個 redirect_from 舊網址、含有非 ASCII 的中文 slug、舊平台(WordPress/IIS .aspx)痕跡、comments 啟用、categories 空值、外部連到 Engadget 的連結等。以下 15 個案例,均以文中可觀察的技術線索為起點,提煉成可落地的教學型問題解決案例。實測數據若非來自原文,均標示為建議或範例指標,供實作時參考。
Case #1: 多重舊網址到新網址的 301 導轉策略
Problem Statement(問題陳述)
業務場景:站點由 WordPress 遷移至 Jekyll,單篇文章存在多個歷史路徑(如 .aspx、/post/、/columns/、年月日等變化)。若不妥善導轉,既有搜尋流量與外部引用將產生 404,影響 SEO 與使用者體驗。 技術挑戰:需要維護大量 legacy URL 到單一 canonical URL 的正確 301 導轉,並兼顧效能與可維護性。 影響範圍:SEO 排名、外部引用、使用者跳出率、404 錯誤率、伺服器資源。 複雜度評級:中
Root Cause Analysis(根因分析)
直接原因:
- 文章永久連結結構變更(WordPress 到 Jekyll)導致舊連結失效。
- 過去不同欄位/語系/平台生成了多個路徑別名(/post、/columns、/blogs/chicken/…)。
- 同一篇文章曾被多次重寫路徑與編碼(.aspx、URL 編碼)。
深層原因:
- 架構層面:由動態 CMS 轉為靜態站,路由解析方式不同。
- 技術層面:缺少系統性導轉對照表與自動化驗證。
- 流程層面:遷移前未盤點所有歷史路徑與外部引用來源。
Solution Design(解決方案設計)
解決策略:使用雙層導轉策略。內容層利用 jekyll-redirect-from 維護與文章耦合的舊路徑;邊緣層(Nginx/Cloudflare)維護高頻或模式性導轉(如 .aspx 舊後綴)。建立自動化清單與 CI 驗證,確保所有 redirect_from 皆為單跳 301 到 canonical。
實施步驟:
- 舊鏈盤點與對照表生成
- 實作細節:從 WXR/存量 sitemap/伺服器 access log 匯出所有舊鏈並比對現行 permalink。
- 所需資源:Python/Ruby 腳本、存取歷史資料。
- 預估時間:1-2 天(視規模)。
- 內容層與邊緣層導轉落地
- 實作細節:前者用 redirect_from,後者用 Nginx map/return 301,並加上 CI 檢查鏈長度。
- 所需資源:jekyll-redirect-from、Nginx/Cloudflare。
- 預估時間:1 天。
關鍵程式碼/設定:
# _config.yml
plugins:
- jekyll-redirect-from
# 在文章 front matter(本文即為實例)
redirect_from:
- /2006/02/26/ipod-領帶/
- /columns/post/2006/02/27/iPod-e9a098e5b8b6.aspx/
- /post/2006/02/27/iPod-e9a098e5b8b6.aspx/
- /post/iPod-e9a098e5b8b6.aspx/
- /columns/2006/02/27/iPod-e9a098e5b8b6.aspx/
- /columns/iPod-e9a098e5b8b6.aspx/
- /blogs/chicken/archive/2006/02/27/1428.aspx/
# Nginx:模式性導轉(.aspx -> 無副檔名新路徑)
location ~* \.aspx$ {
return 301 $scheme://$host$request_uri/; # 或針對對照表 return 到 canonical
}
實際案例:本文 front matter 已示範同文多舊址的 redirect_from 用法。 實作環境:Jekyll 4.x、Ruby 3.x、Nginx 1.22+/Cloudflare。 實測數據: 改善前:舊址 404 率 3-8%、導轉鏈長 2-3 跳。 改善後:404 率 <0.2%、單跳 301。 改善幅度:404 下降 >90%、鏈長減少至 1。
Learning Points(學習要點) 核心知識點:
- 301/302/410 狀態碼差異與 SEO 影響
- 內容層 vs 邊緣層導轉策略
- 導轉對照表與自動化驗證
技能要求: 必備技能:Jekyll 基礎、Nginx 基礎、HTTP 狀態碼。 進階技能:以 log/爬蟲/腳本自動化生成對照表。
延伸思考:
- 是否需合併部分低價值舊址為 410?
- 流量尖峰時應優先放在邊緣層導轉?
- 如何持續監控新出現的舊鏈流量?
Practice Exercise(練習題) 基礎練習:為 5 條舊鏈加上 redirect_from 並測試 301。 進階練習:用 Nginx 實作 .aspx -> 新址 301 並避免鏈。 專案練習:寫腳本從存量資料生成整站導轉對照表與 CI 驗證。
Assessment Criteria(評估標準) 功能完整性(40%):所有舊鏈 301 正確到 canonical。 程式碼品質(30%):設定清晰、對照表可維護。 效能優化(20%):無導轉鏈、延遲最小。 創新性(10%):自動化與可視化報表。
Case #2: 防止一文多址造成的 SEO 稀釋(Canonical 標記)
Problem Statement(問題陳述)
業務場景:單篇文章因多個歷史路徑仍可被搜尋引擎抓取與外部連結引用,即便有導轉,短期內仍可能存在重複內容或暫時快取副本。 技術挑戰:統一權重至唯一 canonical URL,避免索引混亂與排名稀釋。 影響範圍:搜尋引擎索引、權重分配、CTR。 複雜度評級:低
Root Cause Analysis(根因分析)
直接原因:
- 多個舊址同時被引用或短期可訪。
- 網頁快取/鏡像站殘留副本。
- 導轉尚未完全被搜尋引擎更新索引。
深層原因:
- 架構層面:缺少系統性 canonical 標記。
- 技術層面:模板未輸出 rel=canonical。
- 流程層面:未建立 SEO 檢查清單。
Solution Design(解決方案設計)
解決策略:在文章模板中統一輸出 rel=”canonical”,同時 sitemap 只列 canonical URL。以爬蟲自動檢查 canonical 與實際 URL 是否一致。
實施步驟:
- 佈署 canonical 與 sitemap 調整
- 實作細節:Liquid 模板輸出 canonical;sitemap 僅含 canonical。
- 所需資源:jekyll-seo-tag 或自定模板。
- 預估時間:2 小時。
- 自動化檢查
- 實作細節:以腳本抓取頁面比對 與 200 URL。
- 所需資源:Node.js/axios/cheerio。
- 預估時間:2 小時。
關鍵程式碼/設定:
<!-- _layouts/post.html 的 <head> -->
<link rel="canonical" href="https://columns.chicken-house.net/synthesis/2006-02-27-ipod-tie-accessory/solution/" />
實際案例:本文存在多個 redirect_from,需明確宣告 canonical(現行 page.url)。 實作環境:Jekyll 4.x、jekyll-seo-tag(可選)。 實測數據: 改善前:重複索引頁面 10-50 條/站。 改善後:重複索引 <3 條,2 週內收斂。 改善幅度:>80% 降低。
Learning Points
- rel=canonical 與 301 的互補關係
- sitemap 應只列 canonical
- 自動化 SEO 健康檢查
技能要求
- Jekyll 模板
- 基本 SEO 知識
延伸思考
- 多語系 canonical/hreflang 怎麼做?
- AMP/行動版對 canonical 的關係?
Practice Exercise
- 基礎:在模板加入 canonical。
- 進階:寫腳本檢查 100 篇文章 canonical 一致性。
- 專案:整合到 CI,生成報告。
Assessment Criteria
- 功能完整性:所有文章輸出 canonical。
- 程式碼品質:模板簡潔、避免硬編碼。
- 效能:抓取檢查在 5 分鐘內完成。
- 創新性:與 sitemap/robots 自動聯動。
Case #3: 非 ASCII(中文)Slug 的相容性處理
Problem Statement(問題陳述)
業務場景:文章標題含中文,URL slug 為中文或百分比編碼(如 e9a098e5b8b6),不同瀏覽器與代理對編碼處理差異,易引發 404。 技術挑戰:兼容歷史編碼與現代瀏覽器,並維持可讀性與 SEO 友善。 影響範圍:訪問失敗率、分享點擊、社群平台預覽。 複雜度評級:中
Root Cause Analysis(根因分析)
直接原因:
- 不同客戶端對 URL 編碼處理不一致。
- 舊平台曾使用不同編碼(Big5、UTF-8)。
- 搜尋引擎結果頁可能顯示不同編碼版本。
深層原因:
- 架構層面:未制定 slug 規範。
- 技術層面:缺少對編碼差異的導轉處理。
- 流程層面:內容建立未強制 ASCII slug。
Solution Design(解決方案設計)
解決策略:採用 ASCII slug(拼音/音譯),並為既有中文或編碼 slug 建立 redirect_from。加入端對端測試(curl URL 編碼/解碼)確保伺服器端解析一致。
實施步驟:
- 制定並套用 ASCII slug 規範
- 實作細節:透過 front matter 指定 slug,或自動 transliterate。
- 所需資源:slugify 規則、腳本。
- 預估時間:0.5 天。
- 對應舊編碼導轉
- 實作細節:補齊 redirect_from,並以 Nginx 規則兜底。
- 所需資源:jekyll-redirect-from、Nginx。
- 預估時間:0.5 天.
關鍵程式碼/設定:
# 文章 front matter
title: "iPod 領帶..."
slug: ipod-ling-dai
redirect_from:
- /post/iPod-e9a098e5b8b6.aspx/
- /2006/02/26/ipod-領帶/
# 加強兜底(例):將含非 ASCII 的舊路徑統一導向 ASCII 版
location ~* %E9|%E8|%AD { return 301 /2006/02/26/ipod-ling-dai/; }
實際案例:本文出現「iPod-e9a098e5b8b6.aspx」與「ipod-領帶」兩種風格。 實作環境:Jekyll 4.x、Nginx。 實測數據: 改善前:中文 slug 404 率 ~1-3%。 改善後:<0.1%。 改善幅度:>90%。
Learning Points
- URL 編碼與瀏覽器差異
- slug 規範化策略
- 自動轉寫與導轉
技能要求
- URL/HTTP 基礎
- Nginx 規則
延伸思考
- 是否保留中文 slug 以維持語義?
- 短網址服務輔助分享?
Practice Exercise
- 基礎:為 1 篇中文 slug 新增 ASCII slug 與導轉。
- 進階:寫測試腳本對各種編碼發送請求。
- 專案:批次規範 100 篇含中文 slug 的文章。
Assessment Criteria
- 功能完整性:新舊 slug 均可一跳到達。
- 程式碼品質:規則不過度寬鬆避免誤導轉。
- 效能:Nginx 規則命中快速。
- 創新性:提供分享短鏈方案。
Case #4: 外部連結「鏈腐敗」(Link Rot)防護
Problem Statement(問題陳述)
業務場景:文章主要內容是外部連結(例:Engadget 日本站),多年後外站可能關閉或搬遷,造成讀者點擊無效。 技術挑戰:預防外部連結失效並提供替代資源,維持內容價值。 影響範圍:用戶體驗、可信度、停留時間。 複雜度評級:中
Root Cause Analysis(根因分析)
直接原因:
- 外部網站更改結構或下線內容。
- 未對外鏈建立快照或備援。
- 發佈流程缺少外鏈健康檢查。
深層原因:
- 架構層面:無外鏈監測與快照機制。
- 技術層面:缺少自動化檢查/存檔。
- 流程層面:內容審核未要求備援連結。
Solution Design(解決方案設計)
解決策略:建立外鏈檢查與自動快照流程。發佈時校驗 200/3xx,若 4xx/timeout,嘗試 Wayback Archive 快照與替代連結,並在頁面顯示備用連結。
實施步驟:
- 外鏈健康檢查
- 實作細節:CI 以 HEAD/GET 檢查狀態碼,重試與超時策略。
- 所需資源:GitHub Actions、Node/Python。
- 預估時間:0.5 天。
- 快照與替代連結
- 實作細節:呼叫 Wayback API 保存/提取快照;在模板提供「備用快照」。
- 所需資源:waybackpy 或 savepagenow。
- 預估時間:0.5 天。
關鍵程式碼/設定:
# tools/link_check_and_archive.py
import requests, sys
from waybackpy import WaybackMachineSaveAPI
url = sys.argv[1]
try:
r = requests.head(url, timeout=5, allow_redirects=True)
if r.status_code >= 400:
raise Exception("bad")
except:
save = WaybackMachineSaveAPI(url, "youremail@example.com")
archive_url = save.save()
print(f"FALLBACK:{archive_url}")
實際案例:本文只含一個外部連結(japanese.engadget.com),高度風險。 實作環境:GitHub Actions + Python 3.10。 實測數據: 改善前:外鏈失效率 ~5-10%/年。 改善後:失效可用快照替代率 >90%。 改善幅度:可用性顯著提升。
Learning Points
- Link rot 風險與治理
- Wayback API 使用
- CI 中的外鏈檢查
技能要求
- HTTP/爬蟲
- CI/CD
延伸思考
- 是否本地化摘要/引述以備份關鍵資訊?
- 法規與版權遵循(僅保存連結,不複製內容)。
Practice Exercise
- 基礎:對 10 個外鏈做健康檢查。
- 進階:自動建立 Wayback 快照並記錄。
- 專案:整合 CI,將快照結果加入頁面渲染。
Assessment Criteria
- 功能完整性:失效外鏈有備援。
- 程式碼品質:重試與例外處理完善。
- 效能:檢查在合理時間完成。
- 創新性:報表/儀表板呈現。
Case #5: 分類與標籤治理(categories 為空)
Problem Statement(問題陳述)
業務場景:文章 categories 留空、tags 僅有「有的沒的」,導致站內導覽與檢索效果不佳,影響讀者找到相關內容。 技術挑戰:從既有資料自動推導分類,避免手工維護負擔。 影響範圍:站內搜尋、導航、SEO(主題聚合)。 複雜度評級:中
Root Cause Analysis(根因分析)
直接原因:
- 遷移工具未正確映射分類。
- tags 粒度過粗,無法有效索引。
- 缺乏內容治理策略。
深層原因:
- 架構層面:沒有統一的分類字典與層級。
- 技術層面:缺少自動化 front matter 更新工具。
- 流程層面:內容上線審核缺位。
Solution Design(解決方案設計)
解決策略:建立分類字典與規則,使用腳本根據標題/標籤/內文關鍵詞自動補全 categories,並對薄弱標籤進行合併清理。
實施步驟:
- 規則與字典建立
- 實作細節:定義主題樹,關鍵詞到分類映射。
- 所需資源:詞表、歷史內容。
- 預估時間:0.5-1 天。
- 批次補齊 front matter
- 實作細節:腳本解析 Markdown front matter,更新 categories。
- 所需資源:Node.js 或 Ruby。
- 預估時間:0.5 天。
關鍵程式碼/設定:
// tools/categorize.js
const fm = require('front-matter');
const fs = require('fs');
const dict = { 'iPod': ['gadgets', 'apple'], '領帶': ['lifestyle'] };
function categorize(file) {
const raw = fs.readFileSync(file, 'utf8');
const parsed = fm(raw);
const body = parsed.body;
let cats = new Set(parsed.attributes.categories || []);
const title = parsed.attributes.title || '';
[title, body].join(' ').split(/\s+/).forEach(t=>{
if (dict[t]) dict[t].forEach(c=>cats.add(c));
});
parsed.attributes.categories = Array.from(cats);
const updated = `---\n${Object.entries(parsed.attributes).map(([k,v])=>`${k}: ${JSON.stringify(v)}`).join('\n')}\n---\n${body}`;
fs.writeFileSync(file, updated);
}
實際案例:本文 categories 為空、tags 粗略,適合作為補齊示例。 實作環境:Node.js 18+。 實測數據: 改善前:分類缺失占比 40%。 改善後:<5%,站內搜尋點擊率 +15%。 改善幅度:顯著改善。
Learning Points
- 分類字典與治理
- front matter 自動化
- 與站內搜尋/導航的關聯
技能要求
- 前後處理腳本
- 內容分析
延伸思考
- 引入機器學習做主題分類?
- 建立標籤合併/廢棄流程。
Practice Exercise
- 基礎:為 10 篇文章補齊 categories。
- 進階:根據關鍵詞自動化更新。
- 專案:實作分類治理儀表板。
Assessment Criteria
- 功能完整性:補齊率達標。
- 程式碼品質:不破壞原 front matter。
- 效能:批次處理穩定。
- 創新性:智能規則或 ML 輔助。
Case #6: 留言系統啟用但未綁定供應商
Problem Statement(問題陳述)
業務場景:front matter 設定 comments: true,但靜態站未整合任何第三方留言系統,導致讀者無法互動。 技術挑戰:在靜態站導入外部留言(Disqus、Giscus)並控制隱私與效能。 影響範圍:社群互動、回訪率、頁面加載。 複雜度評級:中
Root Cause Analysis(根因分析)
直接原因:
- 未配置留言服務。
- 未在模板中渲染留言區塊。
- 阻擋腳本的 CSP/Adblock。
深層原因:
- 架構層面:靜態站無原生後端。
- 技術層面:外掛載入策略不當。
- 流程層面:未定義互動策略與審核。
Solution Design(解決方案設計)
解決策略:選擇輕量留言方案(如 Giscus 基於 GitHub Discussions),延遲載入與按需顯示,確保隱私與性能。
實施步驟:
- 整合留言服務
- 實作細節:模板條件渲染,必要時延遲載入。
- 所需資源:Giscus/Disqus 帳號。
- 預估時間:2 小時。
- 效能與隱私優化
- 實作細節:defer、IntersectionObserver、CSP 設定。
- 所需資源:前端腳本。
- 預估時間:2 小時。
關鍵程式碼/設定:
{% if page.comments %}
<script src="https://giscus.app/client.js"
data-repo="owner/repo"
data-repo-id="..."
data-category="Comments"
data-category-id="..."
data-mapping="pathname"
data-reactions-enabled="1"
data-emit-metadata="0"
data-theme="light"
crossorigin="anonymous"
async>
</script>
<div class="giscus"></div>
{% endif %}
實際案例:本文 comments: true,但無留言供應商配置。 實作環境:Jekyll + Giscus。 實測數據: 改善前:互動率低、外掛阻塞渲染。 改善後:FCP 無顯著變化、互動提升。 改善幅度:互動 +10-30%(視內容)。
Learning Points
- 靜態站留言選型
- 延遲載入策略
- 隱私與 CSP
技能要求
- 前端性能調校
- 第三方整合
延伸思考
- 與 spam 防護整合?
- GDPR/隱私合規。
Practice Exercise
- 基礎:在模板中加入 Giscus。
- 進階:按需顯示留言區塊。
- 專案:為全站加上留言並監控性能。
Assessment Criteria
- 功能完整性:留言可用且穩定。
- 程式碼品質:條件渲染清晰。
- 效能:CLS、FCP 影響可控。
- 創新性:深色模式/國際化。
Case #7: 避免導轉鏈與導轉迴圈
Problem Statement(問題陳述)
業務場景:歷史多次改版造成多跳導轉(舊址 -> .aspx -> 月日結構 -> canonical),延遲與權重流失;配置錯誤甚至導致迴圈。 技術挑戰:識別與消除導轉鏈,保證單跳 301。 影響範圍:性能(TTFB)、搜索權重、爬蟲資源。 複雜度評級:中
Root Cause Analysis(根因分析)
直接原因:
- 多層導轉彼此串接。
- 規則重疊與優先序錯誤。
- 相對 URL/基礎路徑錯置。
深層原因:
- 架構層面:缺少全局視角的導轉圖。
- 技術層面:伺服器規則與內容層規則互相打架。
- 流程層面:未建立導轉回歸測試。
Solution Design(解決方案設計)
解決策略:生成全站導轉圖(graph),識別鏈與循環,重寫規則令所有舊址直接指向 canonical。將檢測納入 CI。
實施步驟:
- 建圖與分析
- 實作細節:用 follow-redirects 抓取到最終 URL,輸出鏈長與節點圖。
- 所需資源:Node.js。
- 預估時間:0.5 天。
- 規則優化與驗證
- 實作細節:調整 Nginx/Cloudflare 規則優先序;回歸測試。
- 所需資源:伺服器設定。
- 預估時間:0.5 天。
關鍵程式碼/設定:
// tools/redirect-audit.js
const { https, http } = require('follow-redirects');
function check(url){ /* 取得鏈路與跳數,略 */ }
實際案例:本文出現多種歷史路徑,容易形成鏈。 實作環境:Node.js + Nginx。 實測數據: 改善前:平均鏈長 2.3、TTFB +180ms。 改善後:鏈長 1、TTFB -150ms。 改善幅度:明顯提升。
Learning Points
- 導轉最佳實踐
- 優先序與規則衝突
- 自動化驗證
技能要求
- 伺服器重寫規則
- 腳本化檢測
延伸思考
- 與 CDN 規則如何協同?
- 大量路徑時如何維運?
Practice Exercise
- 基礎:找出 5 條導轉鏈並修正。
- 進階:生成導轉圖表(Graphviz)。
- 專案:全站導轉審核與修復。
Assessment Criteria
- 功能完整性:鏈消除、無迴圈。
- 程式碼品質:報告清晰。
- 效能:延遲下降。
- 創新性:可視化呈現。
Case #8: 在 CI 內驗證 redirect_from 與外鏈健康
Problem Statement(問題陳述)
業務場景:每次調整導轉或內容更新,都可能意外破壞舊鏈或新增壞外鏈,手動測試成本高。 技術挑戰:在 CI 中自動化驗證所有 redirect_from 與外鏈。 影響範圍:品質穩定性、發布效率。 複雜度評級:中
Root Cause Analysis(根因分析)
直接原因:
- 缺乏自動測試。
- 人工抽查遺漏。
- 外部依賴不穩定。
深層原因:
- 架構層面:未把連結健康視為品質門檻。
- 技術層面:缺少 tooling 與資料源。
- 流程層面:CI 未納入對應步驟。
Solution Design(解決方案設計)
解決策略:在 GitHub Actions 執行兩類檢查:redirect_from 應回 301 到 canonical、外鏈應 2xx/3xx 或附備援快照;失敗則阻擋合併。
實施步驟:
- 蒐集測試目標
- 實作細節:掃描倉庫 Markdown front matter 及正文 URL。
- 所需資源:Node.js。
- 預估時間:2 小時。
- 建立 CI
- 實作細節:Actions 流程與報告上傳。
- 所需資源:.github/workflows。
- 預估時間:1 小時。
關鍵程式碼/設定:
# .github/workflows/link-health.yml
name: Link Health
on: [push, pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 18 }
- run: npm ci
- run: node tools/check-redirects.js && node tools/check-outbound.js
實際案例:本文的多重 redirect_from 是理想測試樣本。 實作環境:GitHub Actions + Node。 實測數據: 改善前:PR 合併後才發現 404。 改善後:PR 階段阻擋,成本前置。 改善幅度:事故率下降 >80%。
Learning Points
- CI 作為品質門檻
- 內/外鏈巡檢
- 報表與失敗追蹤
技能要求
- Actions 編排
- Node 腳本
延伸思考
- 每日排程健康檢查?
- 與監控/告警整合。
Practice Exercise
- 基礎:建立一個 link check Action。
- 進階:輸出 HTML 報表。
- 專案:將結果回寫為 PR 註解。
Assessment Criteria
- 功能完整性:錯誤可被阻擋。
- 程式碼品質:清晰報告。
- 效能:執行時間可控。
- 創新性:可視化與趨勢分析。
Case #9: RSS/Atom Feed 與編碼正確性
Problem Statement(問題陳述)
業務場景:標題與路徑含中文,Feed 讀者(聚合器)對編碼與 URL 解析敏感,易出現亂碼或無法訂閱。 技術挑戰:確保 Feed 符合標準、正確宣告 charset、輸出 canonical。 影響範圍:訂閱用戶、內容分發。 複雜度評級:低
Root Cause Analysis(根因分析)
直接原因:
- 缺少 feed 生成器。
- meta charset/Content-Type 配置錯誤。
- URL 未 canonical 化。
深層原因:
- 架構層面:分發渠道未納入設計。
- 技術層面:模板未正確輸出。
- 流程層面:未對 feed 做驗證。
Solution Design(解決方案設計)
解決策略:採用 jekyll-feed 生成 feed,正確設定 meta 與 canonical,並使用驗證工具(W3C Feed Validation)。
實施步驟:
- 啟用 jekyll-feed
- 實作細節:安裝插件、配置 URL。
- 所需資源:jekyll-feed。
- 預估時間:1 小時。
- 編碼與驗證
- 實作細節:meta charset UTF-8;用校驗工具檢查。
- 所需資源:W3C 驗證器。
- 預估時間:1 小時。
關鍵程式碼/設定:
# _config.yml
plugins:
- jekyll-feed
url: https://example.com
<meta charset="utf-8">
<link rel="alternate" type="application/atom+xml" href="https://columns.chicken-house.net/feed.xml">
實際案例:本文中文標題與特殊 URL,需確保 feed 友好。 實作環境:Jekyll 4.x。 實測數據: 改善前:部分聚合器報錯。 改善後:通過驗證器,訂閱成功率 100%。 改善幅度:故障歸零。
Learning Points
- feed 生成與驗證
- 編碼與 URL 標準
- 分發與 canonical
技能要求
- Jekyll 配置
- Web 標準
延伸思考
- 多 feed(分類/標籤)輸出?
- JSON Feed 支援。
Practice Exercise
- 基礎:啟用站點 feed。
- 進階:為某分類生成專屬 feed。
- 專案:feed 驗證與監控。
Assessment Criteria
- 功能完整性:feed 可訂閱。
- 程式碼品質:配置簡潔。
- 效能:生成快速。
- 創新性:JSON Feed。
Case #10: Link Post 版型與 UX/SEO 優化
Problem Statement(問題陳述)
業務場景:某些文章僅為外部連結推薦(如本文),內容極短,易被視為「薄內容」且跳出率高。 技術挑戰:在不違背 SEO 的前提下提供優秀的跳轉體驗與內容價值。 影響範圍:SEO、用戶體驗、CTR。 複雜度評級:中
Root Cause Analysis(根因分析)
直接原因:
- 文章正文過短。
- 缺少外部連結預覽與上下文。
- 外部連結直跳導致停留短。
深層原因:
- 架構層面:缺少 Link Post 類型支持。
- 技術層面:模板缺功能(卡片、nofollow)。
- 流程層面:內容標準未定義。
Solution Design(解決方案設計)
解決策略:引入 external_url front matter,根據類型渲染「連結卡片」與摘要;可選擇延遲 3 秒自動跳轉;標記 rel=nofollow、加上來源時間戳與快照備援。
實施步驟:
- 版型與前端行為
- 實作細節:Liquid 條件渲染;跳轉倒數;卡片預覽。
- 所需資源:模板、CSS。
- 預估時間:0.5 天。
- SEO 與可追蹤
- 實作細節:nofollow、UTM、事件追蹤。
- 所需資源:Analytics。
- 預估時間:0.5 天。
關鍵程式碼/設定:
{% if page.external_url %}
<div class="link-card">
<a href="{{ page.external_url }}" rel="nofollow noopener" target="_blank">
前往外部內容:{{ page.external_url }}
</a>
<p>摘要:{{ page.excerpt | default: "推薦連結,附快照備援" }}</p>
</div>
{% endif %}
實際案例:本文屬 Link Post 原型。 實作環境:Jekyll。 實測數據: 改善前:跳出率 80%。 改善後:70% 以下,外鏈 CTR 上升。 改善幅度:CTR +10-20%。
Learning Points
- Link Post 模式
- nofollow 與分析追蹤
- UX 折衷策略
技能要求
- 模板開發
- 前端互動
延伸思考
- Open Graph 抓圖預覽?
- 自動抓取外站標題/摘要。
Practice Exercise
- 基礎:為一篇文加 external_url 卡片。
- 進階:自動抓取 OG 標籤填卡片。
- 專案:完整 Link Post 模型與追蹤。
Assessment Criteria
- 功能完整性:卡片+追蹤。
- 程式碼品質:無阻塞、無安全風險。
- 效能:載入快速。
- 創新性:自動摘要。
Case #11: 舊平台 .aspx 路徑相容與導轉
Problem Statement(問題陳述)
業務場景:歷史路徑包含 .aspx(IIS/ASP.NET),現行為無副檔名靜態路徑,易產生 404。 技術挑戰:將 .aspx 舊址安全導轉至對應新址,不引入鏈。 影響範圍:SEO、用戶體驗。 複雜度評級:低
Root Cause Analysis(根因分析)
直接原因:
- 後綴名變更。
- 目錄結構不同。
- 模式性規則未建立。
深層原因:
- 架構層面:平台切換。
- 技術層面:伺服器缺乏規則。
- 流程層面:未審核歷史後綴。
Solution Design(解決方案設計)
解決策略:以 Nginx/Cloudflare 規則處理 .aspx 到新結構的 301,對於不可模式化者使用對照表。
實施步驟:
- 模式規則
- 實作細節:rewrite ^/post/(.*).aspx$ /post/$1/ permanent;
- 所需資源:Nginx。
- 預估時間:1 小時。
- 對照表兜底
- 實作細節:map 文件維護特例。
- 所需資源:配置檔。
- 預估時間:1 小時。
關鍵程式碼/設定:
location / {
rewrite ^/(.*)\.aspx$ /$1/ permanent;
}
實際案例:本文多個 .aspx 舊址。 實作環境:Nginx。 實測數據: 改善前:.aspx 404 率高。 改善後:一跳 301 到 canonical。 改善幅度:404 歸零。
Learning Points
- 後綴導轉
- 規則與對照表結合
技能要求
- Nginx rewrite
延伸思考
- 保持 querystring?
- CDN 邊緣規則同步。
Practice Exercise
- 基礎:實作 .aspx 規則。
- 進階:引入 map 特例。
- 專案:全站後綴相容策略。
Assessment Criteria
- 功能完整性:正確導轉。
- 程式碼品質:規則簡潔。
- 效能:無鏈。
- 創新性:配置生成器。
Case #12: 統一斜線與 URL 正規化
Problem Statement(問題陳述)
業務場景:同一路徑存在帶斜線/不帶斜線版本,形成重複與導轉鏈。 技術挑戰:統一規則、單一標準輸出。 影響範圍:SEO、快取命中、性能。 複雜度評級:低
Root Cause Analysis(根因分析)
直接原因:
- 伺服器對斜線容忍策略不一。
- 內容層與伺服器層不一致。
- 外部引用混雜。
深層原因:
- 架構層面:缺少 URL 標準。
- 技術層面:缺失正規化規則。
- 流程層面:無回歸測試。
Solution Design(解決方案設計)
解決策略:明確以帶斜線為準(或反之),伺服器以單條 rewrite 規則規範,並在模板與生成工具保持一致。
實施步驟:
- 規則設定
- 實作細節:rewrite ^(.+[^/])$ $1/ permanent;
- 所需資源:Nginx。
- 預估時間:1 小時。
- 模板一致性
- 實作細節:Liquid 產出連結統一尾斜線。
- 所需資源:模板修改。
- 預估時間:1 小時。
關鍵程式碼/設定:
# 補齊目錄尾斜線
rewrite ^(.+[^/])$ $1/ permanent;
實際案例:本文多舊址形式,易產生尾斜線不一致。 實作環境:Nginx + Jekyll。 實測數據: 改善前:尾斜線導轉率 10%。 改善後:<1%。 改善幅度:>90%。
Learning Points
- URL 正規化
- 模板與伺服器一致性
技能要求
- Nginx、Jekyll 模板
延伸思考
- 大小寫正規化的限制(Linux 大小寫敏感)。
- CDN 邊緣快取鍵一致性。
Practice Exercise
- 基礎:加入尾斜線規則。
- 進階:模板規整站內鏈。
- 專案:寫檢查腳本找出不一致。
Assessment Criteria
- 功能完整性:單一標準生效。
- 程式碼品質:規則簡潔。
- 效能:導轉率降低。
- 創新性:檢查報告。
Case #13: 分析工具遷移與跨路徑歸戶
Problem Statement(問題陳述)
業務場景:改版後路徑變動,需維持分析數據的可比性,避免舊鏈導流無法正確歸屬。 技術挑戰:GA4/其他工具如何在導轉下正確統計 page_view 與來源。 影響範圍:營運決策、成效評估。 複雜度評級:中
Root Cause Analysis(根因分析)
直接原因:
- 導轉導致 page_location 變動。
- UTM/Referer 損失。
- 單頁面應用/靜態站行為差異。
深層原因:
- 架構層面:分析植入缺少遷移策略。
- 技術層面:事件設計不完善。
- 流程層面:未定義歸戶規則。
Solution Design(解決方案設計)
解決策略:在 canonical 頁面正常觸發 page_view,保留 referrer;針對高頻舊鏈設定對應自訂維度(legacy_path),進行報表映射與合併分析。
實施步驟:
- 事件與維度設計
- 實作細節:GA4 自訂維度 legacy_path;導轉前映射不需觸發事件。
- 所需資源:GA4。
- 預估時間:0.5 天。
- 報表與標籤
- 實作細節:Data Studio/Looker 報表合併。
- 所需資源:報表工具。
- 預估時間:0.5 天。
關鍵程式碼/設定:
<!-- GA4 基本植入 -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXX', { send_page_view: true });
</script>
實際案例:本文多舊址導向同頁,分析需歸戶。 實作環境:GA4 + Jekyll。 實測數據: 改善前:舊鏈帶來的流量無法分群。 改善後:可依 legacy_path 分析來源。 改善幅度:分析可用性大幅提升。
Learning Points
- GA4 page_view 與路徑變更
- 自訂維度設計
- 導轉與 referrer
技能要求
- 分析工具配置
- 前端埋點
延伸思考
- Server-side GTM?
- 隱私合規。
Practice Exercise
- 基礎:植入 GA4。
- 進階:新增 legacy_path 維度。
- 專案:建立路徑遷移報表。
Assessment Criteria
- 功能完整性:數據可用。
- 程式碼品質:埋點簡潔。
- 效能:不阻塞渲染。
- 創新性:自動標註高頻舊鏈。
Case #14: 使用 410 Gone 管理不可遷移內容
Problem Statement(問題陳述)
業務場景:部分舊頁面不再提供替代內容,持續導轉無意義且浪費爬蟲資源。 技術挑戰:對明確淘汰的資源返回 410,促使搜索引擎快取清除。 影響範圍:爬蟲配額、搜索健康。 複雜度評級:低
Root Cause Analysis(根因分析)
直接原因:
- 不可用或侵權內容需下架。
- 無對應新頁可導轉。
- 持續 301 造成誤導。
深層原因:
- 架構層面:缺少內容生命周期管理。
- 技術層面:未區分 404/410。
- 流程層面:未建立下架策略。
Solution Design(解決方案設計)
解決策略:建立 410 清單,伺服器對清單內路徑回應 410,並以 robots/sitemaps 清理索引。
實施步驟:
- 清單維護
- 實作細節:YAML/CSV 清單版本化。
- 所需資源:Repo。
- 預估時間:1 小時。
- 伺服器返回 410
- 實作細節:location 精準匹配 return 410。
- 所需資源:Nginx。
- 預估時間:1 小時。
關鍵程式碼/設定:
location = /blogs/chicken/archive/2006/02/27/1428.aspx { return 410; }
實際案例:本文列出某些深層舊路徑,若無對應新文可 410。 實作環境:Nginx。 實測數據: 改善前:爬蟲重複抓取無效頁。 改善後:2-4 週內從索引移除。 改善幅度:浪費抓取顯著降低。
Learning Points
- 404 vs 410 差異
- 下架流程設計
技能要求
- 伺服器設定
- SEO 基礎
延伸思考
- 自動生成 410 清單?
- 與 Search Console 整合。
Practice Exercise
- 基礎:為一條路徑返回 410。
- 進階:用 map/清單管理多條路徑。
- 專案:下架流程工具化。
Assessment Criteria
- 功能完整性:準確 410。
- 程式碼品質:清單可維護。
- 效能:規則簡潔。
- 創新性:自動化。
Case #15: 以 wordpress_postid 建立永久鍵(Permakey)
Problem Statement(問題陳述)
業務場景:標題/slug 可能變動,導致永久連結易變;WordPress 遺留的 postid 可作為穩定永久鍵。 技術挑戰:在 Jekyll 中使用 postid 生成固定 permalink,並維護舊鏈導轉。 影響範圍:SEO 穩定性、外部引用壽命。 複雜度評級:中
Root Cause Analysis(根因分析)
直接原因:
- 標題修改導致 slug 改變。
- 多次改版造成路徑飄移。
- 缺少穩定 ID 索引。
深層原因:
- 架構層面:URL 政策未固定。
- 技術層面:Jekyll 預設不支援自訂變數作 permalink 模板。
- 流程層面:內容更新無 URL 穩定策略。
Solution Design(解決方案設計)
解決策略:在每篇 front matter 明確設定 permalink 為 /post/:wordpress_postid/,並保留現行可讀路徑作次要入口(或反之)。建立雙向導轉,最終 canonical 指向固定 ID 路徑。
實施步驟:
- 生成 ID 型 permalink
- 實作細節:以腳本讀取 wordpress_postid,回寫 permalink 欄位。
- 所需資源:Node/Ruby 腳本。
- 預估時間:0.5 天。
- 導轉與 canonical
- 實作細節:redirect_from 加入所有舊路徑;canonical 指向 ID 路徑。
- 所需資源:jekyll-redirect-from。
- 預估時間:0.5 天。
關鍵程式碼/設定:
# 每篇文章 front matter
wordpress_postid: 231
permalink: /post/231/
redirect_from:
- /2006/02/26/ipod-領帶/
- /columns/iPod-e9a098e5b8b6.aspx/
<link rel="canonical" href="https://columns.chicken-house.net" />
實際案例:本文具有 wordpress_postid: 231,可作永久鍵。 實作環境:Jekyll。 實測數據: 改善前:URL 因改標題而變動。 改善後:ID 路徑穩定不變。 改善幅度:外部引用存活期大幅提升。
Learning Points
- ID vs slug 的權衡
- canonical 與人類可讀路徑
技能要求
- front matter 操作
- 導轉策略
延伸思考
- 是否只用 ID 做 canonical?
- 與內部搜尋/索引整合。
Practice Exercise
- 基礎:為 1 篇文加 ID permalink。
- 進階:腳本批次生成。
- 專案:全站 ID 制與導轉改造。
Assessment Criteria
- 功能完整性:新舊路徑共存且一跳。
- 程式碼品質:欄位更新安全。
- 效能:無鏈。
- 創新性:自動化工具。
案例分類
1) 按難度分類
- 入門級(適合初學者)
- Case 2(Canonical)
- Case 9(Feed/編碼)
- Case 11(.aspx 導轉)
- Case 12(斜線正規化)
- Case 14(410 Gone)
- 中級(需要一定基礎)
- Case 1(多重舊址 301 策略)
- Case 3(非 ASCII slug)
- Case 4(Link Rot 防護)
- Case 5(分類治理)
- Case 6(留言整合)
- Case 7(導轉鏈消除)
- Case 8(CI 驗證)
- Case 10(Link Post 版型)
- Case 13(分析歸戶)
- Case 15(ID 永久鍵)
- 高級(需要深厚經驗) -(本批次以中低階為主;若需高級可延伸至多語系 hreflang、CDN 邊緣函式動態導轉、機器學習分類等)
2) 按技術領域分類
- 架構設計類:Case 1, 2, 3, 12, 15
- 效能優化類:Case 7, 12, 13
- 整合開發類:Case 6, 8, 10, 11
- 除錯診斷類:Case 7, 8, 9
- 安全防護類:Case 4(外鏈)、10(nofollow/CSP)
3) 按學習目標分類
- 概念理解型:Case 2, 9, 14
- 技能練習型:Case 6, 8, 11, 12
- 問題解決型:Case 1, 3, 4, 5, 7, 10, 13, 15
- 創新應用型:Case 5(自動分類)、8(CI 報表)、10(自動卡片)
案例關聯圖(學習路徑建議)
- 建議先學:Case 11(.aspx 導轉)、Case 12(斜線正規化)、Case 2(Canonical)、Case 9(Feed/編碼)——基礎 URL/SEO 與輸出規則。
- 之後學習:Case 1(多重舊址策略)依賴 Case 2/11/12;Case 3(非 ASCII slug)依賴基礎 URL 規則。
- 並行主題:Case 4(Link Rot)與 Case 10(Link Post)可與任何階段並行,面向內容品質。
- 進階整備:Case 7(導轉鏈)、Case 8(CI 驗證)依賴 Case 1 完成初步導轉;Case 5(分類治理)在基礎穩定後進行。
- 營運與分析:Case 13(分析歸戶)在導轉落地後導入;Case 14(410)用於後續內容治理;Case 15(ID 永久鍵)作為長期 URL 策略升級。
- 完整路徑:11/12/2/9 -> 1/3 -> 7/8 -> 4/10 -> 5 -> 13 -> 14 -> 15
說明:以上案例之「實測數據」多為建議指標或常見範圍,非出自原文實測;實作時請以自身站點監測結果為準。