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
Vấn đề ban đầu
Section titled “Vấn đề ban đầu”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.0Fix: 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> componentKeystatic chạy như một React SPA. Khi load trang:
- Server render HTML ✅ (thấy giao diện flash 1 giây)
- React bắt đầu hydrate client-side
- Starlight’s View Transitions interceptor chạy, intercept navigation
- 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: falsereact({ 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
Giải pháp: Decap CMS
Section titled “Giải pháp: Decap CMS”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 YAMLCà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.
Chạy local dev với Decap:
Section titled “Chạy local dev với Decap:”npx decap-server # Bật proxy lắng nghe port 8081npm run dev # Astro dev server như bình thườngVào: http://localhost:4321/admin/ để quản lý nội dung
So sánh Keystatic vs Decap CMS
Section titled “So sánh Keystatic vs Decap CMS”| Tiêu chí | Keystatic | Decap 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 |
| Config | TypeScript, linh hoạt | YAML, đơn giản |
| Giao diện | Hiệ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) |
Kết luận
Section titled “Kết luận”- 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.