Vibe Code
Giáo trình/Phần 1 — Trang web đầu tiên

Đưa lên Internet bằng Cloudflare Pages

Ba cách deploy (kéo-thả, dòng lệnh, nối Git), chọn cách nào, gắn tên miền riêng, và bẫy đuôi .html của Pages.

Cấp 130 phút làm

Cuối bài này bạn có một địa chỉ công khai kiểu ten-cua-ban.pages.dev, mở được từ điện thoại của bất kỳ ai, miễn phí, không giới hạn lượt truy cập ở gói free.

Pages là gì (và không là gì)

Cloudflare Pages phục vụ file tĩnh: HTML, CSS, JS, ảnh. Người dùng gọi tới, Cloudflare trả file từ máy chủ gần họ nhất. Không có mã nào chạy phía máy chủ.

Nghĩa là Pages làm được: web giới thiệu, landing, blog, tài liệu, app chỉ chạy trong trình duyệt (lưu localStorage), bảng giá, catalogue. Và không làm được: lưu dữ liệu chung cho nhiều người, đăng nhập thật, gửi email, gọi API có khóa bí mật. Những việc đó cần Workers (Cấp 3).

Pages và Workers đang hợp nhất

Cloudflare đang gộp Pages vào Workers (Workers Static Assets). Thực tế 2026: cả hai vẫn chạy tốt, nhưng project mới nên nghĩ theo hướng Workers + static assets vì nó cho bạn đường nâng cấp liền mạch khi cần thêm backend. Bài này dạy Pages trước vì nó đơn giản nhất để có kết quả đầu tiên; bài Workers sẽ nối tiếp.

Cách 1 — Kéo thả (3 phút, không cần lệnh)

Dùng cho lần đầu, để thấy nó chạy thật.

  1. Vào dash.cloudflare.com → Workers & Pages → Create → tab Pages → Upload assets.
  2. Đặt tên project (chữ thường, gạch nối — tên này thành địa chỉ: ten-project.pages.dev).
  3. Kéo thư mục chứa index.html vào ô. Không nén zip, kéo cả thư mục.
  4. Deploy site → chờ ~20 giây → bấm link.

Xong. Gửi link đó cho ai cũng mở được.

Nhược điểm: lần sau sửa file là phải kéo lại tay. Chịu được 2–3 lần, sau đó bạn sẽ muốn Cách 2.

Cách 2 — Dòng lệnh (cách dùng hằng ngày)

Đây là cách Claude Code làm hộ bạn được, và là cách bạn dùng suốt giáo trình.

cd C:\NVAI\Claude\web-dau-tien
wrangler pages deploy . --project-name=web-dau-tien

Lần đầu nó hỏi tạo project mới — chọn Create a new project, và nhánh thì chọn main.

Kết quả in ra hai link:

✨ Deployment complete!
  https://abc12345.web-dau-tien.pages.dev   ← bản VỪA đẩy (link riêng)
  https://web-dau-tien.pages.dev            ← bản CHÍNH (người dùng vào)

Hiểu đúng hai link này là ý quan trọng nhất của bài. Link thứ nhất chỉ trỏ tới đúng bản vừa đẩy, không bao giờ đổi. Link thứ hai luôn trỏ tới bản mới nhất.

Nếu thư mục của bạn có cả file nguồn không muốn công khai (ghi chú, file .md, script), hãy deploy từ một thư mục con sạch:

wrangler pages deploy dist --project-name=web-dau-tien
Deploy cả thư mục là deploy cả thứ không nên công khai

wrangler pages deploy . đẩy mọi thứ trong thư mục đó lên mạng, kể cả ghi-chu-noi-bo.txt hay bang-gia-goc.xlsx. Chúng không hiện trên trang, nhưng ai biết đường dẫn là tải được.

Luật: chỉ deploy một thư mục chỉ chứa thứ dành cho công chúng (thường đặt tên dist hoặc public). Mọi file nháp để ngoài thư mục đó.

Cách 3 — Nối Git (cách của sản phẩm thật)

Pages tự theo một repo GitHub: bạn git push, web tự cập nhật. Không cần gõ lệnh deploy nữa.

Dashboard → Create → Pages → Connect to Git → chọn repo → cấu hình:

Ô Điền gì (web một file)
Production branch main
Build command để trống
Build output directory / (hoặc dist nếu bạn có bước build)

Từ đó: mỗi git push vào main là bản chính cập nhật; mỗi push vào nhánh khác được một link preview riêng — đúng thứ bạn cần ở Cấp 5 để test trước khi cho người dùng thấy.

Cách 3 là đích đến. Bạn sẽ chuyển sang nó sau khi học Git ở Cấp 2 (Actions nói chi tiết).

Hai link preview/production là thứ bán được hợp đồngchuyên gia insight & case thực tế

Khi làm cho khách, tôi không bao giờ gửi bản thật trước. Tôi gửi link preview kèm câu: "Anh xem thử, chưa ai thấy đâu, anh gật thì em đưa lên."

Hiệu quả không phải về kỹ thuật mà về tâm lý: khách thấy mình được quyền quyết định, và góp ý rất thẳng. Nếu gửi bản thật, khách vào vai người bị đặt vào việc đã rồi, và góp ý trở nên khó nói. Trong 2 năm, đây là thói quen đem lại ít tranh cãi nhất, chỉ tốn thêm một lệnh.

Gắn tên miền riêng

pages.dev dùng được mãi, nhưng khách doanh nghiệp sẽ muốn congty.com.

Nếu tên miền đã nằm trên Cloudflare (bạn đã chuyển DNS về): Pages project → Custom domains → Set up a domain → nhập → Cloudflare tự thêm bản ghi. Chứng chỉ HTTPS tự có trong vài phút.

Nếu tên miền ở nhà cung cấp khác (ví nhà đăng ký trong nước): thêm một bản ghi CNAME trỏ về ten-project.pages.dev. Với tên miền gốc (không có www), nhiều nhà cung cấp không cho CNAME ở gốc — khi đó dùng www.congty.com và đặt chuyển hướng từ gốc sang www.

Pages không gắn được tên miền đang dùng cho một Worker khác

Một tên miền/subdomain chỉ thuộc một nơi. Nếu app.congty.com đang trỏ vào một Worker, bạn không gắn nó cho Pages được nữa — và thông báo lỗi khá tối nghĩa.

Cách đã dùng thật khi gặp: giữ Worker ở tên miền đó và cho Worker chuyển tiếp sang Pages, hoặc đổi sang subdomain khác. Nhớ ràng buộc này trước khi hứa với khách một địa chỉ cụ thể.

Bẫy đuôi .html — đọc kỹ, mất nửa buổi

Pages tự bỏ đuôi .html khỏi địa chỉ. File lien-he.html được phục vụ tại /lien-he, và nếu ai vào /lien-he.html thì bị chuyển hướng về /lien-he.

Hậu quả thật: bạn viết liên kết trong HTML là href="lien-he.html" → mỗi lần bấm là một lượt chuyển hướng thừa; và nếu có tham số hoặc dấu neo thì đôi khi mất.

Luật: viết liên kết nội bộ không có đuôi — href="/lien-he". Hoặc cách gọn hơn, dùng ở chính site này: mỗi trang là một thư mục chứa index.html, liên kết là /lien-he/. Cách này chạy đúng cả trên Pages, trên Workers, và cả khi mở bằng máy chủ cục bộ.

Kiểm sau khi deploy — 6 mục, 3 phút

Đừng tin "deploy thành công" là xong. Luật trong giáo trình này: deploy rồi phải kiểm trên bản thật.

  1. Mở link bản chính bằng cửa sổ ẩn danh (tránh bộ nhớ đệm của trình duyệt bạn).
  2. Mở trên điện thoại thật, mạng 4G, không phải Wi-Fi nhà.
  3. Bấm thử mọi nút — nhất là nút gọi điện và nút chỉ đường.
  4. Kiểm chữ tiếng Việt không bị thành ký tự lạ.
  5. F12 → tab Console: không có dòng đỏ.
  6. Xem tiêu đề tab và mô tả khi dán link vào Zalo/Messenger (<title>, <meta name="description">).
# kiểm nhanh bằng dòng lệnh: trang trả về 200 và đúng bản mới?
curl -I https://web-dau-tien.pages.dev
curl -s https://web-dau-tien.pages.dev | findstr "Chang An"
Phút tôi tin rằng mình làm đượcngười dùng bình thường góp ý

Tôi deploy xong, gửi link cho vợ qua Zalo, vợ mở ra trên điện thoại và nhắn lại "ơ, cái này của anh làm á?". Cảm giác đó mạnh hơn mọi bài đọc. Góp ý của tôi: làm tới bước này ngay trong ngày đầu, đừng để sau. Rất nhiều người học hai tuần mà chưa có cái gì cho người khác xem, rồi nguội.

Một lưu ý nhỏ nhưng thật: lần đầu tôi gửi link abc12345.web-dau-tien.pages.dev (link preview) cho mấy người, hôm sau sửa web thì họ vẫn thấy bản cũ, tưởng tôi chưa sửa. Gửi cho người khác thì gửi link ngắn (bản chính).

Đưa cả quy trình này cho Claude Codechuyên gia thực thi

Sau khi làm tay một lần cho hiểu, lần sau chỉ cần:

Deploy thư mục dist lên Cloudflare Pages, project tên web-dau-tien.
Sau khi deploy xong: curl lại link bản chính, kiểm mã trả về 200 và
kiểm trong HTML có chứa chữ "Chang An". Báo cho tôi cả hai kết quả.

Chú ý nửa sau của đề — bắt nó tự kiểm chứng. Đây là khác biệt lớn nhất giữa Claude Code và chép-dán từ web: nó chạy được lệnh, nên nó chứng minh được việc nó nói là xong.

Chốt review bài nàychuyên gia review
  • Đã kiểm: cả ba cách deploy, gắn tên miền ở hai tình huống (trong/ngoài Cloudflare), bẫy .html và bẫy xung đột tên miền với Worker — đều từ sự cố thật.
  • Chưa nói: _headers, _redirects, bộ nhớ đệm, hàm Pages Functions. Để ở Tốc độ web và Workers.
  • Rủi ro còn lại: site của bạn đang không có bản sao nào ngoài máy bạn và Cloudflare. Hết Cấp 2 thì phải nằm trên GitHub.
Bài tập chốt Cấp 1 — phần 1

Deploy trang của bạn, rồi sửa một chữ và deploy lại, bấm đồng hồ. Mục tiêu: dưới 5 phút cho cả vòng sửa–đẩy–kiểm. Nếu quá 5 phút, tìm xem bước nào chậm — thường là do bạn chưa nhớ lệnh; viết lệnh đó vào một file ghi-chu.md trong project.