Tại sao Pagination (Phân trang) trên WordPress Custom Post Type hay bị lỗi 404? (Và cách xử lý triệt để)

Có rất ít điều gây ức chế hơn một lỗi cứ “tự sửa xong rồi lại hỏng” ngay khi bạn vừa rời mắt. Tuần trước, các chuyên gia về web tại Code Tốt vừa xử lý một ca điển hình của WordPress: Lỗi 404 khi phân trang trên Custom Post Type (CPT).

Kịch bản rất quen thuộc: Bạn vào Settings > Permalinks, nhấn “Save Changes”, và mọi thứ hoạt động hoàn hảo. Nhưng chỉ vài tiếng sau? Trang 2 (/page/2/) lại lăn đùng ra báo lỗi 404.

Sau nhiều năm xây dựng các hệ thống WordPress phức tạp, tôi hiểu rằng khi việc “lưu lại permalinks” chỉ là liều thuốc tạm thời, thì căn bệnh thực sự thường nằm ở Xung đột bộ quy tắc đường dẫn (Rewrite Rule Corruption). Nếu bạn đang gặp tình trạng này, bạn không hề nhìn nhầm đâu—chỉ là WordPress đang bị “mất bản đồ” thôi.

Dưới đây là những gì tôi đã rút ra từ kinh nghiệm thực chiến và cách để bạn xử lý nó vĩnh viễn.

Nguyên nhân: Tại sao lỗi lại quay trở lại?

Nguyên nhân phổ biến nhất là do bộ quy tắc đường dẫn bị ghi đè. WordPress lưu trữ một “bản đồ” cấu trúc URL trong database. Khi một plugin cập nhật, một bài viết mới được lưu, hoặc một hàm (hook) nào đó được kích hoạt sai cách, bản đồ này sẽ bị xáo trộn. Nếu cấu hình CPT của bạn không chuẩn, WordPress sẽ “quên” mất đường dẫn đến các trang phụ.

3 Bước để xử lý dứt điểm

1. Tránh xung đột Slug (Đường dẫn tĩnh)

WordPress sẽ rất bối rối nếu một Trang (Page) và một Custom Post Type dùng chung một slug.

  • Lỗi thường gặp: Bạn có một trang tên là projects và một CPT cũng được đăng ký với slug là projects.
  • Giải pháp: Hãy đảm bảo slug của CPT archive là duy nhất. Nếu bắt buộc phải giống nhau, bạn cần thiết lập 'has_archive' => true và đảm bảo các quy tắc rewrite được phân tách rõ ràng.

2. Lỗi lệch chỉ số posts_per_page

Đây là “sát thủ thầm lặng” gây ra lỗi 404. Nếu cài đặt chung của WordPress (Settings > Reading) để hiển thị 10 bài viết, nhưng trong code template của bạn lại gọi ra 5 bài viết, phép toán sẽ bị sai.

  • Logic: Khi bạn truy cập /page/2/, WordPress sẽ kiểm tra cài đặt hệ thống. Nếu bạn chỉ có tổng cộng 8 bài viết, WordPress nghĩ rằng trang 2 không tồn tại (vì $8 < 10$) và trả về lỗi 404 ngay lập tức, trước cả khi code của bạn kịp thực thi.
  • Giải pháp: Sử dụng hook pre_get_posts trong file functions.php để báo cho WordPress biết chính xác số lượng bài viết cần lấy trước khi trang được tải.

3. Ngừng việc Flush Rules tự động

Tôi đã thấy nhiều lập trình viên đặt hàm flush_rewrite_rules(); trực tiếp vào hook init. Đừng bao giờ làm thế.

  • Hậu quả: Nó ép WordPress phải xây dựng lại toàn bộ bản đồ URL sau mỗi lượt tải trang. Điều này gây tốn tài nguyên và tạo ra độ trễ, đôi khi khiến quy tắc chưa kịp ghi xong đã có yêu cầu truy cập, dẫn đến lỗi 404 ngẫu nhiên.

Giải pháp bằng Code

Tôi khuyên bạn nên thêm đoạn code này vào file functions.php. Nó sẽ đồng bộ hóa “phép toán” của lõi WordPress với yêu cầu hiển thị thực tế của bạn:

PHP

function fix_my_cpt_pagination( $query ) {
    // Chỉ tác động vào query chính ở ngoài front-end và cho đúng CPT của bạn
    if ( !is_admin() && $query->is_main_query() && is_post_type_archive('your_cpt_slug') ) {
        $query->set( 'posts_per_page', 10 ); // Con số này phải khớp với thiết kế của bạn
    }
}
add_action( 'pre_get_posts', 'fix_my_cpt_pagination' );

Danh sách kiểm tra (Checklist)

  • [ ] Slug duy nhất: Slug của CPT có khác với tiêu đề các Page khác không?
  • [ ] Đồng bộ Query: Chỉ số posts_per_page trong code có khớp với cài đặt Reading không?
  • [ ] Loại bỏ Auto-Flush: Bạn đã xóa hàm flush_rewrite_rules khỏi các vị trí không cần thiết chưa?
  • [ ] Lưu lại lần cuối: Vào phần Permalinks và nhấn “Save Changes” một lần cuối cùng.

Lời khuyên từ chuyên gia: Nếu bạn dùng các plugin SEO, hãy kiểm tra tính năng “Strip Category Base” hoặc “Clean Permalinks”. Đôi khi các tính năng này dọn dẹp URL quá mức và xóa luôn cả các quy tắc phân trang trong database của bạn.

Đánh giá post

Bài viết liên quan