Build hệ thống newsletter trong 1 ngày
Tuần trước tôi build hệ thống newsletter trong 1 ngày.
Không dùng Substack hay ConvertKit.
Tự host, toàn quyền kiểm soát.
Đây là nhật ký build.
Tại sao tự host?
- Kiểm soát hoàn toàn dữ liệu
- Không phí hàng tháng (sau setup)
- Tính năng tuỳ chỉnh khi cần
- Trải nghiệm học hỏi
Đánh đổi: Tốn thời gian setup ban đầu.
Tech stack đã chọn
Sau khi nghiên cứu với Claude:
- Gửi email: Resend (API đơn giản, deliverability tốt)
- Database: Supabase (free tier hào phóng)
- Frontend: Astro (nhanh, đơn giản)
- Hosting: Cloudflare Pages (miễn phí)
Tổng chi phí: ~$0-20/tháng tuỳ lượng gửi.
Sáng: Setup nền tảng (4 giờ)
Giờ 1-2: Database schema
-- bảng subscribers
id, email, name, status, created_at, verified_at
-- bảng newsletters
id, subject, content, sent_at, stats
-- bảng events
id, subscriber_id, newsletter_id, event_type, created_at
Dùng Claude để sinh SQL, review thủ công.
Giờ 3-4: Gửi email
Resend setup:
- Xác minh domain
- API key
- Email test
Prompt tôi dùng:
Tôi cần function gửi email với Resend.
Yêu cầu:
- TypeScript
- Xử lý lỗi
- Logic thử lại (3 lần)
- Logging
Sinh code với comments giải thích.
Chiều: Tính năng chính (4 giờ)
Giờ 5-6: Luồng đăng ký
- Submit form → API route
- Lưu vào database (status: pending)
- Gửi email xác minh
- Người dùng click link → status: verified
Xác nhận hai lần để deliverability tốt hơn.
Giờ 7-8: Gửi newsletter
Trang admin (đơn giản, chỉ cho tôi):
- Viết nội dung (Markdown)
- Xem trước
- Gửi đến tất cả subscribers đã xác minh
- Theo dõi lượt gửi
Tối: Hoàn thiện (2 giờ)
Giờ 9: Analytics
Theo dõi:
- Tỷ lệ mở (tracking pixel)
- Tỷ lệ click (redirect links)
- Huỷ đăng ký
Đơn giản nhưng đủ dùng.
Giờ 10: Test và deploy
- Test toàn bộ luồng
- Deploy lên Cloudflare
- Setup DNS
- Gửi newsletter test
Quyết định và đánh đổi
Quyết định 1: Markdown thay vì WYSIWYG
Đánh đổi: Khó hơn cho người không kỹ thuật.
Lý do: Tôi là người dùng duy nhất. Markdown nhanh hơn.
Quyết định 2: Không template cầu kỳ
Đánh đổi: Email nhìn đơn giản.
Lý do: Nội dung quan trọng hơn thiết kế cho newsletters. Văn bản thuần chuyển đổi tốt.
Quyết định 3: Analytics tối thiểu
Đánh đổi: Ít dữ liệu hơn.
Lý do: Tỷ lệ mở và clicks là đủ. Đừng làm quá phức tạp.
Vấn đề gặp phải
Vấn đề 1: Deliverability email
Gmail đưa vào spam ban đầu.
Cách sửa:
- Setup SPF, DKIM, DMARC đúng cách
- Làm nóng domain dần dần
- Uy tín người gửi tốt từ đầu
Vấn đề 2: Link xác minh hết hạn
Links không hoạt động sau 24 giờ.
Cách sửa: Thêm kiểm tra hết hạn token, tuỳ chọn gửi lại.
Vấn đề 3: Đăng ký trùng
Người dùng submit form nhiều lần.
Cách sửa: Upsert thay vì insert.
Kết quả
- Tổng thời gian: ~10 giờ (1 ngày dài)
- Chi phí: $0/tháng (dưới giới hạn free tier)
- Subscribers: Sẵn sàng tăng trưởng
- Kiểm soát: 100%
Nếu làm lại sẽ khác
- Bắt đầu với dịch vụ có sẵn trước
Build tuỳ chỉnh chỉ khi chạm giới hạn.
- Analytics đơn giản hơn
Mất quá nhiều thời gian cho tracking. Có thể bỏ qua ban đầu.
- Thông báo lỗi tốt hơn
Lỗi hiển thị cho người dùng quá chung chung.
Kết luận
Tự host = học hỏi + kiểm soát.
Nhưng không phải cho tất cả mọi người.
Nếu bạn chỉ muốn gửi newsletters, dùng ConvertKit.
Nếu bạn muốn học và có nhu cầu cụ thể, build tuỳ chỉnh.
Source code đầy đủ và hướng dẫn setup có trong Tony’s Friends VIP.