翔揚智慧翔揚智慧
為什麼我們選擇 Next.js + Supabase 作為主力技術棧

為什麼我們選擇 Next.js + Supabase 作為主力技術棧

發布於 2026年4月19日4 分鐘閱讀作者 翔揚智慧團隊nextjssupabasestackcloudflare-r2app-router

接案公司的技術決策到底在比什麼

每次簽約前,PM、架構師、資深工程師都會把候選技術棧攤開來問三個問題:

  1. 交期:這套技術能不能讓我們在 4-8 週內把 MVP 打掉?
  2. 可維護性:交付後客戶的內部團隊或其他工程師能不能接手?
  3. 總持有成本(TCO):基礎設施、第三方服務、人力工時加起來,12 個月內要花多少錢?

一套技術只要任一項是紅燈,就不會進入主力清單。Next.js + Supabase 是少數三題都拿到綠燈的組合。

Next.js:前端的綜合拳

我們把 Next.js 的優勢歸納成四個面向。

App Router + React Server Components

App Router 把「哪些組件跑在 server、哪些跑在 client」變成第一等設計決策。我們大多數行銷頁(首頁、服務頁、案例列表)都是 Server Component,直接在 server 上 fetch Supabase,產出完整 HTML。Client JS bundle 因此變薄,首屏 LCP 容易壓進 2.5 秒以內。

SEO 優先

Server Component 預設 SSR,meta tag、Open Graph、JSON-LD 都在 server 端組好才回給 Google。配合 App Router 的 generateMetadatasitemap.ts,我們可以把每個 case 與 blog post 的雙語 metadata 集中管理、動態產出 sitemap,不必手動維護靜態 XML。

效能與部署簡單

Image 最佳化、Font 本地化、Route handlers、Edge runtime 都內建。Zeabur + Git push 就能部署,不必自己維運 CI pipeline,Node 版本、Build cache、環境變數全由平台接管。

一套框架吃前後端

前台頁面、API、後台介面、middleware auth guard 可以用同一個專案、同一個型別系統維護。接案情境下這意味著:一位資深工程師就能顧到絕大部分的交付面向,不用同時維運前端與後端兩個 repo。

Supabase:後端的「免費開局」

Supabase 把我們過去要花 1-2 週手刻的基礎設施,壓縮成一個 dashboard:

  • Auth:Email + Password、OAuth、Magic Link 全內建,@supabase/ssr 搭配 Next.js middleware 三步驟就能保護 /admin 路徑。
  • Row Level Security (RLS):真正把「誰能讀/寫哪筆資料」的規則寫在 DB 層。接案情境下,這讓匿名前台(僅讀 published 資料)與後台(登入即全權)可以共用一份 schema,API 層不必每支都重複檢查權限。
  • Realtime:Postgres changes、broadcast、presence 三種模式即開即用。做客戶儀表板、聊天、協作編輯時不必再架 WebSocket server。
  • PostgREST:任何資料表都自動有 REST API,前端可以直接查;需要商業邏輯時再補 RPC function。

對我們來說,Supabase 等於省掉「Auth 設計 + API 框架 + 權限檢查 + 部署 DB」的一整段前期工程,交期因此能向前推兩週。

Cloudflare R2 補位:storage 取代 S3

Supabase 雖然自帶 Storage,但在「檔案數量大、流量成本敏感」的專案中,我們改用 Cloudflare R2:

  • 零 egress 費用:R2 不收 egress 流量費,對於圖片密集的作品集、Blog 封面、客戶資料下載而言,長期下來比 S3 / GCS 便宜一個數量級。
  • S3 相容 API:繼續用 @aws-sdk/client-s3,遷移幾乎零學習成本。
  • Cloudflare CDN 內建:bucket 可直接綁自訂網域並走 Cloudflare 的全球節點,圖片載入速度接近免費。

我們的標準做法是:Supabase 負責 Auth 與結構化資料,R2 負責所有 blob;上傳流程走 presigned PUT URL,client 直接傳,伺服器只負責簽名與事後回寫 media_assets 資料表。

實際踩坑與收穫

技術選型不是看官方文件,是看升級那天會不會被噴火。以下是我們在這個官網專案上實際遇到的兩個坑:

坑一:Next.js 16 的 breaking changes

這是我們第一個上線就用 Next.js 16 的專案。升級途中我們被幾個 breaking changes 擋住:

  • App Router API 簽名調整paramssearchParams 在部分路由 handler 中變成 Promise,必須 await 後再使用。TypeScript 編譯期會抓到,但從 Next.js 15 以下複製貼上的 code 會炸開。
  • next/dynamic 對 server component 的約束變嚴:需要明確區分 ssr: falseloading 的用法。
  • 部分 deprecation 轉為 hard error:原本只是警告的 API,在 16 變成 build 失敗。

我們在 app/CLAUDE.md 裡硬性要求所有 agent:寫 code 前先看 node_modules/next/dist/docs/ 對應的 guide,不要靠記憶裡的 Next.js 14/15 寫法下手。

坑二:Turbopack 在 NTFS 上的 dev 體驗

Windows 的 NTFS 檔案系統搭 Turbopack dev server 時,某些 chunk 會觸發 watcher 重複編譯、偶爾 404。解法是把專案目錄掛在 WSL2 的 ext4 上,或切回 webpack dev server 作為備用。這件事在官方文件上只有一行備註,現場踩到才會痛。

收穫

扣除上述坑,整體交期相較舊架構縮短約 35%,主要貢獻來自:

  1. Supabase RLS 讓我們不必重複寫權限檢查中介層。
  2. App Router 的 Server Component 讓 SEO-critical 頁面「寫了就好」,不必額外維護 SSR 邏輯。
  3. Cloudflare R2 + presigned URL 讓媒體上傳不吃 Node 記憶體與出口頻寬。

下一步

我們接下來會把這套組合用在客戶的電商、SaaS、內容平台專案上,並持續把踩坑經驗寫進 Blog。如果你正在猶豫是否要上 Next.js + Supabase,或者卡在某個升級問題,歡迎透過聯絡頁面聊聊,我們很樂意分享第一線經驗。

留言功能開發中