結論先講

網站搬家不做 redirect 等於 SEO 自殺,但自殺不代表救不回來。 我們的部落格從 Hexo 搬到 Quartz,沒做任何 redirect,300 篇文章的 Google 索引全部變成 404。花了 8 週,用 redirect + sitemap + 封面圖 + 結構化資料一步步修回來。結論:遷移的第一天就該做好 SEO,但如果你跟我一樣忘了,現在開始也不晚。

這不是教科書的案例分析。這是我自己搞砸、然後自己修的真實記錄。數字是真的,時間軸是真的,踩過的坑也是真的。


起點:300 篇文章,0 個搜尋流量

背景

  • 舊站:Hexo 靜態部落格,跑了 3 年多,約 300 篇技術文章
  • 新站:Quartz 知識庫,2025 年底上線
  • 搬家方式:直接把 Markdown 搬過去,沒做任何 SEO 處理

問題診斷

搬家後兩個月,我打開 Google Search Console 看了一眼:

指標數值
Google 索引的頁面287
其中可用頁面0
其中 404 錯誤283
其中重新導向4
搜尋點擊(近 28 天)2
搜尋曝光(近 28 天)34

287 個被 Google 索引的頁面,幾乎全是舊站的 URL 格式(/2024/03/15/some-post/),全部回傳 404。新站的 URL 格式(/seo/01-seo-fundamentals)一篇都沒被收錄。

問題總結:

  1. 舊站 URL 全部 404,沒有 redirect 到新站
  2. 新站沒提交 sitemap
  3. 新站沒有 meta description、沒有 OG tags
  4. 沒有封面圖,社群分享只有文字
  5. 沒有結構化資料(Schema.org)

修復時間軸

第 1 週:止血 — Redirect + Sitemap

目標: 把舊站流量導到新站,讓 Google 知道新頁面在哪。

設定 Redirect

Hexo 的 URL 格式是 /YYYY/MM/DD/post-name/,Quartz 是 /category/post-name。我寫了一個映射表:

// generate-redirects.mjs — 產生 redirect 規則
import { readFileSync, writeFileSync, readdirSync } from 'fs';
import { join } from 'path';
 
const contentDir = './content';
const redirects = [];
 
// 掃描所有 .md 檔案,從 frontmatter 取得舊 URL
function scanDir(dir) {
  for (const entry of readdirSync(dir, { withFileTypes: true })) {
    if (entry.isDirectory()) {
      scanDir(join(dir, entry.name));
    } else if (entry.name.endsWith('.md')) {
      const content = readFileSync(join(dir, entry.name), 'utf-8');
      const oldUrlMatch = content.match(/old_url:\s*(.+)/);
      if (oldUrlMatch) {
        const oldUrl = oldUrlMatch[1].trim();
        const newUrl = join(dir, entry.name)
          .replace('content/', '/')
          .replace('.md', '');
        redirects.push({ from: oldUrl, to: newUrl });
      }
    }
  }
}
 
scanDir(contentDir);
 
// 產生 Cloudflare Pages _redirects 檔案
const rules = redirects.map(r => `${r.from} ${r.to} 301`).join('\n');
writeFileSync('public/_redirects', rules);
console.log(`產生 ${redirects.length} 條 redirect 規則`);

如果你的部落格放在 GitHub Pages 上,可以用 jekyll-redirect-from 或直接在 HTML 裡用 <meta http-equiv="refresh">。Cloudflare Pages 則支援 _redirects 檔案。

提交 Sitemap

# 確認 sitemap 可以存取
curl -I https://your-blog.com/sitemap.xml
# HTTP/2 200 ← 要看到這個
 
# 在 GSC 手動提交
# GSC → Sitemaps → 輸入 sitemap.xml → 提交

第 1 週結果:

指標修復前第 1 週末
404 頁面283283(還沒被重新爬取)
已索引新頁面03
Sitemap 狀態未提交已提交,287 個 URL

第 2-4 週:門面 — 封面圖 + OG Tags + Keywords

目標: 讓 Google 正確理解每個頁面的內容,讓社群分享有吸引力。

每篇文章加上 Meta 資訊

# 修復前的 frontmatter
---
title: 什麼是 SEO
---
 
# 修復後的 frontmatter
---
title: '[seo/01] SEO 不是玄學:工程師該知道的搜尋引擎優化基礎'
description: 寫了 300 篇文章但 Google 搜不到?SEO 不是行銷部門的事,是工程決策。
keywords:
  - SEO 基礎
  - Google 搜尋引擎優化
  - 技術 SEO
cover: covers/seo-01-seo-fundamentals-og.webp
---

封面圖產生

每篇文章都需要一張 1200x630 的 OG 封面圖。手動做太慢,我用腳本批次產生:

// generate-og-images.mjs — 概念版
// 實際用 @vercel/og 或 sharp + canvas 產生
import sharp from 'sharp';
 
async function generateOGImage(title, outputPath) {
  // 建立 1200x630 的底圖
  const svg = `
    <svg width="1200" height="630" xmlns="http://www.w3.org/2000/svg">
      <rect width="1200" height="630" fill="#1a1a2e"/>
      <text x="100" y="300" font-size="48" fill="#e0e0e0"
            font-family="Noto Sans TC">${escapeXml(title)}</text>
      <text x="100" y="380" font-size="24" fill="#888">
        terryyaowork.github.io
      </text>
    </svg>`;
 
  await sharp(Buffer.from(svg))
    .webp({ quality: 85 })
    .toFile(outputPath);
}
 
// 批次產生所有文章的封面圖
// ...

結果

社群分享的點擊率明顯提升。有封面圖的文章在 Discord/Twitter 分享時,從純文字連結變成有圖片的卡片,視覺吸引力差很多。

第 4 週結果:

指標第 1 週末第 4 週末
404 頁面283142(一半已被 redirect 覆蓋)
已索引新頁面347
搜尋點擊(28 天)218
搜尋曝光(28 天)34890

第 4-8 週:成長 — 監控 + 內容優化 + 結構化資料

目標: 建立持續改善的循環。

結構化資料

在 Quartz 的 layout 裡加入 Schema.org Article markup:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "SEO 不是玄學:工程師該知道的搜尋引擎優化基礎",
  "author": {
    "@type": "Person",
    "name": "Terry Yao"
  },
  "datePublished": "2026-03-15",
  "dateModified": "2026-03-15",
  "image": "https://your-blog.com/covers/seo-01-og.webp",
  "description": "寫了 300 篇文章但 Google 搜不到?..."
}
</script>

FAQ 結構化資料

每篇文章的 FAQ 區塊加上 FAQPage Schema,讓 Google 在搜尋結果直接顯示問答:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "SEO 需要多久才能看到效果?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "通常需要 4-8 週。Google 重新爬取和索引需要時間..."
      }
    }
  ]
}
</script>

AEO 優化

後半段開始用「結論先講」寫法重新整理文章結構,讓 AI 搜尋引擎更容易擷取重點。詳細做法參考 AEO 基礎

建立監控

SEO 監控自動化 裡的方式,每週自動抓 GSC 數據、檢查壞連結、發 Discord 報告。

第 8 週結果:

指標起點第 1 週末第 4 週末第 8 週末
404 頁面28328314223
已索引新頁面0347198
搜尋點擊(28 天)2218127
搜尋曝光(28 天)34348904,200
平均排名N/A68.234.518.7

什麼有效、什麼沒效

有效的做法

做法影響程度花的時間
301 Redirect(舊 URL → 新 URL)極高2 小時
提交 Sitemap5 分鐘
每篇加 title + description + keywords3 小時(批次)
封面圖(OG Image)4 小時(含腳本開發)
結構化資料(Schema.org)2 小時
FAQ 結構化資料內容撰寫時順手加
「結論先講」寫法(AEO)低-中寫作習慣改變

沒效 / ROI 低的做法

做法為什麼沒效
每天手動在 GSC 提交 URLGoogle 有自己的爬取節奏,頻繁提交沒用
瘋狂增加內部連結內部連結有幫助,但過度連結反而稀釋
關鍵字硬塞Google 早就不吃這套了
一次改太多東西沒辦法分辨是哪個改動有效

學到的 5 個教訓

1. 網站搬家不做 Redirect = SEO 死亡

這是最慘痛的教訓。搬家前一定要

  • 列出所有舊 URL
  • 建立舊 URL → 新 URL 的映射
  • 上線第一天就設好 301 redirect
  • 在 GSC 提交新 sitemap + 通知地址變更

2. Sitemap 提交只是開始

很多人以為提交 sitemap 就完事了。Google 會根據自己的優先度決定什麼時候爬你的頁面。你還需要:

  • 確保 sitemap 格式正確(用 GSC 驗證)
  • 確保 sitemap 裡的 URL 都回傳 200
  • 內部連結要把重要頁面串起來

3. 封面圖改善社群分享的 CTR

有封面圖 vs 沒有封面圖的社群分享點擊率差距非常大。我沒有精確數據,但從 Discord 和 Twitter 的回饋來看,有圖的連結被點擊的機率至少高 3 倍。

4. AEO 優化的內容更快被 AI 採用

用「結論先講」+ 清晰的 H2/H3 結構 + FAQ 區塊寫的文章,更容易被 Perplexity 和 ChatGPT Browse 引用。不是因為 AI 有特殊偏好,而是這種結構本來就比較好讀。

5. 持續性比完美更重要

不要想著一次做到完美。先把 redirect 和 sitemap 弄好(止血),然後每週花 30 分鐘看數據、做小改善。8 週下來的累積效果,比一次大改版更穩定。


新部落格 SEO 第一天清單

如果你今天要開始一個新部落格,這是第一天就該做的事:

上線前

  • 選一個乾淨的 URL 結構(/category/post-name,不要日期)
  • 確認靜態網站產生器會產生 sitemap.xml
  • 每篇文章都有 title、description、keywords
  • 每篇文章都有封面圖(OG Image)
  • robots.txt 不要擋重要頁面
  • canonical URL 設定正確

上線當天

  • 到 GSC 註冊並驗證網站
  • 提交 sitemap
  • 到 Bing Webmaster 註冊並提交
  • 確認所有頁面都回傳 HTTP 200
  • 用 PageSpeed Insights 跑一次效能測試

上線後每週

  • 看 GSC 涵蓋範圍報表(有沒有新的錯誤)
  • 看搜尋效能報表(曝光和點擊有沒有成長)
  • 檢查 CWV 分數有沒有變差
  • 發布新內容時確認 frontmatter 完整

上線後每月

  • 跑一次壞連結檢查
  • 更新過時的文章內容
  • 檢查競爭對手的關鍵字排名變化
  • 回顧哪些文章帶來最多流量,寫更多類似主題

最後的話

SEO 不是火箭科學,但也不是設定完就能忘記的東西。它比較像是花園——你要定期澆水、除草、施肥。好消息是,一旦建立了正確的習慣和自動化工具,每週花 30 分鐘就夠了。

這個系列從 SEO 基礎 講到現在的案例分析,涵蓋了一個技術部落格需要知道的所有 SEO 和 AEO 知識。如果你只記得一件事,記得這個:先讓 Google 找到你,再讓 Google 覺得你值得推薦。


FAQ

Q: 從 0 收錄到有穩定搜尋流量要多久?

以我們的經驗,大約 6-8 週開始看到明顯成長。但這取決於你的內容量、更新頻率、和競爭程度。技術部落格的競爭相對低,成長比較快。

Q: 舊站已經下線了,還能做 Redirect 嗎?

可以,但比較麻煩。你需要在新站設定,讓舊 URL 路徑 301 redirect 到新 URL。如果舊站和新站不在同一個 domain,你需要在舊 domain 設定 redirect(前提是你還控制舊 domain)。

Q: 搬家後 Google 索引恢復很慢怎麼辦?

正常。Google 重新爬取需要時間,你可以在 GSC 手動請求檢索重要頁面(每天有限額),但最有效的是確保 sitemap 正確、redirect 正確,然後等。不要急。

Q: 我的文章內容很好但排名就是上不去?

內容品質只是排名因素之一。檢查:技術 SEO 有沒有問題(sitemap、canonical、CWV)?有沒有外部連結(backlinks)?競爭關鍵字的難度是否太高?試著找更長尾的關鍵字切入。

Q: 這個系列的建議適用於非技術部落格嗎?

大部分適用。SEO 的基本原理不分產業。但技術細節(靜態網站產生器、Schema.org 手動設定)比較偏技術。如果你用 WordPress,很多事情用外掛就能完成(Yoast SEO、RankMath)。


本系列文章

  1. SEO 基礎與注意事項
  2. 技術 SEO 實作
  3. 內容 SEO 策略
  4. 網站搬家 SEO
  5. GSC 實戰指南
  6. Open Graph 與社群分享
  7. AEO 基礎
  8. AEO 內容策略
  9. SEO vs AEO 整合策略
  10. Core Web Vitals 效能優化
  11. AEO 監控自動化
  12. 案例:從 0 到被搜到(本篇)