使用 Cursor AI 轉換 Ghost CMS 樣板到 Next.js

為何選擇 Next.js 搭配 Headless Ghost CMS?

在現代網站開發的浪潮中,Headless CMS 架構因其靈活性、效能和可擴展性而備受推崇。Ghost 作為一個功能強大且專注於內容的 CMS,採用 Headless 模式可以讓您將其卓越的內容管理功能與任何前端框架結合。Next.js 作為領先的 React 框架,以其伺服器端渲染 (SSR)、靜態網站生成 (SSG)、優化的圖片處理和卓越的開發體驗而聞名。

Ghost 作為 Headless CMS,並選擇 Next.js 建構前端,再部署於高效能平台 Vercel,您可以獲得以下優勢:

  • 極致效能Next.jsSSGSSR 功能可顯著提升載入速度和 SEO 表現。
  • 開發彈性:完全掌控前端的技術棧和使用者體驗。
  • 現代化工作流程:利用 React 生態系統和 Next.js 的先進功能。
  • 無縫部署Vercel 提供與 Next.js 的完美整合,簡化部署流程。

然而,從現有的 Ghost 主題(通常基於 Handlebars 模板引擎)遷移到 Next.js(基於 React)可能是一項繁瑣的任務。這正是 AI 輔助工具 Cursor 發揮作用的地方。Cursor 能夠理解程式碼上下文,並根據自然語言指令生成、編輯和重構程式碼,大幅加速轉換過程。

準備工作:開始轉換前的必要條件

在我們深入探討使用 Cursor 轉換的步驟之前,請確保您已具備以下條件:

  1. Node.js 與 npm/yarn:確保您的開發環境已安裝最新穩定版的 Node.js 和套件管理器(npm 或 yarn)。
  2. Cursor 編輯器:下載並安裝 Cursor AI 編輯器。熟悉其基本操作介面,特別是 AI 聊天和程式碼生成功能。
  3. Ghost CMS 主題檔案:準備好您想要轉換的 Ghost 主題的完整原始碼檔案(通常包含 .hbs 檔案、CSS/JS 檔案、圖片等)。
  4. 基本的 Next.js 知識:對 Next.js 的專案結構、元件、路由和資料獲取方法(getStaticProps, getServerSideProps)有基本了解。
  5. Ghost Content API 金鑰:登入您的 Ghost 管理後台,前往 Integrations,建立一個新的 Custom Integration,並取得 Content API KeyAPI URL。這是 Next.js 前端獲取內容所必需的。
  6. 版本控制 (Git):強烈建議使用 Git 進行版本控制,以便追蹤變更並在需要時回滾。

步驟一:初始化 Next.js 專案

首先,我們需要建立一個新的 Next.js 專案作為轉換後程式碼的基礎。

打開您的終端機(Terminal),執行以下指令(我們推薦使用 create-next-app):

npx create-next-app@latest my-headless-ghost-frontend --typescript
# 或如果您偏好 JavaScript:
# npx create-next-app@latest my-headless-ghost-frontend

這將建立一個名為 my-headless-ghost-frontend 的新資料夾,其中包含基本的 Next.js 專案結構。進入該目錄:

cd my-headless-ghost-frontend

接著,使用 Cursor 打開這個新建立的專案資料夾。

步驟二:在 Cursor 中設定轉換環境

Cursor 中打開您的 Next.js 專案後,我們可以開始利用其 AI 功能。

  1. 熟悉介面:確保您知道如何與 CursorAI 互動,例如透過 Cmd+K (Mac) 或 Ctrl+K (Windows/Linux) 來編輯選定程式碼,或使用側邊欄的聊天功能進行更廣泛的查詢和程式碼生成。
  2. 導入 Ghost 主題檔案:將您準備好的 Ghost 主題檔案複製到 Next.js 專案中的某個臨時資料夾(例如,ghost-theme-source),以便在 Cursor 中輕鬆存取和參考。

步驟三:核心轉換 - 將 Handlebars (.hbs) 轉換為 React 元件 (.jsx/.tsx)

這是轉換過程中最關鍵的部分。Ghost 主題使用 Handlebars (.hbs) 檔案來定義頁面結構和模板。我們需要將這些檔案轉換為 Next.js 使用的 React 元件(.jsx.tsx)。

  1. 識別主要佈局檔案:在您的 Ghost 主題中,通常會有一個主要的佈局檔案(例如 default.hbs),它定義了網站的整體結構(頁首、頁尾、主要內容區域)。

  2. 在 Cursor 中轉換 default.hbs

    • Next.js 專案中,建立一個 components 資料夾,並在其中建立一個 Layout.tsx (或 .jsx) 檔案。
    • 打開 ghost-theme-source/default.hbs 檔案。
    • 選取 default.hbs 的全部或部分內容。
    • 按下 Cmd+K / Ctrl+K,然後輸入類似以下的 AI 指令:

      “將這段 Handlebars 程式碼轉換為一個名為 Layout 的 React functional component (使用 TypeScript 和 JSX)。將 {{{body}}} 替換為 children prop。保留 HTML 結構和 CSS class。”

    • Cursor 將會生成對應的 React 元件程式碼。仔細檢查生成的程式碼,可能需要手動調整,特別是 Handlebars 的特定 helpers 或 partials。例如,{{@site.title}}{{navigation}} 需要後續透過 Ghost Content API 獲取資料來填充。
  3. 轉換其他模板檔案 (index.hbs, post.hbs, page.hbs 等)

    • 根據 Next.js 的路由規則,在 pages 資料夾下建立對應的檔案。例如:
      • index.hbspages/index.tsx
      • post.hbspages/posts/[slug].tsx (動態路由)
      • page.hbspages/[slug].tsx (或根據您的 URL 結構調整)
    • 對於每個 .hbs 檔案,重複上述轉換過程:選取 Handlebars 程式碼,使用 Cursor AI (Cmd+K / Ctrl+K) 進行轉換。
    • 範例 AI 指令 (針對 post.hbs)

      “將此 Handlebars 模板轉換為一個 React functional component,用於顯示單篇文章。假設文章資料將透過 props 傳入 (例如 props.post)。將 Handlebars 變數如 {{title}}, {{html}}, {{primary_author.name}} 替換為對應的 prop access (例如 props.post.title, props.post.html, props.post.primary_author.name)。”

    • 處理 Handlebars Helpers:對於 Handlebars 的內建 helpers(如 #if, #each)或自訂 helpers,您需要特別指示 Cursor 如何轉換:
      • {{#if condition}}...{{/if}}: 可以轉換為 JSX 中的條件渲染({condition && ...}condition ? ... : ...)。
        • AI 指令:“將這個 {{#if}} 區塊轉換為 JSX 條件渲染。”
      • {{#each collection}}...{{/each}}: 可以轉換為 JavaScript 的 .map() 方法。
        • AI 指令:“將這個 {{#each posts}} 迴圈轉換為使用 posts.map(...) 的 JSX 列表渲染,確保為每個元素提供唯一的 key prop。”
      • Partials ({{> partial-name}}): 需要將對應的 partial (_partial-name.hbs) 也轉換為一個獨立的 React 元件,然後在主元件中導入並使用。
        • AI 指令 (轉換 partial):“將此 Handlebars partial 轉換為一個名為 PartialName 的 React functional component。”
        • AI 指令 (在主元件中使用):“在此處導入並使用 PartialName 元件,替換 {{> partial-name}}。”
  4. 迭代與修正AI 生成的程式碼不一定是完美的。您需要仔細審閱、測試並修正 Cursor 生成的 React 元件,確保它們的功能和結構符合預期。CursorAI 也可以協助修正錯誤或重構程式碼(例如,選取有問題的程式碼,按 Cmd+K / Ctrl+K,描述問題或期望的修改)。

步驟四:整合 Ghost Content API 以獲取資料

轉換後的 Next.js 元件現在是靜態的結構。我們需要從 Headless Ghost CMS 獲取實際內容。這通常在 Next.js 的頁面檔案中使用 getStaticProps (用於 SSG) 或 getServerSideProps (用於 SSR) 來完成。

  1. 安裝 Ghost Content API SDK

    npm install @tryghost/content-api
    # 或
    yarn add @tryghost/content-api
    
  2. 在頁面中獲取資料:以 pages/index.tsx (首頁) 為例:

    • 導入 API SDK。
    • 在檔案底部添加 getStaticProps 函數。
    • 使用您的 API URLContent API Key 初始化 SDK。
    • 調用 SDK 的方法(例如 api.posts.browse())來獲取文章列表。
    • 將獲取的資料透過 props 返回給頁面元件。

    使用 Cursor 輔助生成 getStaticProps

    • pages/index.tsx 文件中,您可以透過 Cursor 的聊天或 Cmd+K / Ctrl+K 功能請求生成程式碼。
    • 範例 AI 指令

      “為這個 Next.js 頁面元件生成 getStaticProps 函數 (使用 TypeScript)。導入 @tryghost/content-api,使用環境變數 GHOST_API_URLGHOST_CONTENT_API_KEY 初始化 API。獲取最新的 10 篇文章 (posts),包含作者 (author) 和標籤 (tags) 資訊。將文章列表作為 posts prop 返回。”

    • Cursor 將生成包含 API 調用邏輯的 getStaticProps 函數。您需要確保已在環境變數 (.env.local) 中設定 GHOST_API_URLGHOST_CONTENT_API_KEY
  3. 在元件中使用資料:修改您的 React 元件,使其接收並顯示從 getStaticProps 傳來的 props。例如,在 IndexPage 元件中接收 posts prop,並使用 .map() 渲染文章列表。

  4. 處理動態路由 (例如 pages/posts/[slug].tsx)

    • 您需要額外實現 getStaticPaths 來告訴 Next.js 需要預先生成哪些文章頁面。這通常涉及調用 Ghost Content API 獲取所有文章的 slug
    • getStaticProps 中,根據傳入的 params.slug 獲取特定文章的詳細內容。
    • Cursor AI 指令範例 (用於 getStaticPaths)

      “為這個動態路由頁面 [slug].tsx 生成 getStaticPaths 函數。使用 @tryghost/content-api 獲取所有已發布文章的 slug,並將它們格式化為 paths 陣列返回。設定 fallback: 'blocking' (或 true / false 根據需求)。”

    • Cursor AI 指令範例 (用於 getStaticProps for dynamic route)

      “為這個動態路由頁面 [slug].tsx 生成 getStaticProps 函數。從 context.params 獲取 slug。使用 @tryghost/content-api 根據 slug 獲取單篇文章的詳細內容 (包含 html 欄位)。將文章資料作為 post prop 返回。”

步驟五:遷移樣式 (CSS/Sass)

您的 Ghost 主題通常包含 CSS 或 Sass 檔案來定義外觀。將這些樣式應用到 Next.js 專案中有多種方式:

  1. 全域 CSS:將主要的 CSS 檔案(通常在 Ghost 主題的 assets/css 目錄下)複製到 Next.jsstyles 資料夾中,並在 pages/_app.tsx 中導入。這是最簡單直接的方法,但可能導致全域命名衝突。
    // pages/_app.tsx
    import '../styles/global.css'; // 導入您的 CSS 檔案
    import type { AppProps } from 'next/app';
    
    function MyApp({ Component, pageProps }: AppProps) {
      return <Component {...pageProps} />;
    }
    
    export default MyApp;
    
  2. CSS Modules:將 CSS 檔案重命名為 [name].module.css,並將其與對應的 React 元件放在一起。在元件中導入並像使用物件一樣使用 class 名稱。這提供了局部作用域,避免了命名衝突。Cursor 可以協助進行這種重構。
    • AI 指令範例:“將這個 CSS 檔案的規則轉換為 CSS Modules 格式,並更新對應的 React 元件以使用導入的樣式物件。”
  3. Tailwind CSS:如果您希望使用現代的 utility-first CSS 框架,可以考慮將現有樣式重構為 Tailwind CSSCursor 對於這種基於 class 的轉換也能提供一些幫助,但通常需要大量手動調整。
  4. Styled Components / Emotion:如果您偏好 CSS-in-JS 方案,可以將樣式直接寫在 React 元件中。Cursor 也能輔助生成這些樣式化元件的程式碼。

選擇哪種方法取決於您的專案需求和個人偏好。對於直接遷移,全域 CSSCSS Modules 是較常見的選擇。

步驟六:處理路由和連結

確保 Next.js 應用程式中的內部連結指向正確的路徑。

  1. Next.js Link 元件:使用 Next.js 提供的 <Link> 元件來處理客戶端路由,以獲得最佳效能。
    import Link from 'next/link';
    
    // ...
    <Link href={`/posts/${post.slug}`}>
      <a>{post.title}</a>
    </Link>
    // ...
    
  2. 檢查並更新連結:仔細檢查從 Handlebars 轉換過來的程式碼中的所有 <a> 標籤。將內部連結替換為使用 <Link> 元件。Cursor 可以幫助查找和替換這些連結。
    • AI 指令範例:“查找此元件中所有指向 /post/ 開頭的 <a> 標籤,並將其替換為使用 Next.js 的 <Link> 元件,保留 href 和內容。”

步驟七:部署到 Vercel

一旦您的 Next.js 前端能夠成功從 Headless Ghost CMS 獲取內容並正確顯示,就可以將其部署到 Vercel

  1. 推送到 Git 倉庫:將您的 Next.js 專案推送到 GitHub, GitLab, 或 Bitbucket
  2. 在 Vercel 上建立專案:登入您的 Vercel 帳戶,選擇 “Import Project”,然後選擇您的 Git 倉庫。
  3. 配置設定
    • Vercel 通常會自動檢測到是 Next.js 專案並選擇正確的框架預設。
    • 環境變數:在 Vercel 的專案設定中,添加您之前使用的環境變數 GHOST_API_URLGHOST_CONTENT_API_KEY。這是 非常重要 的一步,否則您的部署將無法連接到 Ghost CMS
  4. 部署:點擊 “Deploy”。Vercel 將自動構建和部署您的 Next.js 應用程式。

部署完成後,Vercel 會提供一個 URL,您可以透過該 URL 訪問您的 Headless Ghost CMS 前端。

挑戰與注意事項

  • 複雜的 Handlebars 邏輯:如果您的 Ghost 主題包含非常複雜的自訂 Handlebars helpers 或嵌套邏輯,AI 轉換可能不夠完美,需要更多手動介入。
  • JavaScript 檔案Ghost 主題中的 JavaScript 檔案可能需要進行調整才能在 React/Next.js 環境中正常工作,特別是那些直接操作 DOM 的程式碼。考慮是否可以用 React 的方式重新實現這些功能。
  • 樣式細節:確保所有樣式都已正確遷移且顯示效果與原主題一致。跨瀏覽器測試是必要的。
  • AI 不是萬能的Cursor 是一個強大的輔助工具,但它不能完全取代開發者的理解和判斷。始終審查、測試和優化 AI 生成的程式碼。

結論:利用 AI 加速現代化遷移

Ghost CMS 主題遷移到 Next.js 是一個實現現代化、高效能網站架構的絕佳途徑。雖然這個過程涉及不同技術棧之間的轉換,但藉助於像 Cursor 這樣的 AI 驅動工具,可以顯著減少手動重寫程式碼的時間和精力。透過遵循上述步驟,結合 AI 的輔助和您自身的開發專業知識,您可以成功地將您的 Ghost 內容呈現在一個由 Next.js 驅動、部署在 Vercel 上的快速、現代化的前端應用程式中。


我們 Tenten.co 是一家專注於提供尖端數位解決方案的機構。無論您是需要進行複雜的網站架構遷移、客製化軟體開發,還是尋求提升數位產品效能的策略,我們的專業團隊都能提供協助。如果您在將 Ghost 遷移到 Next.js 或其他數位轉型項目中遇到挑戰,歡迎與我們聯繫。

立即預約免費諮詢會議,讓我們一同探討如何為您的專案帶來成功:預約免費會議