Avatar

[Content Engine #1] - Vấn đề về Code Block của Substack

3 phút đọc

Chia sẻ kiến thức là một phần của quá trình học hỏi. Tuy nhiên, hành trình tìm kiếm một "nơi ở" cho các bài viết của tôi không hề suôn sẻ như dự tính.

Vấn đề: Code Block của Substack

Lựa chọn ban đầu của tôi là Substack - một nền tảng tuyệt vời cho Newsletter, nhưng nó lại "có vấn đề" đối với dạng nội dung tôi hay viết.

  1. Code Block "nguyên thủy": Substack không hỗ trợ Syntax Highlighting. Những đoạn code TypeScript, Go của tôi trông chẳng khác gì một tệp văn bản thô, cực kỳ khó đọc.

  2. Code Screenshot: Để đối phó, nhiều người (bao gồm cả tôi) đã phải dùng ảnh chụp màn hình code từ Carbon hoặc Ray.so.

    • Về mặt UX: Người đọc không thể copy code để chạy thử. Đây là rào cản rất lớn.
    • Về mặt SEO: Nội dung code hoàn toàn biến mất khỏi các công cụ tìm kiếm.

Tôi nhận ra mình cần một giải pháp khác. Ban đầu tôi nghĩ đến Ghost CMS, nhưng hiện tại phiên bản mới của nó nhồi nhét rất nhiều tính năng khiến việc cài đặt trở nên rắc rối hơn nhiều.

Giải pháp: Xây dựng một "Content Engine" tinh gọn

Thay vì tìm các giải pháp bên ngoài, tôi quyết định tự xây dựng nền tảng cho riêng mình. Tuy nhiên, tôi phải đặt ra một ràng buộc: Không sa đà vào over-engineering. Mục tiêu là viết bài, không phải là dành cả tháng để code một cái CMS.

Hình ảnh so sánh khi có và không có code highlighting

Tại sao lại là Next.js và Markdown/MDX?

  • Markdown/MDX: Cho phép tôi viết code ngay trong trình soạn thảo quen thuộc (VS Code). MDX còn mạnh mẽ hơn khi cho phép chèn trực tiếp các React component vào bài viết nếu cần tương tác.
  • Next.js (Static Site Generation): Hiệu suất cực cao. Bài viết được render tĩnh, tải tức thì và SEO cực tốt. Quan trọng nhất, nó có hệ sinh thái thư viện xử lý code (như Shiki hay rehype-pretty-code) rất mạnh, giải quyết triệt để vấn đề highlight mà Substack đang bỏ ngỏ.

Giải bài toán Frontend bằng shadcn/ui

Tôi không giỏi — và cũng không muốn dành quá nhiều thời gian — để "vật lộn" với HTML/CSS thuần hay thiết kế giao diện từ con số 0. Tôi lựa chọn shadcn/ui

  • Tốc độ: Thay vì tự build, tôi sử dụng các component đã được chuẩn hóa.
  • Kiểm soát: Tôi có toàn quyền truy cập vào mã nguồn của component để tinh chỉnh theo ý mình.
  • Minimalism: Đúng tinh thần tối giản mà tôi hướng tới.

Done is better than perfect

Hệ thống hiện tại chưa phải là hoàn hảo nhất, nhưng nó giải quyết đúng và trúng vấn đề tôi đang gặp phải: Đọc code và copy code một cách mượt mà.

Trong các bài viết tiếp theo, tôi sẽ đi sâu hơn vào việc quyết định tính năng, cấu trúc thư mục, cách hiển thị makdown và cách triển khai CI/CD để mỗi lần git push là một lần bài viết mới được "online".