Skip to content

Keystatic vs Decap CMS - Bài học thực chiến với Astro Starlight

Keystatic vs Decap CMS - Bài học thực chiến với Astro + Starlight

Section titled “Keystatic vs Decap CMS - Bài học thực chiến với Astro + Starlight”

Ngày: 2026-03-08
Dự án: my-private-docs (Astro 5 + Starlight)
Kết luận: Dùng Decap CMS cho Starlight, dùng Keystatic cho Astro thuần/custom


Muốn tích hợp một CMS có giao diện quản lý nội dung (kiểu WordPress) vào site my-private-docs chạy Astro 5 + Starlight. Ban đầu chọn Keystatic vì:

  • Đã dùng thành công trên cudem-claw (Astro 5 + MDX, không có Starlight)
  • Giao diện đẹp, lưu file local git
  • TypeScript config rõ ràng

Các lỗi gặp phải với Keystatic + Starlight

Section titled “Các lỗi gặp phải với Keystatic + Starlight”

1. @astrojs/starlight@^0.49.0 không tồn tại

Section titled “1. @astrojs/starlight@^0.49.0 không tồn tại”
npm error notarget No matching version found for @astrojs/starlight@^0.49.0

Fix: Hạ version xuống ^0.37.7

2. output: "hybrid" bị khai tử trong Astro 5

Section titled “2. output: "hybrid" bị khai tử trong Astro 5”
! The output: "hybrid" option has been removed.

Fix: Keystatic v5 trở lên không cần output: "hybrid" nữa → dùng output: "server" + @astrojs/node adapter

3. Duplicate routes - Keystatic tự inject + manual page = 2 routes

Section titled “3. Duplicate routes - Keystatic tự inject + manual page = 2 routes”
[WARN] The route "/keystatic/[...params]" is defined in both "src/pages/keystatic/[...params].astro"
and "node_modules/@keystatic/astro/internal/keystatic-astro-page.astro"

Fix tạm: Dùng keystatic({ injectKeystaticRouter: false }) và tạo manual pages

4. Vấn đề cốt lõi không fix được: React hydration crash

Section titled “4. Vấn đề cốt lõi không fix được: React hydration crash”
The above error occurred in the <LocalAppShellProvider> component

Keystatic chạy như một React SPA. Khi load trang:

  1. Server render HTML ✅ (thấy giao diện flash 1 giây)
  2. React bắt đầu hydrate client-side
  3. Starlight’s View Transitions interceptor chạy, intercept navigation
  4. Keystatic React context bị destroy → blank screen 💥

Root cause: Starlight dùng Astro View Transitions để navigate giữa các trang. Khi React hydrate Keystatic admin panel, Starlight’s client-side router fire, destroy React tree → crash.

Các cách đã thử:

  • React 18 → React 19 → React 18 lại
  • Vite optimizeDeps, resolve.alias
  • prefetch: false
  • react({ experimentalReactChildren: true })
  • Manual route pages
  • Node adapter + output: "server"

Không giải quyết được vì đây là conflict cấu trúc giữa Starlight router và React SPA


Decap CMS (trước là Netlify CMS) không dùng React SPA → không bị conflict với Starlight.

Cách cài:

public/
admin/
index.html ← Load Decap CMS từ CDN, không cần npm install
config.yml ← Define collections bằng YAML

Cài không tốn 1 dòng npm install, không cần SSR adapter, không conflict với bất kỳ integration nào.

Terminal window
npx decap-server # Bật proxy lắng nghe port 8081
npm run dev # Astro dev server như bình thường

Vào: http://localhost:4321/admin/ để quản lý nội dung


Tiêu chíKeystaticDecap CMS
Cài vào Starlight⚠️ Conflict View Transitions✅ Zero conflict
Cần npm install✅ Cần❌ Không (CDN)
Cần SSR adapter✅ Cần @astrojs/node❌ Không
ConfigTypeScript, linh hoạtYAML, đơn giản
Giao diệnHiện đại, đẹpĐơn giản, ổn định
Lưu file✅ Git commit✅ Git commit
Phù hợp my-private-docs
Phù hợp cudem-claw (MDX thuần)❌ (thiếu tính năng)

  • Astro thuần (MDX, không Starlight) → Dùng Keystatic
  • Astro + Starlight → Dùng Decap CMS
  • Lý do Keystatic không hợp với Starlight: Starlight tích hợp sâu View Transitions vào mọi trang, khiến React SPA của Keystatic không hydrate được ổn định.