Slug tiếng Việt là chỗ mà rất nhiều hệ thống làm sai: để nguyên dấu thành chuỗi %E1%BB%91, quên chữ "đ", giữ cả câu tiêu đề mười mấy chữ, hoặc để CMS âm thầm thêm -2. Bài này viết một slug generator cho tiếng Việt và một bước kiểm tra trùng, dựa trên những gì tài liệu cấu trúc URL của Google Search Central khuyến nghị.
Google khuyến nghị gì
- Dùng dấu gạch ngang để tách từ, không dùng gạch dưới và không viết liền.
- URL phân biệt chữ hoa, chữ thường, nên
/Collagenvà/collagenlà hai địa chỉ khác nhau. - Từ khóa trong đường dẫn gần như không ảnh hưởng thứ hạng ngoài breadcrumb. Mục tiêu là URL rõ nghĩa và ổn định, không phải nhồi từ khóa.
- Khi đổi URL lâu dài, dùng chuyển hướng phía máy chủ loại vĩnh viễn như 301.
Bỏ dấu tiếng Việt đúng cách
Chuẩn hóa Unicode NFD tách dấu ra khỏi chữ, nhưng chữ "đ" không phải chữ "d" có dấu, nên phải xử lý riêng:
import re
import unicodedata
def bo_dau(s: str) -> str:
s = s.replace("đ", "d").replace("Đ", "D")
s = unicodedata.normalize("NFD", s)
return "".join(c for c in s if unicodedata.category(c) != "Mn")
Rút gọn về từ khóa chính
Slug tốt chỉ giữ từ khóa chính, bỏ các từ thừa như "cách", "hướng dẫn", "chi tiết", "mới nhất", và không chứa năm. Năm có thể nằm trong title, nhưng URL thì không, vì bài sẽ còn được cập nhật nhiều năm.
TU_THUA = {"cach", "huong", "dan", "chi", "tiet", "moi", "nhat", "cua", "va", "cho"}
def tao_slug(tieu_de: str, toi_da: int = 6) -> str:
s = bo_dau(tieu_de).lower()
s = re.sub(r"\b(19|20)\d{2}\b", " ", s)
tu = re.findall(r"[a-z0-9]+", s)
giu = [t for t in tu if t not in TU_THUA] or tu
return "-".join(giu[:toi_da])
Danh sách từ thừa ở trên chỉ là điểm khởi đầu. Bỏ "cach" hay "nhat" một cách máy móc có thể làm mất nghĩa ("loai nao tot nhat" là một cụm có nghĩa), nên slug sinh ra nên là gợi ý để người viết duyệt, không phải giá trị cuối cùng.
Chặn đuôi -2 trước khi CMS tự thêm
WordPress thêm -2, -3 khi slug đã tồn tại, kể cả ở bài trong thùng rác, bản nháp cũ hoặc trang đính kèm ảnh. Đuôi này thường là dấu hiệu hai trang cùng chủ đề. Thay vì để CMS tự xử lý, hãy kiểm tra trước và trả lỗi rõ ràng:
def kiem_tra_slug(slug: str, slug_da_co: dict) -> str:
"""slug_da_co: {slug: (trang_thai, url)} gồm cả trash, draft, attachment"""
if slug in slug_da_co:
trang_thai, url = slug_da_co[slug]
return f"Slug '{slug}' đã dùng bởi {url} ({trang_thai}). Xem lại trang đó trước."
return ""
Trên WordPress, danh sách slug đã có lấy được bằng WP-CLI: wp post list --post_type=any --post_status=any --fields=post_name,post_status,guid --format=json. Chú ý --post_status=any không bao gồm thùng rác; cần gọi thêm với --post_status=trash.
Đổi URL đã đăng
Khi buộc phải đổi slug của trang đang có traffic: tạo chuyển hướng 301 phía máy chủ từ URL cũ sang URL mới, cập nhật mọi link nội bộ trỏ thẳng vào URL mới thay vì đi qua chuyển hướng, rồi yêu cầu lập chỉ mục URL mới trong Search Console. Quy tắc đặt slug cho người viết nội dung, bảng slug mẫu theo ngành và cách cài permalink có trong bài URL chuẩn SEO là gì trên Onic.vn.
Top comments (0)