CMS遷移不失SEO:2026完整指南
過去三年,我們將超過 40 個網站從 WordPress 遷移到 headless 架構。有些進行得很順利。有些是痛苦的教訓。決定遷移是否能保留每一滴自然流量,還是會導致排名在六個月內崩潰的因素,歸結於準備,而不是運氣。
這是我們在 Social Animal 客戶說「我們想採用 headless」時實際使用的劇本。這不是理論性的。每個檢查清單項目、每個重定向策略、每個監控步驟都來自我們實際進行的遷移 —— 大多數是 WordPress 到 Next.js,但這些原則適用於任何 CMS 到 CMS 的遷移。
如果您計畫在 2026 年進行遷移,請將此頁加入書籤。您將需要它。
目錄
- 為什麼 CMS 遷移會破壞排名
- 遷移前審計:基礎
- 真正有效的 301 重定向策略
- 規範標籤:被誤解的安全網
- 網站地圖保存和提交
- 技術遷移檢查清單
- WordPress 到 Headless Next.js:分步指南
- 遷移後監控
- 我們看到過的常見錯誤(以及我們犯過的錯誤)
- 常見問題

為什麼 CMS 遷移會破壞排名
Google 不在乎您使用哪個 CMS。它關心的是 URL、內容、頁面速度、內部連結和結構化資料。當您更改 CMS 時,您冒著同時破壞所有這些的風險。
以下是通常出現的問題:
- URL 結構變更 —— WordPress 使用
/2024/03/my-post/或/category/subcategory/post-name/。您的新系統可能使用/blog/post-name。這是數百或數千個破損的 URL。 - 內部連結破損 —— 網站內部從一個頁面指向另一個頁面的每個連結都是為舊的 URL 結構構建的。
- 元資料消失 —— 您的 Yoast 或 RankMath SEO 標題、元描述和 OG 標籤不會神奇地轉移到 headless CMS。
- 結構化資料消失 —— 外掛程式的結構標記在您的新前端中不存在。
- 頁面速度變更 —— 有時會更好(您好,Next.js),有時如果您不小心使用客戶端呈現,會變差。
根據 2025 年 Ahrefs 研究,34% 進行 CMS 遷移的網站經歷至少 10% 的流量下降,持續超過三個月。避免這種情況的網站不是幸運的 —— 他們是有準備的。
遷移前審計:基礎
在您為新平台編寫單一代碼行之前,您需要一份完整的當前 SEO 狀態快照。這不是可選的。跳過這個,您就是盲目飛行。
爬取所有內容
使用 Screaming Frog、Sitebulb 或 Ahrefs Site Audit 對您現有的網站進行完整爬取。您需要:
- 每個 URL(包括分頁頁面、標籤頁面、作者頁面)
- 每個 URL 的 HTTP 狀態碼
- 所有內部連結及其錨文本
- 每個頁面的元標題和描述
- 每個頁面的規範標籤
- 如果您有多語言內容,hreflang 標籤
- 每個頁面的結構化資料
- 圖像 URL 和替代文本
將其匯出到試算表。這是您的遷移聖經。
記錄您的頂級表現者
從 Google Search Console 提取過去 16 個月的資料。識別:
- 按自然點擊數排名前 100 的頁面
- 按曝光數排名前 100 的頁面
- 在高價值關鍵詞的第 1-10 位排名的頁面
- 擁有最多反向連結的頁面(使用 Ahrefs 或 Semrush)
這些是您的 VIP 頁面。它們首先進行測試、首先進行監控,如果出現任何問題,也首先進行修復。
為指標建立基準線
在遷移前的一週記錄這些數字:
| 指標 | 工具 | 為什麼重要 |
|---|---|---|
| 索引頁面總數 | Google Search Console | 快速捕捉解除索引 |
| 自然工作階段/週 | GA4 | 主要成功指標 |
| 平均位置 | GSC | 檢測排名下降 |
| Core Web Vitals | PageSpeed Insights | 效能比較 |
| 引薦網域總數 | Ahrefs/Semrush | 確保反向連結仍然解析 |
| 爬取錯誤 | GSC | 用於比較的基準線 |
| 網站地圖頁面已提交與已索引 | GSC | 追蹤索引健狀況 |
真正有效的 301 重定向策略
這是遷移的生死攸關之地。我見過一些機構將重定向當作事後想法 —— 「在上線後要處理的事」。這就是您在一夜之間失去 40% 流量的方式。
在建置前映射每個 URL
建立一個重定向映射試算表,包含以下欄位:
舊 URL | 新 URL | 狀態碼 | 優先級 | 備註
您的爬取中的每個 URL 都需要一個目的地。是的,包括那些您忘記存在的標籤頁面和作者檔案。
重定向決策框架
| 舊頁面類型 | 建議的動作 | 重定向至 |
|---|---|---|
| 部落格文章(保留內容) | 301 重定向 | 相同內容的新 URL |
| 部落格文章(移除內容) | 301 到最相關頁面 | 相關部落格文章或分類 |
| 分類頁面 | 301 重定向 | 等效的新分類/標籤頁面 |
| 標籤頁面(低價值) | 301 到分類 | 父分類頁面 |
| 作者頁面 | 301 到關於/團隊頁面 | 團隊頁面或首頁 |
| 分頁頁面 (/page/2/) | 301 到主頁面 | 父頁面(第 1 頁) |
| 媒體/附件頁面 | 301 到父文章 | 包含媒體的文章 |
| 舊 WordPress 頁面 (/wp-admin, /xmlrpc.php) | 410 已消失 | N/A |
| Feed URL (/feed/, /rss/) | 301 或重新建立 | 新 Feed URL(如適用) |
在正確的層級實施重定向
對於 Next.js 遷移,您可以選擇重定向的位置:
// next.config.js - 適用於已知的靜態重定向
module.exports = {
async redirects() {
return [
{
source: '/2024/03/my-old-post/',
destination: '/blog/my-old-post',
permanent: true, // 301
},
// 基於模式的重定向
{
source: '/category/:slug',
destination: '/blog/category/:slug',
permanent: true,
},
]
},
}
對於大規模遷移(500+ 重定向),我們通常使用中間件或邊緣函數:
// middleware.ts - 更適合大量重定向映射
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
import redirectMap from './redirects.json'
export function middleware(request: NextRequest) {
const path = request.nextUrl.pathname
const redirect = redirectMap[path]
if (redirect) {
return NextResponse.redirect(
new URL(redirect.destination, request.url),
redirect.permanent ? 301 : 302
)
}
}
export const config = {
matcher: [
// 匹配舊 WordPress URL 模式
'/:year(\\d{4})/:month(\\d{2})/:slug*',
'/category/:path*',
'/tag/:path*',
'/author/:path*',
],
}
對於具有數千個重定向的網站,考慮在 CDN/邊緣級別(Vercel Edge Config、Cloudflare Workers 或 Netlify 重定向檔案)處理它們,以避免膨脹您的應用程式碼。
測試每一個重定向
我是認真的。每一個。我們使用一個簡單的指令碼:
# test-redirects.sh
while IFS=, read -r old_url new_url; do
status=$(curl -o /dev/null -s -w "%{http_code}" -L "$old_url")
final=$(curl -o /dev/null -s -w "%{url_effective}" -L "$old_url")
echo "$status | $old_url -> $final"
done < redirects.csv
在上線前針對您的暫存環境執行此操作。然後在上線後立即在生產環境中再次執行。

規範標籤:被誤解的安全網
規範標籤不是重定向的替代品。但它們是遷移期間的一個重要防禦層。
每個頁面上的自參考規範標籤
您新網站上的每個頁面都應該有一個自參考規範標籤:
<link rel="canonical" href="https://yourdomain.com/blog/exact-current-url" />
在 Next.js with App Router 中:
// app/blog/[slug]/page.tsx
import { Metadata } from 'next'
export async function generateMetadata({ params }): Promise<Metadata> {
const post = await getPost(params.slug)
return {
alternates: {
canonical: `https://yourdomain.com/blog/${params.slug}`,
},
}
}
遷移期間的常見規範標籤錯誤
- 尾部斜杠不一致 ——
/blog/post和/blog/post/對 Google 來說是不同的 URL。選一個,重定向另一個,並確保您的規範標籤匹配。 - 規範標籤中的 HTTP 與 HTTPS —— 始終使用 HTTPS。聽起來很明顯,但我見過它出錯。
- 暫存 URL 洩露到生產中 —— 如果您的規範標籤指向
staging.yourdomain.com,您告訴 Google 索引您的暫存網站。我們在 QA 中捕捉到這種情況的次數比我願意承認的要多。 - 在分頁內容上缺少規範標籤 —— 如果您對部落格清單進行分頁,每個頁面需要自己的規範標籤,而不是指向第 1 頁的規範標籤。
網站地圖保存和提交
立即產生新網站地圖
您的新網站地圖應在第一天準備好。對於 Next.js 專案,我們動態產生網站地圖:
// app/sitemap.ts (Next.js 14+/15)
import { MetadataRoute } from 'next'
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const posts = await getAllPosts() // 來自您的 headless CMS
const blogEntries = posts.map((post) => ({
url: `https://yourdomain.com/blog/${post.slug}`,
lastModified: new Date(post.updatedAt),
changeFrequency: 'weekly' as const,
priority: 0.8,
}))
const staticPages = [
{
url: 'https://yourdomain.com',
lastModified: new Date(),
changeFrequency: 'daily' as const,
priority: 1,
},
// ... 其他靜態頁面
]
return [...staticPages, ...blogEntries]
}
提交策略
- 遷移前:下載您的舊網站地圖並保存
- 遷移後:立即在 Google Search Console 中提交新網站地圖
- 暫時保留舊網站地圖:在前 30 天內,讓您的舊網站地圖 URL 正確重定向,以便 Google 可以跟隨鏈
- 使用 Google 的 URL 檢查工具:手動要求索引前 50 個 VIP 頁面
- 每天監控索引覆蓋報告 前兩週內
不要忘記 robots.txt
您的新 robots.txt 需要:
- 允許 Googlebot 爬取它之前可以爬取的所有內容
- 指向您的新網站地圖位置
- 不要意外封鎖 Next.js 需要用於呈現的 JS/CSS 檔案
User-agent: *
Allow: /
Sitemap: https://yourdomain.com/sitemap.xml
技術遷移檢查清單
這是我們實際使用的檢查清單。列印出來、層壓它、刺在您的手臂上 —— 任何有效的方式。
上線前(上線前 2-4 週)
- 完成現有網站的完整爬取並匯出到試算表
- 按流量和反向連結識別頂級頁面
- 已建立並檢查完整重定向映射
- 最終確定新 URL 結構(此後不進行任何更改)
- 元標題和描述已遷移到新 CMS
- 在新網站上實施結構化資料 (JSON-LD)
- 已實施 Open Graph 和 Twitter Card 標籤
- 內部連結已更新以使用新 URL 結構
- 圖像替代文本已遷移
- 規範標籤已在每個範本上驗證
- 已實施 Hreflang 標籤(如果多語言)
- robots.txt 已檢查
- 新網站地圖正確產生
- 已建立 404 頁面,包含有用的導航
- Core Web Vitals 在暫存上透過
- 已安裝分析和追蹤程式碼
- 為新網域/子網域驗證 GSC(如果更改)
上線日
- DNS 變更已傳播
- SSL 憑證有效
- 所有重定向都已測試並驗證
- 新網站地圖已提交到 GSC
- 手動為前 20 個頁面要求索引
- 煙霧測試:隨機檢查 50 個舊 URL 以驗證正確的重定向
- 驗證規範標籤中沒有暫存 URL
- 驗證生產頁面上沒有
noindex標籤 - 檢查伺服器回應時間(應低於 200ms TTFB)
上線後(前 30 天)
- 每日 GSC 監控爬取錯誤
- 每週與基準線比較自然流量
- 監控索引覆蓋報告是否下降
- 在 GSC 中檢查軟 404
- 驗證反向連結是否正確解析(隨機檢查前 20 個)
- 監控欄位資料中的 Core Web Vitals
- 解決 GSC 中出現的任何新 404
WordPress 到 Headless Next.js:分步指南
這是我們最常見的遷移途徑。以下是我們在 headless CMS 開發專案 上進行工作時的方法。
選擇您的 Headless CMS
您正在離開 WordPress —— 單體,但您可能會將 WordPress —— CMS 作為 headless 後端,或者您可能會遷移到完全不同的東西。
| CMS | 最適合 | 內容遷移工作量 | 定價 (2026) |
|---|---|---|---|
| WordPress (headless via WPGraphQL) | 熟悉 WP 的團隊 | 最少 —— 內容保持不變 | 僅託管成本 |
| Sanity | 結構化內容、開發人員團隊 | 中等 —— 需要匯出/匯入 | 免費層,然後 $99+/月 |
| Contentful | 企業、多頻道 | 中等到高 | 免費層,然後 $300+/月 |
| Strapi | 自託管控制 | 中等 | 免費(自託管)或 $29+/月雲端 |
| Payload CMS | Next.js 原生、TypeScript 團隊 | 中等 | 免費(自託管)或 $35+/月雲端 |
如果您使用 WordPress 作為 headless 後端,您完全避免了內容遷移問題。我們使用 Next.js 開發專業知識 構建了多個網站 —— 編輯團隊保留了他們的 WordPress 管理員,前端是一個超快速的 Next.js 應用。
內容遷移指令碼
如果您要遷移到新的 CMS,您將需要一個遷移指令碼。以下是我們用於從 WordPress 提取內容的簡化版本:
// scripts/migrate-wp-to-sanity.ts
import WPAPI from 'wpapi'
import { createClient } from '@sanity/client'
const wp = new WPAPI({ endpoint: 'https://old-site.com/wp-json' })
const sanity = createClient({
projectId: 'your-project',
dataset: 'production',
token: process.env.SANITY_TOKEN,
apiVersion: '2026-01-01',
})
async function migratePosts() {
let page = 1
let hasMore = true
while (hasMore) {
const posts = await wp.posts().page(page).perPage(100)
for (const post of posts) {
await sanity.create({
_type: 'post',
title: post.title.rendered,
slug: { current: post.slug },
// 將 WP HTML 轉換為 Portable Text 或 MDX
body: convertHtmlToPortableText(post.content.rendered),
publishedAt: post.date,
// 保存舊 URL 以進行重定向映射
legacyUrl: new URL(post.link).pathname,
seo: {
metaTitle: post.yoast_head_json?.title || post.title.rendered,
metaDescription: post.yoast_head_json?.description || '',
},
})
}
hasMore = posts._paging?.totalPages > page
page++
}
}
大多數遷移指南遺漏的關鍵細節:在新 CMS 中保存舊 URL 作為字段。這使得重定向產生變得微不足道,並為您提供了內容來自何處的永久記錄。
結構化資料遷移
WordPress 外掛程式(如 Yoast)會自動產生結構化資料。在 Next.js 中,您需要自己實施:
// components/ArticleSchema.tsx
export function ArticleSchema({ post }) {
const schema = {
'@context': 'https://schema.org',
'@type': 'Article',
headline: post.title,
datePublished: post.publishedAt,
dateModified: post.updatedAt,
author: {
'@type': 'Person',
name: post.author.name,
},
publisher: {
'@type': 'Organization',
name: 'Your Company',
logo: {
'@type': 'ImageObject',
url: 'https://yourdomain.com/logo.png',
},
},
image: post.featuredImage?.url,
description: post.excerpt,
}
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>
)
}
不要忘記 BreadcrumbList、FAQPage 和您的 WordPress 網站產生的任何其他結構化資料類型。在遷移前後使用 Google 的富文本結果測試進行檢查。
遷移後監控
遷移後的前 48 小時至關重要。以下是要監控的內容:
前 48 小時
- 監控伺服器日誌中的 404s 實時。每個 404 都是一個遺漏的重定向。
- 使用 GSC 的 URL 檢查工具檢查您的 VIP 頁面 —— 它們正在被重新爬取嗎?
- 監控您的 CDN/託管是否出現意外流量峰值或下降。
前 2 週
一些排名波動是正常的。Google 需要重新爬取並重新處理您的整個網站。不正常的是:
- 持續超過 5 天的流量下降超過 15%
- VIP 頁面失去超過 3 個位置
- 索引覆蓋下降超過 10%
如果您看到這些中的任何一個,首先檢查您的重定向。然後檢查是否有意外的 noindex 標籤。然後檢查您的內容是否確實呈現(Next.js 中的 SSR 問題可能會為 Googlebot 提供空頁面)。
前 3 個月
設定每週自動化報告,比較:
- 自然流量周同比
- 前 50 個關鍵詞的平均位置
- 索引頁面數量
- Core Web Vitals 分數
根據我們的經驗,執行良好的遷移在 2-4 週內看到流量恢復到基準線,並且通常在 8 週內超過基準線,這得益於 Next.js 效能優勢帶來的改進 Core Web Vitals。
我們看到過的常見錯誤(以及我們犯過的錯誤)
同時更改 URL 結構和內容。 不要這樣做。按原樣遷移您的內容,上線,讓 Google 穩定,然後稍後優化內容。同時更改太多信號會使診斷問題變得不可能。
忘記圖像。 如果您的圖像來自 yourdomain.com/wp-content/uploads/,現在它們在 CDN 上,具有不同的 URL,每個指向您的圖像的外部網站上的每個圖像連結都被破壞了。也重定向這些路徑。
尾部斜杠處理不一致。 Next.js 有一個 trailingSlash 組態選項。選擇 true 或 false,並確保每個重定向、規範標籤和網站地圖條目都相符。
在星期五上線。 只是別這樣做。在週二或週三早上上線,這樣您就有整整一週的時間來監控和修復問題。
沒有告訴 Google 有關遷移的信息。 如果您更改網域,請使用 GSC 的「位址變更」工具。即使停留在同一網域上,也要重新提交您的網站地圖並使用「移除」工具清除不應被索引的任何舊 URL。
如果您對所有這些感到不知所措,這是可以理解的 —— 這確實是複雜的工作。我們的團隊定期處理這些遷移,我們很樂意討論您的具體情況。
常見問題
Google 識別 301 重定向需要多長時間? Google 通常在幾天到兩週內發現並處理 301 重定向,具體取決於 Googlebot 爬取您的網站的頻率。具有大量反向連結的高權限頁面傾向於更快被重新爬取。您可以通過提交更新的網站地圖和使用 URL 檢查工具要求重新爬取關鍵頁面來加快速度。
我會從 301 重定向損失連結權重(連結果汁)嗎? Google 自 2016 年以來已確認 301 重定向傳遞完整連結權重。不再有 PageRank 重定向稅。但是,重定向鏈 (A → B → C) 可能會減慢轉移並導致爬蟲預算問題。盡可能保持單跳重定向。
在遷移期間我可以使用 302 重定向而不是 301 嗎? 不。對遷移使用 301(永久)重定向。302 告訴 Google 移動是暫時的,它應該將舊 URL 保留在其索引中。這直接與您在 CMS 遷移期間想要的相反。唯一的例外是如果您真的計畫還原 —— 但如果您要遷移 CMS,您就不會回頭。
Next.js 有多少 301 重定向太多了?
Next.js 在 next.config.js 中很好地處理大約 1,000 個條目的重定向。超過這個,您會想要使用中間件、邊緣函數或在 CDN 級別處理重定向。Vercel 的 Edge Config 可以以亞毫秒查詢時間處理數以萬計的重定向。對於自託管 Next.js,考慮在中間件中使用 Redis 支援的重定向查詢。
我應該重定向 WordPress 標籤和作者頁面嗎? 是的,但要有戰略性。如果您的標籤頁面有大量流量或反向連結,請將其重定向到新網站上最相關的等效頁面。如果它們是流量為零的瘦內容頁面(大多數 WordPress 標籤頁面都是這樣),請將它們重定向到父分類或部落格索引。作者頁面通常應重定向到關於頁面或團隊頁面。
遷移後我的 Google 商家檔案和其他引用會發生什麼? 如果您的網域保持不變,大多數引用和您的 Google 商家檔案都不會受到影響。但是,如果列出了特定 URL(例如服務頁面),請確保這些重定向正確。在遷移後的第一週內更新 Google 商家檔案、社群媒體個人資料和主要目錄清單中的任何 URL。
遷移到 headless WordPress 還是不同的 headless CMS 更好? 這取決於您的團隊。如果您的內容編輯者喜歡 WordPress,且您的內容模型適合 WordPress 很好,使用 WordPress 作為帶有 WPGraphQL 的 headless 後端可消除內容遷移風險。如果您遇到了 WordPress 內容建模的限制,或者想要更現代的編輯體驗,Sanity、Payload CMS 或 Contentful 是強大的替代品。我們在 headless CMS 開發頁面 上進一步細分了選項。
在 CMS 遷移期間如何處理多語言內容?
多語言遷移增加了另一層複雜性。您需要完全按照之前的方式保留 hreflang 標籤,將每個語言版本重定向到其對應的新 URL,並確保您的新 CMS 支援相同的語言/地區結構。如果您要從子目錄 (/es/、/fr/) 切換到子網域或反之亦然,這對於每種語言基本上都是網域更改,需要額外注意重定向和 GSC 組態。