Bạn có bao giờ mua một cuốn sách không có trang mục lục?
Bạn có biết tại sao đa số những bài blog, bài viết rất hay, rất chất lượng trên website, lại có tỷ lệ rời bỏ trang (bounce rate) rất cao không?
Cũng giống như việc bạn không mua một cuốn sách không có trang mục lục, khách truy cập cũng sẽ khó lòng mà đọc hết bài viết của bạn nếu bài viết không có phần mục lục.
Cùng với việc tăng tốc cho website, tạo mục lục cho bài viết là một trong những cách hiệu quả nhất để giảm tỷ lệ rời bỏ trang. Hơn nữa, Google cũng rất ưu ái cho những bài viết nào có phần mục lục.
Nhưng vấn đề là, không phải theme nào trong WordPress cũng được tích hợp sẵn phần mục lục (table of contents).
Để tạo mục lục cho bài viết trong WordPress, cách thông thường là tải và kích hoạt plugin Easy Table of Contents. Nhưng phần table of contents được tạo ra bởi plugin này nhìn rất nhàm chán, nó giống như thế này.

Bạn có muốn thêm một chút gia vị cho phần mục lục để tạo dấu ấn của riêng mình, giống như phần mục lục bên dưới của Bác Sĩ SEO không?
Bài viết này sẽ hướng dẫn bạn tạo mục lục cho bài viết trong trang WordPress không cần plugin theo 2 cách: cách thủ công (cách dễ nhưng cực) và cách tự động (cách khó nhưng khỏe).
Cách 1: Tạo mục lục cho bài viết trong WordPress bằng HTML – Cách thủ công, dễ nhưng cực
Cách đơn giản nhất để tạo phần mục lục cho bài viết trong WordPress là viết HTML và tạo điểm neo HTML cho các tiêu đề phụ trong bài viết và gắn liên kết cho các tiêu đề phụ đó.
Cách này rất đơn giản, nhưng chỉ phù hợp cho trang web không có nhiều bài viết. Nếu trang của bạn có nhiều hơn 30 bài viết, về lâu dài làm theo cách này sẽ cực hơn cách thứ 2.
Sau đây là phần hướng dẫn chi tiết cho cách tạo mục lục trong WordPress bằng HTML.
Đây là đoạn mã HTML cơ bản của phần mục lục, bạn hãy copy paste nó vào từng bài viết trong trang WordPress.
<div class="bss_toc">
<h2>Mục lục</h2>
<ul>
<!-- Số dòng <li><a href="#"></a></li> tương ứng với số lượng tiêu đề phụ trong bài viết -->
<li><a href="#tieu-de-phu-1">Tiêu đề phụ 1</a></li>
<li><a href="#tieu-de-phu-2">Tiêu đề phụ 2</a></li>
<li><a href="#tieu-de-phu-3">Tiêu đề phụ 3</a></li>
<li><a href="#tieu-de-phu-4">Tiêu đề phụ 4</a></li>
</ul>
</div>
Bạn thay thế các dòng a href=”#” và tiêu đề phụ giống với các tiêu đề phụ trong bài viết.
Ví dụ, đây là đoạn mã HTML để tạo phần mục lục cho chính bài viết này.
<div class="bss_toc">
<h2>Mục lục</h2>
<ul>
<!-- Số dòng <li><a href="#"></a></li> tương ứng với số lượng tiêu đề phụ trong bài viết -->
<li><a href="#tao-muc-luc-bang-html">Cách 1: Tạo mục lục cho bài viết trong WordPress bằng HTML - Cách thủ công, dễ nhưng cực</a>
</li>
<li><a href="#tao-muc-luc-bang-php-javascript-css">Cách 2: Tạo mục lục cho bài viết trong WordPress bằng PHP, Javascript và CSS - Cách tự động, khó nhưng khỏe</a>
<ul>
<li><a href="#buoc-1">Bước 1: Tạo file "table-of-contents.js" trong folder js của child theme</a></li>
<li><a href="#buoc-2">Bước 2: Thêm code enqueue script vào file functions.php của child theme</a></li>
<li><a href="#buoc-3">Bước 3: Thêm CSS vào phần Tùy biến >> CSS bổ sung để style phần mục lục</a></li>
<li><a href="#buoc-4">Bước 4: Thêm mã tạo table of contents vào mọi bài viết trong trang WordPress</a></li>
</ul>
</li>
</ul>
</div>
Nếu bạn không biết tạo liên kết mỏ neo HTML cho tiêu đề phụ thì hãy làm theo các bước bên dưới.
Bước 1: Chỉnh sửa bài viết mà bạn muốn thêm mục lục

Bước 2: Click vào một tiêu đề phụ bất kỳ trong bài viết

Bước 3: Chọn tab Nâng cao

Bước 4: Thêm Điểm neo HTML cho tiêu đề phụ
Ví dụ, tiêu đề phụ trên là “Copy paste và chỉnh sửa HTML” thì bạn thêm liên kết cho tiêu đề phụ là copy-paste-va-chinh-sua-html

Bạn tiếp tục lặp lại thứ tự các bước trên cho mọi tiêu đề phụ trong bài viết.
Sau khi thêm liên kết mỏ neo HTML của tiêu đề phụ và tiêu đề phụ vào đoạn mã HTML phía trên, bạn Cập nhật bài viết và xem bài viết ở trong website. Nếu bạn làm chính xác theo những gì đã hướng dẫn thì bạn sẽ thấy phần mục lục đã được tạo cho bài viết, giống như thế này.

Như vậy là bạn đã tạo thành công phần mục lục cho bài viết trong WordPress bằng HTML. Tuy này cách rất dễ thực hiện nhưng nếu trang web của bạn có rất nhiều bài viết hoặc bài viết có quá nhiều tiêu đề phụ thì cách này sẽ rất cực.
Nếu bạn muốn tạo phần table of contents cho mọi bài viết trong WordPress mà không phải mất thời gian thêm code HTML vào từng bài, hãy tiếp tục đọc và làm theo cách bên dưới.
Cách 2: Tạo mục lục cho bài viết trong WordPress bằng PHP, Javascript và CSS – Cách tự động, khó nhưng khỏe
Đây là cách khó hơn để tạo table of contents cho bài viết trong WordPress.
Nhưng đây cũng là cách tự động, bạn chỉ cần làm một lần và không cần phải lo lắng về việc bài viết của mình đã có phần mục lục hay chưa (giống như xài plugin nhưng thay vì xài plugin thì bạn sẽ thêm phần mục lục bằng code để tối ưu tốc độ cho trang WordPress).
Thật ra, tất cả những gì bạn cần làm là copy paste code và biết paste code vào chỗ nào. Sau khi hoàn tất, bạn chỉ cần gõ duy nhất dòng chữ này vào bất kỳ bài viết nào mà bạn muốn tạo mục lục.
[bsstoc]
Và đó là những gì Bác Sĩ SEO sẽ hướng dẫn bạn chi tiết bên dưới.
Bước 1: Tạo file “table-of-contents.js” trong folder js của child theme
Trong folder js của child theme,, bạn tạo một file mới có tên là table-of-contents.js (tạo file mới bằng FTP Client như FileZilla hoặc sử dụng File Manager do dịch vụ hosting của bạn cung cấp, bạn có thể đọc bài viết này của Hostinger để biết cách cài đặt cũng như cấu hình để kết nối FileZilla đến root folder của trang web).

Sau khi tạo file xong, bạn copy những dòng code dưới đây vào trong file table-of-contents.js (dùng text editort như Notepad hoặc Visual Studio Code để thêm code nếu bạn sử dụng FTP Client để kết nối đến root folder của website).
Sau khi thêm xong, bạn nhớ save lại.
jQuery(document).ready(function($){
var $bsstoc = $(".bsstoc");
var $content = $bsstoc.parent();
var stopAt = $bsstoc.data("stopat");
var sub_headers = [];
switch(stopAt){
case "h6":
sub_headers.push("h6");
case "h5":
sub_headers.push("h5");
case "h4":
sub_headers.push("h4");
case "h3":
sub_headers.push("h3");
case "h2":
sub_headers.push("h2");
}
sub_headers = sub_headers.join();
var $heads = $content.find(sub_headers);
if($heads.length === 0){
return;
}
var toc = "";
toc += "<h2>Mục lục</h2><ul>";
$heads.each(function(){
var $this = $(this);
var tag = $this[0].tagName;
var txt = $this.text();
var slug = convertToSlug(txt);
$this.attr("data-linked",slug);
toc += '<li class="bsstoc-level-'+tag+'">';
toc += '<a href="#" data-linkto="'+slug+'">'+txt+"</a></li>";
});
toc += "</ul>";
$bsstoc.append(toc);
$(".bsstoc ul").on("click", "a", function(e){
e.preventDefault();
$([document.documentElement, document.body]).animate({
scrollTop: $content.find('[data-linked="'+$(this)
.attr("data-linkto")+'"]').offset()
.top - parseInt($bsstoc.attr("data-offset"), 10)
}, 2000);
});
function convertToSlug(text){
return text.toString().toLowerCase()
.replace(/\s+/g, "-")
.replace(/[^\w\-àáãạảăắằẳẵặâấầẩẫậèéẹẻẽêềếểễệđìíĩỉịòóõọỏôốồổỗộơớờởỡợùúũụủưứừửữựỳỵỷỹýÀÁÃẠẢĂẮẰẲẴẶÂẤẦẨẪẬÈÉẸẺẼÊỀẾỂỄỆĐÌÍĨỈỊÒÓÕỌỎÔỐỒỔỖỘƠỚỜỞỠỢÙÚŨỤỦƯỨỪỬỮỰỲỴỶỸÝ]+/g, "")
.replace(/\-\-+/g, "-")
.replace(/^\d+/, "")
.replace(/^-+/, "")
.replace(/-+$/, "")
.replace(/à|á|ạ|ả|ã|â|ầ|ấ|ậ|ẩ|ẫ|ă|ằ|ắ|ặ|ẳ|ẵ/g, "a")
.replace(/è|é|ẹ|ẻ|ẽ|ê|ề|ế|ệ|ể|ễ/g, "e")
.replace(/ì|í|ị|ỉ|ĩ/g, "i")
.replace(/ò|ó|ọ|ỏ|õ|ô|ồ|ố|ộ|ổ|ỗ|ơ|ờ|ớ|ợ|ở|ỡ/g, "o")
.replace(/ù|ú|ụ|ủ|ũ|ư|ừ|ứ|ự|ử|ữ/g, "u")
.replace(/ỳ|ý|ỵ|ỷ|ỹ/g, "y")
.replace(/đ/g, "d")
.replace(/\u0300|\u0301|\u0303|\u0309|\u0323/g, "")
.replace(/\u02C6|\u0306|\u031B/g, "");
}
});

Như vậy là bạn đã tạo xong file javascript table-of-contents.js. Đây có thể nói là file quan trọng nhất của cả quá trình tạo mục lục tự động cho WordPress, bạn nhớ copy chính xác và không chỉnh sửa gì thêm.
Bước 2: Thêm code vào file functions.php của child theme
Bạn copy đoạn code sau vào file functions.php và save lại.
/* Add shortcode code for table of contents */
function bss_bsstoc($atts) {
if (empty($atts)) {
$atts = array();
}
if (empty($atts['stopat'])) {
$atts['stopat'] = 'h4';
}
if (empty($atts['offset'])) {
$atts['offset'] = '20';
}
return '<div class="bsstoc" data-stopat="'.$atts['stopat'].'" data-offset="'.$atts['offset'].'"></div>';
}
add_shortcode('bsstoc', 'bss_bsstoc');
/* Enqueue custom scripts */
function bss_custom_scripts() {
wp_enqueue_script('table-of-contents-script', get_stylesheet_directory_uri().'/js/table-of-contents.js', array('jquery'), false, true);
}
add_action('wp_enqueue_scripts', 'bss_custom_scripts');
Lưu ý
Nếu bạn có thêm nhiều script khác như script thêm tính năng của nút trở về đầu trang mà Bác Sĩ SEO đã hướng dẫn trong bài viết này thì bạn chỉ cần copy dòng wp_enqueue_script và paste vào dòng bên dưới của dòng wp_enqueue_script phía trên là được, giống như thế này.
/* Enqueue custom scripts */
function bss_custom_scripts() {
/* Đây là code gọi javascript của nút back to top */
wp_enqueue_script('back-to-top-script', get_stylesheet_directory_uri().'/js/back-to-top.js', array('jquery'), false, true);
/* Đây là code gọi javascript của nút back to top */
/* Đây là code gọi javascript của table of contents */
wp_enqueue_script('table-of-contents-script', get_stylesheet_directory_uri().'/js/table-of-contents.js', array('jquery'), false, true);
/* Đây là code gọi javascript của table of contents */
}
add_action('wp_enqueue_scripts', 'bss_custom_scripts');

Như vậy là bạn đã xong phần thêm code PHP. Tiếp theo ở bước 3, bạn sẽ trang trí cho phần mục lục của bài viết bằng CSS.
Bước 3: Thêm CSS vào phần Tùy biến >> CSS bổ sung để style phần mục lục
Bạn copy paste và save lại đoạn mã CSS dưới đây vào phần Tùy biến >> CSS bổ sung để style table of contents.
/* Table of contents */
.bsstoc ul{
margin-left: 45px;
padding-left: 0;
border-left: 1px solid #c4cbdb;
}
.bsstoc li {
padding-left: 20px;
list-style: none;
margin-bottom: 0px;
}
.bsstoc .bsstoc-level-H3{
padding-left: 40px;
}
.bsstoc .bsstoc-level-H4{
padding-left: 60px;
}
.bsstoc .bsstoc-level-H2:before{
content: "";
display: block;
height: 0;
width: 8px;
border-bottom: 1px dashed #c4cbdb;
transform: translateX(-15px) translateY(19px);
}
.bsstoc .bsstoc-level-H3:before{
content: "";
display: block;
height: 0;
width: 30px;
border-bottom: 1px dashed #c4cbdb;
transform: translateX(-35px) translateY(19px);
}
.bsstoc .bsstoc-level-H4:before{
content: "";
display: block;
height: 0;
width: 50px;
border-bottom: 1px dashed #c4cbdb;
transform: translateX(-55px) translateY(19px);
}
@media screen and (max-width: 768px) {
/* Table of contents */
.bsstoc ul{
margin-left: 0;
}
.bsstoc .bsstoc-level-H2:before,
.bsstoc .bsstoc-level-H3:before,
.bsstoc .bsstoc-level-H4:before{
margin-top: -3px;
position: absolute;
}
}
Sau khi thêm và save lại đoạn mã CSS trên, bạn đã tạo mục lục tự động cho mọi bài viết trong WordPress thành công.
Bước 4: Thêm shortcode table of contents vào mọi bài viết trong WordPress
Tất cả những gì bạn cần làm bây giờ là gõ shortcode bên dưới vào bất cứ bài viết nào mà bạn muốn tạo mục lục (thay vì chỉnh sửa chi li như cách tạo mục lục bằng HTML ở phía trên).
Và cái hay của cách này là bạn có thể thêm phần mục lục bằng shortcode vào bất cứ chỗ nào trong bài viết mà bạn muốn, không phải cố định mục lục ở phần đầu bài viết như các plugin table of contents hay làm.
[bsstoc]

Khi thêm xong, bạn vào xem bài viết trên website, bạn sẽ thấy phần mục lục đã được tạo hoàn toàn tự động cho bài viết đó (giống như phần mục lục của các bài viết trong website bacsiseo.com).
Bạn có thể click toàn bộ liên kết tiêu đề phụ trong phần mục lục để đi đến phần nội dung của tiêu đề phụ đó, vô cùng tiện lợi phải không nào?