使用 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.js 的 SSG 和 SSR 功能可顯著提升載入速度和 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 Key 和 API 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. 熟悉介面:確保您知道如何與 Cursor 的 AI 互動,例如透過 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.hbs → pages/index.tsx
      • post.hbs → pages/posts/[slug].tsx (動態路由)
      • page.hbs → pages/[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 元件,確保它們的功能和結構符合預期。Cursor 的 AI 也可以協助修正錯誤或重構程式碼(例如,選取有問題的程式碼,按 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 URL 和 Content 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_URL 和 GHOST_CONTENT_API_KEY 初始化 API。獲取最新的 10 篇文章 (posts),包含作者 (author) 和標籤 (tags) 資訊。將文章列表作為 posts prop 返回。”

    • Cursor 將生成包含 API 調用邏輯的 getStaticProps 函數。您需要確保已在環境變數 (.env.local) 中設定 GHOST_API_URL 和 GHOST_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.js 的 styles 資料夾中,並在 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 CSS。Cursor 對於這種基於 class 的轉換也能提供一些幫助,但通常需要大量手動調整。
  4. Styled Components / Emotion:如果您偏好 CSS-in-JS 方案,可以將樣式直接寫在 React 元件中。Cursor 也能輔助生成這些樣式化元件的程式碼。

選擇哪種方法取決於您的專案需求和個人偏好。對於直接遷移,全域 CSS 或 CSS 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_URL 和 GHOST_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 或其他數位轉型項目中遇到挑戰,歡迎與我們聯繫。

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