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。
畫面



技術
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 共同落實,仍需持續檢查。
