Chuyển đổi văn bản thành Slug (URL)
Chuẩn hóa văn bản thành slug thân thiện với URL, hỗ trợ chuyển thành chữ thường, ký tự phân cách và loại bỏ từ dừng tùy chỉnh.
Tại sao cần Slugify?
🔍 Tối ưu SEO
Từ khóa trong URL giúp công cụ tìm kiếm hiểu nội dung trang, cải thiện thứ hạng. Ví dụ: example.com/blog/how-to-learn-javascript thân thiện hơn example.com/blog/123.
👁️ Tính dễ đọc và chia sẻ
Người dùng có thể biết nội dung chỉ bằng cách nhìn vào URL, rất thân thiện khi chia sẻ trên mạng xã hội và dễ ghi nhớ, nhập thủ công.
💻 Tương thích hệ thống
Tránh lỗi do ký tự đặc biệt trong tên tệp/URL, tương thích đa nền tảng (Windows/Linux/Mac), tránh vấn đề mã hóa.
🗄️ Thân thiện với cơ sở dữ liệu
Dùng làm định danh duy nhất (ví dụ: tên người dùng, thẻ), tránh rủi ro SQL injection, hỗ trợ lập chỉ mục và truy vấn dễ dàng.
Slugify là gì?
Slug là chuỗi văn bản đã được chuẩn hóa để sử dụng làm URL, tên tệp hoặc định danh. Các xử lý phổ biến bao gồm đồng nhất chữ hoa/thường, loại bỏ dấu câu và nối các từ bằng ký tự phân cách.
- Ưu tiên ASCII: Loại bỏ dấu nhấn và ký hiệu, chỉ giữ lại chữ cái, số và khoảng trắng
- Tương thích Unicode: Chuẩn hóa NFKD cho hầu hết các ký tự ngôn ngữ trước khi xử lý
- Thân thiện với URL: Kết quả chỉ chứa chữ cái, số và ký tự phân cách, có thể dùng trực tiếp trong đường dẫn
Câu hỏi thường gặp
Q: Các ký tự Trung Quốc sẽ được xử lý thế nào?
A: Mặc định sẽ loại bỏ dấu thanh điệu và giữ lại các chữ cái pinyin. Các từ thuần Trung Quốc có thể trở thành rỗng; nên chuyển đổi thủ công sang pinyin trước khi slugify, hoặc dùng công cụ chuyển đổi pinyin Trung Quốc.
Q: Tại sao kết quả của tôi lại trống?
A: Có thể đầu vào chỉ gồm dấu câu/biểu tượng/khoảng trắng, hoặc sau khi lọc từ dừng không còn từ nào. Hãy thử tắt tùy chọn từ dừng hoặc điều chỉnh nội dung đầu vào.
Q: Nên dùng - hay _ làm ký tự phân tách?
A: SEO khuyến nghị dùng - (dấu gạch nối), vì Google xem nó như khoảng trắng; _ (gạch dưới) bị xem là ký tự nối, không tốt cho việc tách từ. Đối với tên tệp, có thể chọn tùy ý.
Q: Slug có giới hạn độ dài không?
A: Về mặt kỹ thuật không có giới hạn, nhưng nên giữ dưới 50 ký tự để dễ hiển thị URL và tối ưu SEO. Slug quá dài có thể bị công cụ tìm kiếm cắt ngắn.
Thực hành tốt nhất
Cách làm được khuyến nghị
- ✓ Giữ ngắn gọn (khuyến nghị < 50 ký tự)
- ✓ Tránh ký tự đặc biệt, chỉ dùng chữ cái/số/ký tự phân tách
- ✓ Chuyển thành chữ thường để tránh vấn đề phân biệt chữ hoa/thường
- ✓ Loại bỏ từ dừng để tăng mật độ ngữ nghĩa
Cách nên tránh
- ✗ Đừng bao gồm thông tin nhạy cảm (như ID, email, mật khẩu)
- ✗ Đừng dùng ký tự đặc biệt (như @#$%^&*)
- ✗ Đừng giữ khoảng trắng hoặc ký tự phân tách liên tiếp
- ✗ Đừng lặp lại cùng một từ
Ghi chú kỹ thuật
Sử dụng NFKD để phân tách + loại bỏ ký tự kết hợp (\p{M}), chuyển Café thành Cafe. Hỗ trợ đa số ký tự hệ Latin.
Dựa trên các từ thông dụng trong tiếng Anh (a/an/the/and/or/of/to/in/on/for/at/by/with), có thể mở rộng tùy chỉnh. Cần xử lý riêng cho từ dừng tiếng Trung.
Cần hỗ trợ ES6+ và biểu thức chính quy Unicode (\p{...}). Các trình duyệt hiện đại (Chrome 64+, Firefox 78+, Safari 11.1+) đều hỗ trợ.
Làm thế nào để tạo Slug bằng ngôn ngữ lập trình?
JavaScript
function slugify(text) {
return text
.toLowerCase()
.normalize("NFKD")
.replace(/[\u0300-\u036f]/g, "")
.replace(/[^\w\s-]/g, "")
.trim()
.replace(/[\s_-]+/g, "-")
.replace(/^-+|-+$/g, "");
}
PHP
function slugify($text) {
$text = mb_strtolower($text);
$text = iconv("UTF-8", "ASCII//TRANSLIT", $text);
$text = preg_replace("/[^\w\s-]/", "", $text);
$text = preg_replace("/[\s_-]+/", "-", $text);
return trim($text, "-");
}
Python
import re
import unicodedata
def slugify(text):
text = text.lower()
text = unicodedata.normalize("NFKD", text)
text = text.encode("ascii", "ignore").decode("ascii")
text = re.sub(r"[^\w\s-]", "", text)
text = re.sub(r"[\s_-]+", "-", text)
return text.strip("-")
Go
import (
"regexp"
"strings"
"golang.org/x/text/unicode/norm"
)
func Slugify(text string) string {
text = strings.ToLower(text)
text = norm.NFKD.String(text)
re := regexp.MustCompile(`[^\w\s-]`)
text = re.ReplaceAllString(text, "")
re = regexp.MustCompile(`[\s_-]+`)
text = re.ReplaceAllString(text, "-")
return strings.Trim(text, "-")
}
Ruby
require "unicode"
def slugify(text)
text = text.downcase
text = Unicode.nfkd(text).gsub(/[^\x00-\x7F]/, "")
text = text.gsub(/[^\w\s-]/, "")
text = text.gsub(/[\s_-]+/, "-")
text.strip.gsub(/^-+|-+$/, "")
end
Java
import java.text.Normalizer;
public static String slugify(String text) {
text = text.toLowerCase();
text = Normalizer.normalize(text, Normalizer.Form.NFKD);
text = text.replaceAll("[^\\w\\s-]", "");
text = text.replaceAll("[\\s_-]+", "-");
return text.replaceAll("^-+|-+$", "");
}