跳到主要內容
yoAkyoku
← Work

yoAkyoku 夜明曲 工作室網站

工作室官方網站:以 Next.js 呈現 Work、Notes 與 Studio,Payload CMS 管理內容;主題可依節氣切換,也可在每次重新整理時隨機更換,正式站部署於自管 VPS。

  • Web
  • Tools
Contents

概述

這是工作室的官方網站,也是一個持續演進中的全端作品。Work 展示專案,Notes 記錄工程設計,Studio 說明服務;內容由 Payload CMS 管理,編輯者可在後台預覽並發布,不必改程式或重新部署。品牌角色是首頁與 Studio 的視覺元素,不是獨立角色介紹頁。

問題

  • 作品與筆記要能分別編輯、預覽與發布,並維護彼此關聯;內容發布應與程式部署分開,避免小幅文字修正也走完整部署流程。
  • 主題與 Hero 素材需隨節氣切換,也能由後台預覽或暫時覆寫;若規則散落在頁面元件,容易造成不同頁面呈現不一致;隨機模式也需在每次完整重新整理時重新抽選,站內導覽沿用目前主題。
  • 公開內容必須遵守工作室的隱私邊界:不公開創作者真名、照片、地點、雇主與學經歷,也避免從媒體 metadata 或 SEO 欄位意外帶出。內容規則、存取權限與發布前 QA 要一起落實,而非只靠記憶。

解法

網站使用 Next.js App Router,透過 server-only content adapter 統一讀取 Payload;編輯者在 /admin 管理 Projects、Notes、Media 與 Settings。正式站運行於 VPS:Caddy 終止 HTTPS 並反向代理至 Next.js systemd service,Payload 以 SQLite 儲存內容,媒體放在 release 目錄之外的持久化位置。主題引擎支援依 24 節氣切換七種主題,也可設定成每次完整重新整理時隨機選擇;後台可覆蓋目前主題與 Hero 素材。

Settings.themeOverride ──▶ 固定主題 ───────────────────────────────────────┐
season.ts ──▶ 節氣主題/SSR 與無 JS 備援 ──────────────────────────────┤
themeMode=random ──▶ 每次完整重新整理抽選;站內導覽沿用現行主題 ───────┴──▶ <html data-theme=…>
                                                                                  │
                                                                         CSS tokens + 粒子層

主要功能

  • Work / Notes / Studio 為網站主要導覽;Character 是首頁 Hero 與 Studio 頁的品牌視覺,並非獨立公開頁面。作品與筆記可互相關聯,任一邊宣告即可。
  • 後台:作品、筆記、媒體、網站設定(主題覆蓋、各主題 Hero 素材)。內文是 Lexical,加上四種自訂區塊:Diagram、Code、Screens、Callout。
  • 季節主題:七個主題以節氣為邊界自動切換,?theme= 可預覽任何主題;隨機模式則在每次完整重新整理時重新抽選,站內導覽沿用目前主題。
  • 搜尋:靜態索引,鍵盤可操作的 combobox。
  • SEO 與分享:sitemap、每頁 canonical、筆記 RSS;沒有封面的文章自動產生含標題的分享卡片。

架構

src/
├── app/(site)/        頁面,只呼叫 src/lib/content 與 src/lib/theme
├── app/(payload)/     Payload admin 與 REST
├── lib/content/       內容模組:Payload adapter、標題 id、搜尋索引
├── lib/season*.ts     主題字彙(client-safe)與節氣邊界(server only)
├── components/lexical 伺服器端 Lexical → JSX 轉換器
└── payload/           collections、globals、access、hooks

工程決策

  • 深模組:頁面透過內容模組取得已解析的型別,Payload 查詢留在 adapter 內。這次從 MDX 切換到 Payload,頁面仍使用同一組讀取介面;新增資料來源仍需實作 adapter 並回歸驗證。
  • 不用 HTML 字串:程式碼高亮用 Shiki 的 token 直接產出 JSX,內文沒有任何 dangerouslySetInnerHTML。
  • 主題只動 token:季節主要調整 CSS tokens 與裝飾層,核心版面和字體保持一致;各主題仍需做響應式與視覺 QA;隨機模式只在完整重新整理時重新抽選,站內導覽沿用目前主題。
  • 資料持久化:開發環境採用 SQLite 與本機媒體;正式站把 SQLite 資料庫與媒體放在 release 目錄外,部署前備份資料庫再切換新版;其他環境設定 postgres:// 與 Blob token 即可切換至 Neon 與 Vercel Blob。
  • 內容可攜:Payload 內容可匯出為 MDX,MDX 也能透過 seed 匯回;這份副本有利版本管理與搬遷,但 Schema、內容與媒體仍須一併驗證。
  • 安全預設:匿名只能讀已發佈內容、GraphQL 關閉、上傳只收 png/jpeg/webp、登入路由限流、CSP 與安全標頭在 next.config。

畫面

首頁:窗景背景、角色與文案分層的 Hero
首頁 Hero 是三層:窗景、角色、文案。
Work 列表頁
Work:縮圖、標題、一行摘要。
筆記內頁,右側有目錄與相關作品
文章頁:右欄是目錄與相關連結。

技術

Next.js 16(App Router、Turbopack)、React 19、TypeScript、Tailwind CSS v4、Payload CMS 3(Lexical、SQLite、本機媒體儲存)、Shiki、lunar-javascript。正式站運行於 Linux VPS,使用 Caddy 與 systemd。

結果與心得

正式站的內容可在 Payload 後台編輯、預覽與發布,不必為文字更新重新部署;Next.js 頁面透過內容 adapter 讀取 CMS,使頁面與資料來源保持分離。這提升了內容維護彈性,但 CMS、Schema 與儲存層的遷移仍需要資料轉換、部署與回歸驗證。隱私保護由內容規範、存取控制、媒體處理與發布 QA 共同落實,仍需持續檢查。