Next.js & ReactNổi bật

12/06/2026 · 2 phút đọc · cập nhật 18/06/2026

Dựng blog markdown bằng Next.js App Router server-first

Một cấu trúc server-first cho blog markdown: content file, service normalize dữ liệu, page mỏng và route handler khi cần API.

Next.jsApp RouterMarkdownSEO

Server-first nghĩa là gì

Với blog markdown, dữ liệu đã nằm trong repository nên không cần đẩy việc load bài viết xuống client. Server Component có thể đọc content qua service, render HTML có metadata đầy đủ và gửi xuống trình duyệt một payload gọn hơn.

Server-first không có nghĩa là không dùng Client Component. Nó chỉ có nghĩa là mặc định dữ liệu và HTML chính nên được xử lý ở server. Client chỉ xuất hiện cho phần thật sự cần browser API, ví dụ thanh tiến trình đọc bài.

Luồng dữ liệu nên dùng

Một luồng gọn cho blog markdown:

src/content/blog/*.md
  -> blog-service.ts
  -> app/blog/page.tsx hoặc app/blog/[slug]/page.tsx
  -> reusable blog components

Service chịu trách nhiệm parse frontmatter, validate field, tính reading time, lọc draft và sort bài viết. Page chỉ gọi service và compose UI.

Vì sao không fetch API nội bộ trong page

Route Handler hữu ích khi cần consumer HTTP thật, nhưng page server không cần gọi chính API của mình để lấy markdown local. Gọi service trực tiếp giảm overhead, tránh serialize không cần thiết và giữ kiểu dữ liệu sát hơn.

API vẫn có thể tồn tại:

export async function GET(_: Request, { params }: { params: Promise<{ slug: string }> }) {
  const { slug } = await params
  const post = await getBlogPost(slug)
  return post
    ? Response.json({ ok: true, data: post })
    : Response.json({ ok: false }, { status: 404 })
}

Điểm chính là API dùng cùng service với page, không tạo logic đọc markdown thứ hai.

Metadata và sitemap

Mỗi bài blog nên có generateMetadata riêng để set title, description, canonical, Open Graph type article, published time, updated time và tags. Sitemap cần lấy cùng danh sách published posts để draft không bị index.

Category page cũng nên có canonical riêng. Khi category có route tường minh, Google và người đọc đều hiểu blog đang có taxonomy rõ ràng.

Kết luận

Một blog markdown tốt không cần CMS ngay từ đầu. Chỉ cần content files có schema rõ, service normalize dữ liệu, routes mỏng và SEO được sinh từ cùng một nguồn dữ liệu. Cấu trúc này đủ đơn giản để cập nhật bằng tay nhưng vẫn đủ sạch để scale.