Tuần này tôi rà lại robots.txt của chính site này và tìm ra một lỗi: dòng khai sitemap trỏ tới bản có www, trong khi bản chuẩn của site là không có www. Mỗi lần Googlebot tải sitemap là thêm một lượt chuyển hướng thừa.

Nhưng thứ đáng nói hơn là quyết định tôi không làm: không chặn trang quản trị và trang tìm kiếm nội bộ trong robots.txt, dù gần như mọi mẫu robots.txt trên mạng đều khuyên như vậy. Lý do nằm ở chỗ nhiều người hiểu ngược: chặn thu thập và chặn lập chỉ mục là hai việc khác nhau, và chọn nhầm công cụ cho kết quả trái với mong muốn.

Bài này giải thích sự khác biệt đó, khi nào dùng cái nào, và tại sao dùng Disallow để gỡ một trang khỏi Google lại là cách chắc chắn giữ nó ở lại.

Hai việc khác nhau, hay bị gộp làm một

Trước khi nói về cú pháp, cần tách bạch hai hành động của công cụ tìm kiếm:

  • Thu thập (crawl) là việc bot tải nội dung một URL về. Đây là chỗ robots.txt có tiếng nói.
  • Lập chỉ mục (index) là việc đưa URL đó vào cơ sở dữ liệu để có thể xuất hiện trên kết quả tìm kiếm. Đây là chỗ thẻ meta robots có tiếng nói.

Hai việc này diễn ra nối tiếp nhau nhưng không phụ thuộc nhau theo cách người ta hay nghĩ. Google có thể lập chỉ mục một URL mà chưa từng tải nội dung của nó, nếu có đủ liên kết từ nơi khác trỏ tới. Ngược lại, Google có thể tải một trang về rồi quyết định không lập chỉ mục.

robots.txt nói "đừng vào". Thẻ noindex nói "vào được, nhưng đừng đưa lên kết quả tìm kiếm". Muốn ra lệnh thứ hai thì bắt buộc phải cho phép việc thứ nhất.

robots.txt là gì

Một tệp văn bản thuần đặt ở thư mục gốc của tên miền, tại đúng đường dẫn /robots.txt. Nó chứa các chỉ dẫn cho bot về những phần nào của website chúng không nên tải.

Ba đặc tính hay bị bỏ qua:

  • Phạm vi tính theo từng host. https://example.com/robots.txt chỉ áp dụng cho https://example.com. Tên miền phụ có robots.txt riêng, và bản http cũng vậy về mặt kỹ thuật.
  • Nó là đề nghị, không phải hàng rào. Googlebot và các bot lớn tuân thủ. Bot thu thập nội dung để dùng lại, bot dò lỗ hổng, và bất kỳ ai mở trình duyệt thì không.
  • Nó công khai với tất cả mọi người. Ai cũng mở được /robots.txt của bạn. Liệt kê đường dẫn nhạy cảm trong đó là tự chỉ đường.

Cú pháp cần biết

Một file tối thiểu và đủ dùng cho blog:

User-agent: *
Allow: /

Sitemap: https://example.com/sitemap.xml

Các chỉ thị:

  • User-agent — bot nào áp dụng nhóm quy tắc phía dưới. Dấu * nghĩa là mọi bot. Một bot chỉ đọc một nhóm: nhóm khai đích danh tên nó, nếu không có thì mới rơi vào nhóm *.
  • Disallow — đường dẫn không nên tải. Khớp theo tiền tố, nên Disallow: /tin chặn cả /tin-tuc lẫn /tintuc-abc.
  • Allow — mở lại một nhánh con nằm trong vùng đã chặn.
  • Sitemap — đường dẫn tuyệt đối tới sitemap. Chỉ thị này độc lập với các nhóm User-agent, đặt ở đâu trong file cũng được, và mọi công cụ tìm kiếm đều đọc.

Hai ký tự đặc biệt: * thay cho chuỗi ký tự bất kỳ, $ đánh dấu kết thúc URL. Ví dụ Disallow: /*.pdf$ chặn mọi URL kết thúc bằng đuôi pdf.

Khi một URL khớp nhiều quy tắc, quy tắc có đường dẫn dài hơn thắng, không phải quy tắc đứng trước. Nếu độ dài bằng nhau thì Allow thắng. Đây là chỗ hay gây bất ngờ:

User-agent: *
Disallow: /tai-lieu/
Allow: /tai-lieu/mien-phi/

Toàn bộ /tai-lieu/ bị chặn, trừ nhánh /tai-lieu/mien-phi/ được mở lại vì quy tắc đó cụ thể hơn.

Lỗi kinh điển: dùng Disallow để gỡ trang khỏi Google

Đây là tình huống lặp đi lặp lại. Một trang không nên xuất hiện trên tìm kiếm — trang cảm ơn sau khi điền form, trang kết quả lọc, một bài cũ đã lỗi thời. Người quản trị thêm một dòng Disallow rồi chờ nó biến mất.

Nó không biến mất. Thường thì tệ hơn: URL vẫn nằm trên kết quả tìm kiếm, nhưng giờ không có tiêu đề tử tế và phần mô tả bị thay bằng dòng thông báo rằng không có thông tin cho trang này.

Cơ chế rất đơn giản một khi đã tách bạch hai khái niệm ở đầu bài. Thẻ noindex nằm bên trong trang. Muốn đọc được nó, Googlebot phải tải trang về. Bạn vừa cấm nó tải trang. Nên lệnh gỡ nằm im trong một tệp mà Google không được phép mở.

Còn URL vẫn lọt vào chỉ mục vì Google học được sự tồn tại của nó từ nơi khác: liên kết từ trang khác trong site, liên kết từ website khác, hoặc chính sitemap của bạn. Có URL, không có nội dung, kết quả là một dòng trơ trọi trên trang tìm kiếm.

Trình tự đúng để gỡ một trang:

  1. Bỏ mọi dòng Disallow đang chặn URL đó.
  2. Thêm <meta name="robots" content="noindex"> vào trang.
  3. Đợi Google thu thập lại. Muốn nhanh thì dùng công cụ Kiểm tra URL trong Search Console rồi yêu cầu lập chỉ mục — nghe ngược đời nhưng đó là cách đẩy nhanh việc bot quay lại đọc lệnh mới.
  4. Chỉ khi URL đã rời chỉ mục, nếu vẫn muốn tiết kiệm lượt thu thập thì mới thêm Disallow.

Bước 4 gần như không cần với site nhỏ. Đừng làm nếu không có lý do rõ ràng.

Một lưu ý về noindex trong robots.txt

Có một thời gian Google âm thầm hỗ trợ chỉ thị Noindex: ngay trong robots.txt, và nhiều bài hướng dẫn cũ vẫn dạy cách này. Google đã ngừng hỗ trợ từ tháng 9 năm 2019.

Nếu file của bạn có dòng đó, nó đang không làm gì cả. Đây cũng là một cách nhanh để đánh giá độ mới của một bài hướng dẫn SEO: bài nào còn dạy Noindex: trong robots.txt thì phần còn lại cũng nên kiểm chứng lại.

Thẻ meta robots và tiêu đề X-Robots-Tag

Thẻ meta đặt trong phần <head>:

<meta name="robots" content="noindex, follow">

Các giá trị đáng dùng:

Giá trịTác dụng
index / noindexCho phép hoặc cấm đưa trang vào chỉ mục. Không khai gì thì mặc định là index.
follow / nofollowCó đi theo các liên kết trên trang hay không.
noarchiveKhông lưu bản sao trong bộ nhớ đệm.
nosnippetKhông hiển thị đoạn mô tả trên kết quả tìm kiếm.
max-snippet:150Giới hạn độ dài đoạn mô tả.
max-image-preview:largeCho phép ảnh xem trước cỡ lớn. Nên bật với bài viết có ảnh tốt.
noimageindexKhông lập chỉ mục ảnh trên trang.

Về cặp noindex, nofollow: dùng nó nhiều hơn mức cần thiết là một thói quen xấu. Với trang bạn muốn ẩn khỏi tìm kiếm nhưng vẫn có liên kết hữu ích ra ngoài — chẳng hạn trang kết quả tìm kiếm nội bộ — hãy dùng noindex, follow. Bot vẫn đi theo liên kết trên đó để tìm ra các bài bên trong. Đó cũng là cách site này đang cấu hình cho trang tìm kiếm.

Với tệp không phải HTML — PDF, hình ảnh, tệp tải về — không có chỗ đặt thẻ meta. Lúc đó dùng tiêu đề HTTP:

X-Robots-Tag: noindex

Khai ở tầng máy chủ hoặc trong mã ứng dụng. Trong Laravel có thể trả tiêu đề này kèm response của route phục vụ tệp.

Muốn gì thì dùng cái gì

Mục tiêuCông cụ đúng
Gỡ một trang HTML khỏi kết quả tìm kiếmmeta robots noindex, và phải cho phép thu thập
Gỡ một tệp PDF hoặc ảnh khỏi kết quảTiêu đề X-Robots-Tag: noindex
Ngăn bot tiêu tốn tài nguyên máy chủ ở một nhánh URLrobots.txt Disallow
Che nội dung khỏi mắt người ngoàiĐăng nhập hoặc phân quyền. Không phải robots.txt, không phải noindex
Gom nhiều URL trùng nội dung về một bảnThẻ canonical
Không cho bot đi theo một liên kết cụ thểrel="nofollow" trên chính thẻ liên kết

Trên một blog thì nên noindex những trang nào

Danh sách ngắn, và nên giữ cho nó ngắn:

  • Trang kết quả tìm kiếm nội bộ. Nội dung sinh động theo truy vấn, không có giá trị riêng, và có thể tạo ra vô số URL. Dùng noindex, follow.
  • Trang đăng nhập và toàn bộ khu quản trị. noindex, nofollow. Đặt thẻ ở layout admin là xong một lần cho mọi trang bên trong.
  • Trang cảm ơn, trang xác nhận sau khi gửi form. Không có lý do gì để chúng xuất hiện trên tìm kiếm.
  • Trang lọc theo thẻ chỉ có một hai bài. Nội dung quá mỏng. Nhưng cách xử lý tốt hơn là gộp thẻ lại cho đỡ vụn, thay vì noindex hàng loạt.

Một trường hợp không nên noindex: các trang phân trang của danh mục, kiểu /blog?page=2. Chúng là đường dẫn để bot đi tới các bài cũ. Đặt noindex lên đó, và theo thời gian Google sẽ giảm cả việc đi theo liên kết trên những trang này, khiến bài cũ khó được thu thập lại. Cứ để chúng index, follow bình thường.

robots.txt không phải công cụ bảo mật

Điểm này đáng tách riêng vì hậu quả nghiêm trọng hơn mọi lỗi SEO trong bài.

Tệp /robots.txt của bạn ai cũng đọc được, không cần quyền gì. Mỗi dòng Disallow là một lời tuyên bố công khai rằng "ở đây có thứ tôi không muốn ai xem". Với người dò tìm lỗ hổng, đó là bản chỉ dẫn.

Đó là lý do robots.txt của site này không có dòng nào chặn đường dẫn quản trị, dù đường dẫn ấy đã được đổi khỏi tên mặc định. Khu quản trị được bảo vệ bằng đăng nhập và phân quyền, còn việc không xuất hiện trên tìm kiếm thì do thẻ noindex trong layout đảm nhiệm. Không cần và không nên nhắc tới nó trong một tệp công khai.

Nguyên tắc: thứ gì thật sự cần giữ kín thì đặt sau lớp xác thực. Nếu chỉ cần nó không lên Google thì dùng noindex. robots.txt không giải quyết cả hai.

Khi nào robots.txt thật sự hữu ích

Sau khi đã liệt kê những việc nó không làm được, cần nói cho công bằng về những việc nó làm tốt:

  • Chặn các URL tham số sinh ra vô hạn. Bộ lọc trên trang danh mục có thể tạo ra hàng nghìn tổ hợp không có giá trị riêng. Đây là lý do chính đáng nhất.
  • Chặn các endpoint tốn tài nguyên mà bot hay gọi vào — tìm kiếm nội bộ có truy vấn nặng, các đường dẫn xuất dữ liệu.
  • Khai đường dẫn sitemap cho mọi công cụ tìm kiếm cùng lúc, không riêng Google. Chi tiết về sitemap tôi đã viết trong bài về sitemap XML.

Với một blog vài chục tới vài trăm bài, không có bộ lọc phức tạp, file bốn dòng ở đầu bài là đủ. Mỗi dòng Disallow thêm vào là thêm một khả năng chặn nhầm.

Cách kiểm tra

Công cụ robots.txt Tester độc lập ngày trước đã bị gỡ. Giờ có hai chỗ để kiểm tra trong Search Console.

Báo cáo robots.txt, nằm trong phần Cài đặt. Nó cho biết Google tải file lần gần nhất khi nào, trạng thái ra sao, và nội dung mà Google thật sự đọc được — hữu ích khi bạn vừa sửa file mà chưa thấy tác dụng.

Báo cáo robots.txt trong phần Cài đặt của Google Search Console
Báo cáo robots.txt nằm trong Cài đặt, không nằm cùng khu với sitemap — chỗ này hay bị tìm nhầm.

Công cụ Kiểm tra URL, dán một URL cụ thể vào ô tìm kiếm trên cùng. Nó trả lời trực tiếp câu hỏi quan trọng nhất: URL này có bị chặn không, và nếu bị chặn thì bởi dòng nào.

Kiểm tra nhanh bằng dòng lệnh:

# Xem nội dung file máy chủ đang phục vụ
curl -s https://example.com/robots.txt

# Kiểm tra một trang có trả về X-Robots-Tag không
curl -sI https://example.com/tai-lieu/file.pdf | grep -i robots

# Kiểm tra thẻ meta robots trong HTML
curl -s https://example.com/tim-kiem | grep -i 'name="robots"'

Sáu lỗi thường gặp

LỗiHậu quả
Dùng Disallow để gỡ trang khỏi chỉ mụcTrang ở lại chỉ mục, mất luôn tiêu đề và mô tả.
Vừa Disallow vừa đặt noindexLệnh noindex không bao giờ được đọc. Hai lệnh triệt tiêu nhau.
Để nguyên Disallow: / từ môi trường thử nghiệmToàn bộ website biến mất khỏi Google. Lỗi hiếm nhưng thiệt hại lớn nhất.
Chặn thư mục chứa CSS và JavaScriptGoogle không dựng được giao diện trang, đánh giá sai trải nghiệm trên di động.
Liệt kê đường dẫn quản trị trong robots.txtCông khai chính thứ mình muốn giấu.
Dòng Sitemap trỏ tới URL bị chuyển hướngThêm một lượt 301 mỗi lần bot tải sitemap. Đúng lỗi tôi vừa gặp ở đầu bài.

Tóm lại

Ba câu đủ để nhớ cả bài:

  1. robots.txt điều khiển việc tải nội dung. Thẻ meta robots điều khiển việc hiển thị trên kết quả tìm kiếm.
  2. Muốn một trang biến mất khỏi Google thì phải để Google vào đọc lệnh noindex. Chặn cửa là giữ nó ở lại.
  3. Không thứ gì trong hai công cụ này là bảo mật. Cần giữ kín thì dùng đăng nhập.

Với phần lớn blog, robots.txt đúng là một file bốn dòng và không bao giờ cần sửa lại. Nếu file của bạn dài hơn mười dòng, nhiều khả năng bạn đang giải quyết nhầm bài toán bằng nhầm công cụ.