Vibe Code
Giáo trình/Phần 4 — Nâng cao

Chất lượng — SEO, analytics và dễ truy cập

Lớp 7 của sơ đồ. Bốn việc làm app đúng thành app có người tìm thấy, đo được và ai cũng dùng được. Phần lớn làm một lần rồi quên.

Cấp 435 phút làm

Lớp 7 trong sơ đồ Vibe Stack có bốn ô: Web Vitals · SEO kỹ thuật · Analytics · Dễ truy cập. Web Vitals đã có bài riêng; bài này nói ba ô còn lại.

Đặc điểm chung của lớp này: không ô nào tạo ra tính năng, và đó là lý do chúng bị bỏ. Nhưng app không ai tìm thấy, không đo được, hoặc người lớn tuổi không đọc nổi — thì tính năng nhiều bao nhiêu cũng vô ích.

SEO kỹ thuật — chỉ 6 việc, làm một lần

Đây là phần SEO mà bạn kiểm soát được bằng mã. Phần nội dung và từ khóa là việc khác, không nằm trong giáo trình này.

1. Mỗi trang một <title> và một <meta description> riêng.

<title>Bánh cuốn Quảng Đông Chang An — Sầm Sơn</title>
<meta name="description" content="Quán bánh cuốn Quảng Đông tại Sầm Sơn. Mở 6h–21h, có chỗ để xe, nhận đặt bàn.">

Lỗi phổ biến nhất của web nhiều trang: mọi trang dùng chung một tiêu đề. Google coi đó là dấu hiệu trang trùng lặp, và kết quả tìm kiếm hiện ra không ai muốn bấm.

2. Thẻ chia sẻ mạng xã hội (Open Graph). Khi dán link vào Zalo, Messenger, Facebook — đây là thứ quyết định nó hiện ra đẹp hay hiện ra một dòng trắng trơn:

<meta property="og:title" content="Bánh cuốn Quảng Đông Chang An">
<meta property="og:description" content="Mở 6h–21h tại Sầm Sơn. Có chỗ để xe.">
<meta property="og:image" content="https://changan.com/anh/og-1200x630.jpg">
<meta property="og:url" content="https://changan.com/">
<meta property="og:type" content="website">

Ảnh phải 1200×630px và là đường dẫn đầy đủ (có https://). Đây là việc 10 phút có tác động nhìn thấy ngay — và với khách hàng Việt Nam, link đẹp trên Zalo đáng giá hơn nhiều thứ SEO khác.

3. Một địa chỉ chính cho mỗi trang. Nếu web vào được bằng cả congty.com và www.congty.com, chọn một làm chính và chuyển hướng 301 cái kia. Thêm thẻ:

<link rel="canonical" href="https://congty.com/bang-gia/">

4. robots.txt và sitemap.xml.

User-agent: *
Allow: /
Sitemap: https://congty.com/sitemap.xml

Sitemap thì để script build tự sinh — liệt kê mọi trang, không cần làm tay.

5. Dữ liệu có cấu trúc, cho đúng loại hình kinh doanh của bạn. Đây là thứ làm Google hiện thêm giờ mở cửa, đánh giá, giá ngay trong kết quả tìm kiếm:

<script type="application/ld+json">
{"@context":"https://schema.org","@type":"Restaurant",
 "name":"Chang An","telephone":"+84823976658",
 "address":{"@type":"PostalAddress","streetAddress":"...","addressLocality":"Sầm Sơn","addressCountry":"VN"},
 "openingHours":"Mo-Su 06:00-21:00",
 "servesCuisine":"Món Hoa"}
</script>

6. Trang quản trị và trang nội bộ phải chặn lập chỉ mục.

<meta name="robots" content="noindex, nofollow">
App nội bộ lọt lên Google — chuyện có thật và rất khó dọn

Một app chấm công để trang đăng nhập công khai, không chặn lập chỉ mục. Ba tháng sau, tìm tên công ty trên Google thì ra trang đăng nhập nội bộ — kèm cả tên app và một phần nội dung trang.

Không phải lỗ hổng bảo mật, nhưng khách rất khó chịu, và gỡ khỏi Google mất hàng tuần dù bạn đã sửa ngay.

Luật: mọi app nội bộ phải có noindex ngay từ ngày deploy đầu tiên, cộng với Disallow: / trong robots.txt. Thêm sau thì đã muộn.

Analytics — đo chuyển đổi, không đo lượt xem

Hầu hết người mới cài công cụ đo rồi chỉ nhìn một con số: số lượt truy cập. Con số đó gần như vô dụng — nó không nói bạn nên sửa gì.

Thứ đáng đo là việc người dùng cần làm xong:

Loại web Đo cái gì
Web giới thiệu quán/dịch vụ Số lượt bấm nút gọi điện, bấm chỉ đường
Landing bán hàng Số lượt gửi form, và bỏ cuộc ở ô nào
App nội bộ Số lượt hoàn thành việc chính, và thời gian làm xong
Blog, tài liệu Trang nào đọc hết, trang nào thoát ngay

Cloudflare Web Analytics là lựa chọn mặc định hợp lý: miễn phí, không cần cookie, không cần banner xin phép — vì nó không theo dõi cá nhân. Bật trong dashboard, Cloudflare tự chèn ở biên.

Mã đo của Cloudflare do biên chèn, không nằm trong mã nguồn

Hai hệ quả hay gây hiểu nhầm: 1. curl trần không thấy nó (Cloudflare chỉ chèn cho yêu cầu có nhận dạng trình duyệt) → đừng vội kết luận là mất. 2. Nó là script defer, không ảnh hưởng FCP/LCP/TBT. Đừng khuyên khách tắt nó để lấy điểm tốc độ — lời khuyên đó sai.

Muốn đo đúng việc của app thì tự ghi, và đây là cách rẻ nhất:

// Gửi một mốc sự kiện — dùng sendBeacon để không chặn thao tác
function ghiMoc(ten, them) {
  try {
    navigator.sendBeacon("/api/moc", JSON.stringify({
      ten, duong: location.pathname, phien_ban: APP_VERSION, ...them
    }));
  } catch (e) {}
}

btnGoi.addEventListener("click", () => ghiMoc("bam-goi-dien"));
formDat.addEventListener("submit", () => ghiMoc("gui-form-dat-ban"));

Lưu vào D1 rồi hiện thành một bảng nhỏ trong trang quản trị. Đừng gửi dữ liệu cá nhân vào mốc sự kiện — chỉ gửi tên việc và đường dẫn.

Con số làm khách gia hạn hợp đồngchuyên gia insight & case thực tế

Khi tới kỳ gia hạn, câu hỏi của khách luôn là "app này mang lại gì?". Câu trả lời tốt nhất không phải danh sách tính năng, mà là một bảng số liệu:

"Tháng 9: 1.240 lượt nhập đơn trên điện thoại, trung bình 38 giây mỗi đơn. Trước đây nhập tay vào Excel mất khoảng 4 phút. Tiết kiệm khoảng 70 giờ công."

Bảng này dựng được chỉ khi bạn đã ghi mốc sự kiện từ đầu. Thêm vào lúc sắp gia hạn thì không có dữ liệu quá khứ.

Nên lời khuyên thực dụng: ngày đầu tiên giao app, hãy ghi mốc cho đúng một việc — việc chính. Một dòng mã. Sáu tháng sau nó là lập luận bán hàng mạnh nhất bạn có.

Dễ truy cập — bốn việc, không cần học chuẩn nào

Không cần đọc tiêu chuẩn quốc tế. Bốn việc dưới đây ăn phần lớn lợi ích, và chúng cũng làm app tốt hơn cho mọi người, không riêng người khuyết tật:

1. Ảnh có mô tả (alt).

<img src="bieu-do.png" alt="Doanh thu tháng 9 tăng 12% so với tháng 8">   <!-- ảnh mang thông tin -->
<img src="hoa-van.svg" alt="">                                            <!-- ảnh trang trí: để rỗng -->

Để rỗng cho ảnh trang trí là đúng, không phải lười — nó báo cho trình đọc màn hình bỏ qua.

2. Tương phản chữ đủ cao. Tỉ lệ tối thiểu 4,5:1 cho chữ thường. Đây là lỗi AI hay mắc nhất: chữ xám nhạt trên nền trắng, trông sang trên màn hình đẹp trong phòng, không đọc nổi ngoài nắng trên điện thoại cũ.

Kiểm nhanh ngay trong trình duyệt: F12 → chọn phần tử → mục màu chữ sẽ hiện tỉ lệ tương phản.

3. Bấm được bằng bàn phím. Nhấn Tab liên tục qua cả trang: mọi nút và liên kết phải nhìn thấy được viền chọn, và thứ tự phải hợp lý. Đừng bao giờ viết outline: none mà không thay bằng viền khác.

4. Nhãn cho ô nhập. Mỗi ô phải có nhãn thật, không chỉ chữ mờ gợi ý:

<label for="sdt">Số điện thoại</label>
<input id="sdt" type="tel" inputmode="numeric" placeholder="09xx xxx xxx">

Chữ gợi ý biến mất khi bắt đầu gõ — người dùng quên ô đó là ô gì. Việc này ảnh hưởng tới mọi người, không riêng ai.

Bố tôi 68 tuổi dùng app của tôingười dùng bình thường góp ý

Và tôi học được nhiều hơn mọi tài liệu về trợ năng. Ba thứ bố tôi vướng:

  1. Chữ xám nhạt — bố tôi nghiêng điện thoại ra ánh sáng rồi vẫn phải hỏi. Tôi đổi thành chữ đen.
  2. Nút nhỏ — bố bấm trượt ba lần rồi cáu. Tôi tăng mọi nút lên 48px.
  3. "Không biết bấm xong thì nó có nhận chưa" — không có phản hồi khi bấm. Tôi thêm chữ "Đang lưu…" ngay trên nút.

Không cái nào là kỹ thuật cao siêu. Và sau khi sửa, nhân viên trẻ trong công ty cũng khen app dễ dùng hơn — dù họ không vướng gì ban đầu.

Kết luận của tôi: làm dễ truy cập không phải làm cho một nhóm nhỏ. Là làm cho tất cả.

Bảng kiểm lớp 7 — chạy trước khi giao

SEO
[ ] Mỗi trang có title và description riêng
[ ] Có thẻ og: — dán link vào Zalo thử xem hiện ra thế nào
[ ] Có canonical, robots.txt, sitemap.xml
[ ] Trang nội bộ/quản trị có noindex

ANALYTICS
[ ] Đã bật công cụ đo
[ ] Đã ghi mốc cho ÍT NHẤT một việc chính
[ ] Có chỗ xem lại số liệu (trang quản trị hoặc dashboard)

DỄ TRUY CẬP
[ ] Mọi ảnh mang thông tin có alt
[ ] Tương phản chữ >= 4,5:1
[ ] Tab qua cả trang, thấy viền chọn rõ
[ ] Mọi ô nhập có nhãn thật

WEB VITALS  -> xem bài Tốc độ web
[ ] Đã đo bằng Lighthouse hoặc PageSpeed, có số thật
Đề rà lớp chất lượngchuyên gia thực thi
Rà project này theo 4 nhóm dưới đây. Với mỗi thiếu sót: ghi file,
dòng, và cách sửa nhỏ nhất. Nhóm nào đã đủ thì ghi "đủ", không
cần giải thích dài.

1 SEO: trang nào thiếu title/description riêng? có thẻ og: chưa?
  có canonical, robots.txt, sitemap không? trang quản trị đã
  noindex chưa?
2 ANALYTICS: có ghi mốc sự kiện nào không? nếu có thì đo việc gì?
3 DỄ TRUY CẬP: liệt kê mọi <img> thiếu alt; mọi input thiếu label;
  mọi chỗ đặt outline:none mà không thay bằng viền khác.
4 Liệt kê mọi cặp màu chữ/nền trong CSS có tỉ lệ tương phản
  dưới 4,5:1 — tính ra số cụ thể, đừng ước lượng.

Chỉ đọc mã, không sửa. Mục 4 phải có con số.

Mục 4 là mục AI làm tốt mà người làm rất ngại: tính tương phản thủ công cho 20 cặp màu thì ai cũng bỏ qua.

Chốt review bài nàychuyên gia review
  • Đủ: 6 việc SEO kỹ thuật, analytics theo hướng đo chuyển đổi, 4 việc dễ truy cập, bảng kiểm, đề rà tự động.
  • Cố ý hẹp: không nói SEO nội dung, không nói từ khóa, không nói backlink — đó là nghề khác và nó thay đổi theo thuật toán. Phần kỹ thuật trong bài này thì bền.
  • Đã trả giá thật: app nội bộ lọt lên Google vì thiếu noindex.
  • Rủi ro còn lại: phần dễ truy cập ở đây là mức tối thiểu, không phải tuân thủ tiêu chuẩn WCAG. Nếu app phục vụ cơ quan nhà nước hoặc có yêu cầu pháp lý về trợ năng, cần người có nghề.
Bài tập chốt
  1. Chạy đề rà lớp chất lượng, sửa hết nhóm 1 và nhóm 3.
  2. Dán link web của bạn vào Zalo và xem nó hiện ra thế nào. Xấu thì sửa thẻ og:.
  3. Ghi mốc cho một việc chính của app. Chờ một tuần rồi xem số liệu.
  4. Nhấn Tab qua cả trang chính — nếu có chỗ nào "mất dấu" không biết đang chọn gì, sửa viền chọn.
  5. Nếu app là app nội bộ: kiểm noindex đã có chưa. Chưa thì làm ngay hôm nay.