Skip to content
Thuan Bui
Go back

Tích hợp Sveltia CMS cho blog Astro — quản lý bài viết bằng giao diện GUI

Từ ngày chuyển blog qua Astro, mỗi lần viết bài mới, mình phải mở VS Code, tạo file markdown mới, điền frontmatter, viết nội dung, commit rồi push lên GitHub.

Quy trình không phức tạp như WordPress, nhưng vẫn hơi phiền khi muốn sửa nhanh một bài viết hoặc thay đổi metadata mà không có giao diện trực quan. Đặc biệt, không thể viết bài trên điện thoại di động — bắt buộc phải sử dụng máy tính.

Mới đây, mình đã tích hợp thêm Sveltia CMS — một open-source Git-based CMS — giúp quản lý nội dung blog hoàn toàn bằng giao diện GUI ngay trên trình duyệt. Điểm mình thích nhất: giờ có thể sửa bài, viết bài mới ngay trên điện thoại, không cần máy tính.

Bài viết này sẽ hướng dẫn cách tích hợp Sveltia CMS cho Astro, tạo nên bộ đôi hoàn hảo để quản lý bài viết cho blog.

I. Vì sao chọn Sveltia CMS?

Với blog Astro dạng static site, mọi nội dung đều lưu dưới dạng file Markdown trong repo. Cách này rất phù hợp với developer: dễ quản lý lịch sử, build nhanh, deploy đơn giản.

Tuy nhiên, khi muốn:

…thì thao tác thủ công trên VS Code lại trở thành rào cản.

Sveltia CMS giải quyết triệt để vấn đề này bằng giao diện web hiện đại, cho phép:

II. Giới thiệu Sveltia CMS

Sveltia CMS là một hệ thống quản lý nội dung (content management system) mã nguồn mở, miễn phí, hoạt động theo mô hình Git-based headless CMS. Đây là phiên bản kế thừa từ Netlify CMS (nay là Decap CMS), tương thích hoàn toàn với cấu hình cũ nhưng bổ sung nhiều tính năng mới.

Sveltia CMS
Sveltia CMS

1. Đặc điểm kiến trúc

2. Luồng hoạt động

Trình duyệt (Sveltia CMS) ←→ GitHub API ←→ GitHub Repository
Cloudflare R2 (ảnh)
  1. Người dùng đăng nhập qua GitHub OAuth
  2. Sveltia giao tiếp với GitHub API để đọc/ghi file markdown
  3. Mỗi thao tác save tạo một commit mới trên branch (thường là main)
  4. Cloudflare Workers tự động rebuild blog khi có commit mới
  5. Ảnh upload lên Cloudflare R2, URL public được chèn tự động vào content

3. Vì sao nên dùng Git-based CMS?

III. Hướng dẫn tích hợp Sveltia CMS

1. Thêm file cấu hình CMS

Tạo file public/cms/config.yml với nội dung:

public/cms/config.yml
backend:
name: github
repo: username/repo-name
branch: main
skip_ci: true
media_libraries:
cloudflare_r2:
access_key_id: ...
bucket: bucket-name
account_id: ...
public_url: https://<r2-public-url>
prefix: images/
collections:
- name: blog
label: Blog
folder: /src/data/blog
identifier_field: title
extension: md
format: frontmatter
frontmatter_delimiter: "---"
fields:
- { label: Title, name: title, widget: string }
- { label: Author, name: author, widget: string, default: "Thuan Bui" }
- {
label: Publish Date,
name: pubDatetime,
widget: datetime,
date_format: "YYYY-MM-DD",
time_format: "HH:mm",
format: "YYYY-MM-DDTHH:mm:ssZ",
}
- {
label: Last Modified Date,
name: modDatetime,
widget: datetime,
required: false,
}
- { label: Featured, name: featured, widget: boolean, default: false }
- { label: Tags, name: tags, widget: list, default: [], required: false }
- { label: Categories, name: categories, widget: list, default: [] }
- { label: Series, name: series, widget: list, required: false }
- {
label: Description,
name: description,
widget: string,
required: false,
}
- { label: Featured Image, name: image, widget: image, required: false }
- { label: Draft, name: draft, widget: boolean, default: false }
- { label: Body, name: body, widget: markdown, modes: [raw] }
path: "{{year}}-{{month}}-{{day}}-{{slug}}"
sortable_fields: [title, pubDatetime, modDatetime]

File này gồm 3 phần chính: backend, media_libraries, và collections:

a. Backend

backend:
name: github
repo: username/repo-name
branch: main
skip_ci: true

Phần này khai báo Sveltia CMS dùng GitHub làm backend:

b. Media libraries (R2)

media_libraries:
cloudflare_r2:
access_key_id: ...
bucket: bucket-name
account_id: ...
public_url: https://<r2-public-url>
prefix: images/

Phần này cấu hình upload ảnh lên Cloudflare R2:

Khi upload ảnh trong CMS, file sẽ được upload lên R2 bucket/images/ và URL public sẽ tự động được chèn vào markdown.

c. Collections

Phần collections khai báo các loại content. Mình khai báo collection Blog để quản lý bài viết với các trường thông tin sau:

FieldWidgetMô tả
titlestringTiêu đề bài viết
pubDatetimedatetimeNgày giờ publish
modDatetimedatetimeNgày giờ chỉnh sửa cuối
featuredbooleanBài viết nổi bật
tags, categories, serieslistPhân loại nội dung
descriptionstringMô tả ngắn cho SEO
imageimageẢnh đại diện
draftbooleanTrạng thái nháp
bodymarkdownNội dung bài viết

Đặc biệt, path: "{{year}}-{{month}}-{{day}}-{{slug}}" giúp file mới tạo có format 2026-05-08-tich-hop-sveltia-cms-astro-blog.md.

2. Tạo trang CMS index

Tạo file public/cms/index.html — đây là trang HTML để load Sveltia CMS:

public/cms/index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="robots" content="noindex" />
<title>Sveltia CMS</title>
</head>
<body>
<script src="https://unpkg.com/@sveltia/cms/dist/sveltia-cms.js"></script>
</body>
</html>

Sveltia CMS sẽ tự động đọc file config.yml để khởi tạo giao diện quản lý. Truy cập /cms/ là có thể bắt đầu sử dụng.

IV. Xác thực qua OAuth thay vì dùng Token

Mặc định, Sveltia CMS dùng Github Access Token (personal access token) — đây là cách đơn giản nhất, không cần cấu hình thêm.

Bấm vào Sign In Using Access Token và nhập Token để đăng nhập

Sveltia CMS Auth
Sveltia CMS Auth

Mình thích xác thực trực tiếp qua GitHub OAuth thay vì dùng token, vì:

Để dùng OAuth, cần phải deploy thêm Sveltia CMS Auth Worker — đây là OAuth client server chạy trên Cloudflare Workers.

1. Deploy Sveltia CMS Auth Worker

Deploy nhanh lên Cloudflare Worker theo link sau:

Truy cập: https://deploy.workers.cloudflare.com/?url=https://github.com/sveltia/sveltia-cms-auth

Bấm Create an deploy để tạo Worker mới

Sveltia CMS Auth
Sveltia CMS Auth

Sau khi deploy, copy URL Worker (ví dụ: https://sveltia-cms-auth.xxx.workers.dev) để dùng cấu hình cho Github OAuth App.

2. Tạo GitHub OAuth Application

Tiếp theo, cần tạo OAuth App trên GitHub để lấy Client ID và Client Secret:

  1. Truy cập Settings > Developer Settings > OAuth Apps
  2. Click New OAuth App
  3. Điền thông tin:
    • Application name: Sveltia CMS (tùy ý)
    • Homepage URL: <YOUR_WORKER_URL>
    • Authorization callback URL: <YOUR_WORKER_URL>/callback
  4. Bấm Register applicaton để tạo
Sveltia CMS Auth
Sveltia CMS Auth

Bấm vào nút Generate a new client secret.

Sveltia CMS Auth
Sveltia CMS Auth

Lưu Client IDClient Secret để cấu hình bên Worker.

Sveltia CMS Auth
Sveltia CMS Auth

3. Lưu Client ID và Client Secret vào Worker

Quay lại Worker vừa tạo, truy cập vào phần Settings > bấm Add ở mục Variables and Secrets

Sveltia CMS Auth
Sveltia CMS Auth

Nhập vào 2 thông số sau và bấm Deploy

Sveltia CMS Auth
Sveltia CMS Auth

4. Cập nhật config.yml

Thêm base_url vào config.yml và push lên Github để Cloudflare cập nhật thông số

public/cms/config.yml
backend:
name: github
repo: username/repo-name
branch: main
base_url: https://sveltia-cms-auth.xxx.workers.dev

Giờ mình đã có thể đăng nhập bằng cách bấm vào nút Sign In with Github để đăng nhập bằng tài khoản Github

Sveltia CMS Auth
Sveltia CMS Auth

V. Trải nghiệm sử dụng thực tế

Quy trình viết bài của mình trở nên linh hoạt hơn hẳn, có thể dùng VS Code hoặc Sveltia CMS tùy tình huống:

Giao diện quản lý bài viết của Sveltia CMS

Sveltia CMS Dashboard
Sveltia CMS Dashboard

Sau khi tích hợp Sveltia CMS, mình vẫn dùng VS Code cho các bài viết dài và phức tạp. Nhưng với những lúc cần sửa vội một bài trên điện thoại, Sveltia CMS là lựa chọn tiện lợi hơn nhiều.

Sveltia CMS có tích hợp sẵn Lexica Editor để chỉnh sửa bài viết trực quan, nhưng mình thích dùng markdown nên chọn chế độ raw mode.

Giao diện chỉnh sửa bài viết của Sveltia CMS
Giao diện chỉnh sửa bài viết của Sveltia CMS

VI. Kết luận

Sveltia CMS là giải pháp tuyệt vời cho blog Astro: nhẹ, miễn phí, không cần server riêng, tích hợp cực nhanh (chỉ 2 file), quản lý nội dung qua UI hiện đại, upload ảnh trực tiếp lên R2.

Nếu bạn đang sử dụng Astro xây dựng blog, hãy thử tích hợp Sveltia CMS — đảm bảo sẽ tiện lợi hơn rất nhiều!

Chúc bạn cài đặt thành công!


Share this post on:

Previous Post
Tailscale Exit Node - Thiết lập VPN đơn giản không cần cấu hình phức tạp
Next Post
Hướng dẫn tích hợp GitHub Identity Provider với Cloudflare One
Loading...
Loading comments...