把六年的 WordPress 改成自架-免年費、超高自由度,完整 Prompt 分享
從決定不續約主機,到 DNS 切換完成的完整遷移紀錄:用 Astro + Vercel 重建雙語部落格,圖片搬 Cloudinary,留言系統換 Supabase,順手設計了一套發文流程。
搬了三個月,但其實純搬站只要一週——我把完整 prompt 都留在這篇了。
這篇文章記錄我把 ijuhsu.com 從 WordPress 搬到 Astro 的完整過程。從 2026 年 4 月開始有空就動工,7 月 4 日 DNS 切換完成,前後三個月含重新設計;但如果只是單純搬站不重新設計,一週內可以解決。
一共 260 篇文章、雙語(繁中+英文)、自訂留言系統、800 多張圖片——如果你也想要脫離 Hosting 以及更大的自由度,希望這篇能幫你少走幾條彎路 ;)
門檻說明:懂基本終端機操作(
cd、npm run)就夠了,不需要會寫程式——Claude Code 負責所有程式碼,你負責判斷對不對。
為什麼要搬?
許 i 啾不認真這個網站出生於 2020 年,感謝 Selena 當初教我怎麼透過 Wordpress 架站 :D
原本用 A2 Hosting 的共享主機跑 WordPress,三年方案 $503 美金,2027 年 5 月到期;
不過其實遇到了不少問題…
- 費用 - $503 美金在當時是必要的費用,但現在 AI 時代來看,會去思考是否還有需要 Hosting 的必要
- 龐大的外掛 - 我的外掛裝到 14 個——SEO、多語言、圖片壓縮、備份、防火牆、社群發文……每個外掛都有設定頁,互相衝突的問題三不五時就出現Q_Q 有時只是想改個版面樣式,卻要先搞清楚 OceanWP 主題覆蓋了哪些 CSS…
- 自由度 - 仍然會有很多被 Wordpress 包住的限制
近來幾個用 AI 自己架站的 Side Projects,發現架站其實並不是那麼困難;
尤其我的發文頻率低(:P),成本也超~級低,所以不禁起了自己架站的想法。
和 Claude Code 討論了一陣子後,選擇了使用 Astro 為架構做了幾篇實測文--靜態輸出 + Vercel 免費方案,幾乎零主機成本;
也完美解決了我之前遇到的幾個問題,就開始找假日的時間來搬啦!
技術
以下是我目前架構起來後和 Claude Code 一起討論出來的內容,給大家參考:
- Astro + Vercel:靜態輸出部署到 Vercel,免費方案完全夠用。Astro 原生支援 MDX,content collection 讓文章管理乾淨,改版型只要改
.astro元件和 CSS,不用碰任何後台設定; - Cloudinary:圖片 CDN,自動轉 WebP、按尺寸裁切,不用在 Astro 裡跑
<Image />轉檔。也定好命名規則,之後圖片管理清爽很多; - Supabase:取代 WordPress 的留言系統,直接存進 PostgreSQL;補上了 Cloudflare 的認證機制來避免惡意留言;
- Telegram Bot:留言的核准/刪除/回覆全部透過 Telegram 按鈕操作,不需要建 admin 後台。
搬家流程
Phase 0:架基礎
先請 Claude Code 協助將 Astro 的骨架搭起來再說。
首先是設計,我其實也參考了不同的設計風格,不過因為我的需求是:有日常也有專業的內容,所以希望有兩套不同的 Design System 可以明顯看出兩者區別;
同時我也希望保留我一點插畫風格,所以決定先以這種簡單的設計上架。
- Casual 日常路線,採用原本網站的色系設計並保有一些遊戲的元素,採用 non-serif 的字型;
- Pro 專業路線,採用期刊風格,找個相關的色系(深綠)並搭配網格,採用 serif 的字型。
另外則是網站架構,除了雙類型、雙設計外,也有雙語的設置(我許多遊戲攻略讀者是海外人士XD),因此也需要把 URL 結構弄好--
繁中預設無前綴,英文加 /en/,對 SEO 影響最大的決定都在這邊定好。
所有內容都是在 Claude Code 建好後 npm 驗證,push 上 Github,Vercel 就會自動 Deploy。
特別建議: 在一開始計畫時選較高的模型(我選 Fable 或 Opus),然後再請 Sonnet 執行,會快很多哦!
Claude Code Prompt(Phase 0):
我要把 WordPress 部落格搬到 Astro。請幫我:
1. 建立 Astro 5 骨架,支援 MDX content collection
2. 設計雙語:繁中無前綴(/posts/slug),英文 /en/posts/slug
3. Layout:(自由決定)
4. 部署目標:Vercel 靜態輸出
先給我架構規劃與資料夾結構,確認後再開始寫程式。
Phase 1:搬圖片
搬圖片本來以為是複雜的事情,沒想到比想像中簡單:845 張圖片,Claude Code 寫了一支 migrate-images.mjs 的腳本:
- WP REST API 批次抓媒體庫
- 直接用 URL 上傳到 Cloudinary(省掉下載再上傳的步驟)
- 輸出 WP URL → Cloudinary public ID 的對照表
Claude Code Prompt(Phase 1):
幫我寫 migrate-images.mjs,把 WordPress 媒體庫批次搬到 Cloudinary:
1. 用 WP REST API 逐頁抓所有圖片
2. 直接用圖片原始 URL 上傳到 Cloudinary(不需下載到本機)
3. 輸出 JSON 對照表
Cloudinary 命名規則:/{slug}-{nn}(nn 兩位數流水號)
WP 網址:https://my-site.com
Cloudinary 憑證從環境變數讀取(CLOUDINARY_CLOUD_NAME / API_KEY / API_SECRET)
大約一兩個小時全部跑完,共 845 張,842 張成功,3 張 404(WP 那邊的孤兒QQ),成功率很高,讚讚。
Phase 2:轉 MDX
這也是靠 Claude Code 把六年來的 147 篇 WP 文章,寫了 migrate-posts.mjs 腳本(最終 260 篇是加上英文翻譯與 Astro 上線後新增的文章):
- WP REST API 抓 HTML 文章內容
- HTML → Markdown(用 turndown)
- 替換圖片 URL → Cloudinary 格式
- 輸出帶完整 frontmatter 的 MDX 檔案
Claude Code Prompt(Phase 2):
幫我寫 migrate-posts.mjs,把 WordPress 文章批次轉成 Astro MDX:
1. WP REST API 逐頁抓所有文章
2. HTML 內容用 turndown 轉 Markdown
3. 圖片 URL 用 migrate-images 產生的對照表替換成 Cloudinary 格式
4. 輸出 MDX 含 frontmatter:title, description, pubDate, lang, slug, category
需清理:WP shortcode、[caption] 標籤、TOC 外掛殘留 HTML、Elementor markup
輸出路徑:src/content/posts/zh/
最麻煩的是 WP HTML 裡各種外掛殘留:shortcode、TOC 區塊、Elementor page builder markup,每種都要寫一條 regex 清掉。
腳本跑完之後,還需要人工審查分類——最後有 50 篇重新分類。
這目前仍有不少 legacy 需要調整,但大部分的文章都算穩定了
Phase 3:翻譯補全
當初 WP 的英文文章很零散——有些在 zh 資料夾裡、有些有翻有些沒翻。
全部整理好、補齊 126 篇的英文翻譯,用 translate-zh-to-en skill 輔助,每篇仍需人工確認——英文版由 AI 輔助翻譯,若發現問題歡迎留言告知。
這比較要注意的是如果在翻譯的部分有需要特別標記的,例如:樂透要翻成「Lottery」,也要在 skills 都補上。
Claude Code Prompt(Phase 3):
把 src/content/posts/zh/my-post.mdx 翻成英文 MDX,存到 src/content/posts/en/。
- translationKey 和 zh 版完全一致
- 語氣保持原文風格,不要過度正式化
- 專有名詞、工具名(Astro、Cloudinary 等)不翻
- 有特殊翻譯規則的詞先列出來(例:「樂透」→「Lottery」)
Phase 4:留言移轉
一共有 326 筆 WP 留言,Claude Code 寫了 migrate-wp-comments.mjs 兩段式匯入:
先插頂層留言、再插回覆(保留 parent_id 巢狀結構)。
其實有些人家已經寫好的外掛,但有些只限 Github 帳號才能使用;我很多讀者都沒有;有些要付費。
後來研究了一下便以 Supabase 為後端,把內容架,並加入 Cloudflare Turnstile 補強,這樣就可以省去許多惡意留言。
我也補上了 Telegram 來通知我留言、審核留言並回覆留言的功能,這樣就不需要進後台處理了!
Claude Code Prompt(Phase 4):
幫我寫 migrate-wp-comments.mjs,把 WordPress 留言匯入 Supabase。
Supabase 資料表欄位:id, post_slug, parent_id, author_name, content, created_at, approved
流程:
1. WP REST API 抓所有已核准留言
2. 兩段式插入:先插頂層留言(parent=0),取得新 id 後再插回覆(對應 parent_id)
3. post_slug 從留言的 link 欄位解析
Supabase 連線從環境變數讀取(SUPABASE_URL、SUPABASE_SERVICE_KEY)
Phase 5:SEO / Redirects
這一步很容易被跳過,但最重要。WP 的舊 URL 要全部 301 到新 URL,不然 Google 要重新爬,累積的排名白白損失 ;_;
Claude Code 幫我從文章清單程式化產出 262 條 redirect 規則,直接寫進 astro.config.mjs。
另外補了 JSON-LD schema、hreflang 互指、自訂 404、llms.txt。
P.s. 我還有自己架好的 404 頁面哦:D
Claude Code Prompt(Phase 5):
我的 WP 舊 URL 格式有:(請自行列出)
新 URL 格式:/posts/{slug}(繁中),/en/posts/{slug}(英文)(請根據你的來修正)
請讀 src/content/posts/zh/*.mdx 的 frontmatter,
產生 astro.config.mjs 的 redirects 陣列,每篇文章的三種舊格式都要 301 對應到新 slug。
同時幫我補上:
- hreflang 互指(zh ↔ en)
- JSON-LD Article schema
- sitemap(@astrojs/sitemap)
- 自訂 404 頁面
正式搬家啦!DNS 切換
在大致都驗證好、也把該有的圖和內容補好後,2026/07/04 正式搬家啦!
因為原本就有用 Cloudflare,就去刪掉 A2 Hosting 的 A record,改 CNAME 指向 Vercel,設 DNS only 讓 Vercel 自動簽 SSL。
切完之後記得手動更新兩件事:
- Cloudflare Turnstile 的允許網域
- Telegram webhook URL(
https://api.telegram.org/bot{TOKEN}/setWebhook) 就可以正式上線了:D
上線後踩坑:Google 索引的舊 URL
以為設好 redirect 就沒事了,結果上線後發現 analytics 還是有 404——原因是 Google 搜尋結果裡存著 WP 時代的各種舊 URL,而這些不是只有「舊文章網址」而已。
幾個沒預期到的坑:
1. WP 的 en slug 會自動加 -2
WP 的機制是:中英文是兩篇獨立文章,如果 slug 一樣,後建的那篇會在後面補 -2。所以英文文章的 Google 索引 URL 可能長這樣:
/en/n8n-learningjapanese-2/ ← 不是 slug 本名,是 WP 自動加的
/en/phd2uxr-2/
這類 URL 有 130+ 篇,要全部補 redirect。
2. WP 的特殊頁面和分類
WP 的 tag 頁是 /tag/:tag/,Astro 我用的是 /tags/:tag/(多一個 s);
聯絡頁是 /contact/,Astro 沒有,要導到 /about/;
舊分類頁 /category/:cat/ 也要導到新的 /:cat/。
怎麼找到漏網之魚?
Google Search Console 的「未找到 (404)」報告是第一線;
另外在 Google 搜 site:你的網域 也能看到被索引的舊頁面,逐一比對是否還能正常打開。
最後我的 vercel.json 從預計的 262 條規則,補到了 844 條。設好 301 redirect 後,等 Google 爬蟲重訪,舊排名就會轉移到新 URL 了。
現在的架構
ijuhsu.com(Vercel,靜態 + serverless API)
├── 內容:~260 篇 MDX(zh + en)
├── 圖片:Cloudinary(自動 WebP + resize)
├── 留言:Supabase + Cloudflare Turnstile(防機器人)
├── 通知管理:Telegram Bot
└── 搜尋:Fuse.js 客戶端模糊搜尋
發文現在也有兩種流程:短文用 Telegram 發到 n8n → GitHub Actions 自動 commit 草稿 MDX(可見聰明透透這篇的流程,我把權限開到可以編輯文章!);
長文還是 Claude Code 一條龍(收稿 → 圖片上傳 → 事實查核 → 翻譯 → 上線)。
速度變快了多少?
之前的痛點就是 PageSpeed 數字一直很差,在 WP 想要改善都沒有什麼用;搬家後比較自由,一上線後就實測 PageSpeed Insights,電腦版:
| 指標 | WordPress 時期 | Astro + Vercel |
|---|---|---|
| PageSpeed 電腦版 | 無法重測(已下線) | 99 / 100 |
| PageSpeed 行動版 Lighthouse | 一直調不好(估計 30–50) | 55 / 100 |
| LCP 電腦版 | — | 0.9 秒 |
| FCP 電腦版 | — | 0.7 秒 |
行動版 Lighthouse 55 不夠理想,但背景是「慢速 4G 節流」模擬(1.6 Mbps),而且 CJK 字型(Noto TC)固有偏重;Claude Code 認為台灣用戶實際在 WiFi / 4G 上的體驗跟桌機接近,所以就大致維持這樣了。WP 時期在 A2 Hosting 共享主機跑的分數更低——PHP 處理時間 + 14 個外掛的 JS,加在一起更慘。
搬到 Astro 後還做了幾項最佳化:
- Google Fonts 改非同步載入
- 文章內 Cloudinary 圖片補 srcset(480/800/1200/1600w)+ lazy loading
- 遊戲首頁 sprite PNG → WebP(3.2 MB → 560 KB)
這些都大大改善了網站的表現 :D
搬家值得嗎?
| 面向 | WordPress + A2 Hosting | Astro + Vercel |
|---|---|---|
| 主機費用 | $503 美金 / 3 年 | 免費(Vercel Hobby) |
| 外掛依賴 | 14 個(SEO、備份、防火牆…) | 0 |
| 改版方式 | WP 後台 + 主題 CSS 覆寫 | 直接改 .astro 元件 |
| 部署流程 | FTP / WP 後台手動更新 | git push → 自動部署 |
| 文章儲存 | MySQL 資料庫 | MDX 純文字,git 版控 |
| 圖片處理 | WP 外掛(Smush 等) | Cloudinary 自動 WebP + resize |
| 留言管理 | WP 後台審核 | Telegram 按鈕一鍵核准 |
| PageSpeed 電腦版 | 估計 30–50(難調整) | 99 / 100 |
| PageSpeed 行動版 | 更差 | 55 / 100 |
| 自訂彈性 | 受主題與外掛限制 | 完全自由 |
省了超多的主機費用,網站設計及版型想改隨時改,不用再擔心外掛版本衝突;
文章寫作沒有像之前那麼視覺化,因為就是 git 管的純文字檔;
但是如果習慣 markdown 的寫作其實比上 WP 寫得更快。
代價是工時——時長約三個月,但主要是因為我只是有空才搬(我方案明年才到期,而且也在忙其他的網站如《LinguaPass》 XD),
Claude Code 我也是用 Pro 而已,只要 limit 一到我就跑去做別的事XD
如果你的文章只有 20–30 篇,直接用 WordPress.com 真的就可以了; 但 260 篇、雙語、想要完全自訂——我覺得超值得,可以把樂透放得更多,完美XD。
WP → Astro 搬家 Checklist
按照這個順序走,不容易漏掉東西:
事前準備
- 確定技術架構(Astro 版本、部署平台)
- 設計 URL 結構(語言前綴、slug 格式)——這個決定最難改,要先定好
- 申請 Cloudinary / Supabase 帳號(若要自架留言)、取得 API Key
Phase 0:架基礎
- Astro 骨架 + content collection schema
- 雙語路由設定
- Layout 元件(含雙設計系統如有)
- 部署到 Vercel,確認 CI/CD 流程跑通
Phase 1:搬圖片
- 寫腳本批次上傳 WP 媒體庫到 Cloudinary
- 輸出 WP URL → Cloudinary publicId 對照表
- 確認對照表完整(check 404 孤兒圖)
Phase 2:轉文章
- 寫腳本 WP REST API → turndown → MDX
- 清理外掛殘留(shortcode、Elementor markup、TOC HTML)
- 替換圖片 URL(用 Phase 1 的對照表)
- 人工審查分類,重新分配 category
Phase 3:翻譯
- 整理現有英文版,補齊 translationKey 配對
- 批次翻譯(Claude Code 輔助)
- 每篇人工確認語氣與專有名詞
Phase 4:留言
- 建立留言資料表(Supabase)
- 寫腳本兩段式匯入(先頂層、再回覆)
- 設定 Cloudflare Turnstile 防機器人
- 設定 Telegram Bot 審核通知
Phase 5:SEO / Redirects
- 程式化產生 301 redirect 規則(舊 WP URL → 新 slug)
- hreflang 互指標記(雙語)
- JSON-LD Article schema
- sitemap + robots.txt
- 自訂 404 頁面
DNS 切換
- 在新平台完整驗證(所有連結、圖片、留言)
- 刪除舊 A record,CNAME 指向 Vercel
- Cloudflare Turnstile 更新允許網域
- Telegram webhook URL 更新
- 確認 SSL 自動簽發
你也想要從 WP 轉成自架網站看看嗎? 有什麼搬家相關的問題歡迎留言,或是從關於頁面找到我的 Facebook / LinkedIn 聯絡我 😊
p.s. 有人找得到網站中的小彩蛋嗎:p
留言