Heading là phần HTML mà developer và người viết nội dung cùng chạm vào: theme quyết định tiêu đề bài có phải H1 không, widget quyết định tên sidebar là H3 hay H4, còn người viết quyết định phần còn lại. Kết quả thường là một dàn heading mà không ai nhìn trọn. Bài này đi qua những gì Google nói về heading và một script audit cho cả trang.
Google nói gì
Hướng dẫn SEO cơ bản của Google Search Central nói heading theo đúng thứ tự ngữ nghĩa rất tốt cho trình đọc màn hình, nhưng với Google Search thì không đúng thứ tự cũng không sao, và không có số lượng heading lý tưởng. Google cũng từng xác nhận nhiều H1 không làm trang bị phạt.
Vậy tại sao vẫn audit? Vì hai lý do. Thứ nhất là accessibility: người dùng trình đọc màn hình điều hướng bằng heading, và nhảy cấp làm họ khó hiểu bố cục. Thứ hai, AI chat và AI Overview thường tách trang thành từng đoạn theo heading để chọn đoạn trả lời, nên heading rõ nghĩa giúp đúng đoạn được chọn.
Lấy dàn heading của trang
from bs4 import BeautifulSoup
def dan_heading(html: str) -> list:
soup = BeautifulSoup(html, "html.parser")
ket_qua = []
for h in soup.find_all(["h1", "h2", "h3", "h4", "h5", "h6"]):
cap = int(h.name[1])
chu = h.get_text(" ", strip=True)
trong = h.find_parent(["header", "footer", "aside", "nav"])
ket_qua.append({"cap": cap, "chu": chu, "vung": trong.name if trong else "main"})
return ket_qua
Trường vung rất hữu ích: heading nằm trong footer, aside hay nav thường là heading trang trí của theme, không thuộc bố cục nội dung.
Các kiểm tra nên chạy
CHUNG_CHUNG = {"giới thiệu", "thông tin thêm", "lưu ý", "liên hệ", "tìm hiểu thêm"}
def audit(ds: list) -> list:
loi = []
h1 = [h for h in ds if h["cap"] == 1]
if len(h1) != 1:
loi.append(f"Có {len(h1)} H1: {[h['chu'] for h in h1]}")
truoc = 1
for h in ds:
if h["vung"] != "main":
loi.append(f"Heading trong {h['vung']}: H{h['cap']} '{h['chu']}'")
continue
if h["cap"] > truoc + 1:
loi.append(f"Nhảy cấp H{truoc} -> H{h['cap']}: '{h['chu']}'")
if not h["chu"]:
loi.append(f"H{h['cap']} rỗng")
elif h["chu"].lower().rstrip(":") in CHUNG_CHUNG or h["chu"].lower().startswith("phần "):
loi.append(f"Heading không mang nghĩa: '{h['chu']}'")
truoc = h["cap"]
return loi
Danh sách heading chung chung là heuristic. Nó không thay được người đọc, nhưng lọc ra những ứng viên rõ ràng nhất để người viết sửa.
Những lỗi theme hay gây ra
- Logo hoặc tên website bọc trong H1 trên mọi trang, cộng với H1 tiêu đề bài là hai H1.
- Tên widget sidebar dùng H2 hoặc H3, xen giữa dàn heading của nội dung.
- Tiêu đề sản phẩm liên quan ở cuối trang dùng H2, nhiều hơn cả H2 của bài.
Sửa ở tầng template: đổi các tiêu đề trang trí sang p hoặc div có class, giữ heading cho bố cục nội dung.
Kiểm tra nhanh không cần code
Người viết nội dung có thể dùng tiện ích HeadingsMap trên Chrome, hoặc nút "Chế độ xem dạng danh sách" trong trình soạn thảo khối WordPress. Phép thử cuối cùng vẫn là con người: chỉ đọc dàn heading, có hiểu bài trả lời gì không. Quy tắc đặt heading cho người viết, gồm dàn mẫu cho bài blog, trang sản phẩm và trang dịch vụ, có trong bài Heading là gì trên Onic.vn.
Top comments (0)