SEO on-page với KDIGI CMS: checklist từng bước
Cập nhật lần cuối:

SEO on-page với KDIGI CMS gồm bốn việc: đặt mẫu tiêu đề/mô tả một lần cho cả site, nhập từ khóa chính và ghi đè khi cần cho từng tài liệu, điền knowledgeGraph để JSON-LD đầy đủ, rồi chạy SEO audit định kỳ. Phần còn lại — breadcrumb, JSON-LD, redirect khi đổi slug — CMS tự làm khi bạn lưu.
Tóm tắt nhanh
- Tiêu đề và mô tả là mẫu (
Sites.seoTitles), ghép lúc render;seo.titletrống là đúng thiết kế.- Mỗi lần lưu
pages,posts,products,landings,taxonomies, CMS dựng một@graphJSON-LD vàoseo.jsonLd.raw.- Ảnh Open Graph đi theo thứ tự: ảnh OG riêng → ảnh đại diện → ảnh mặc định của site.
- Đổi slug tự sinh redirect 301 (kèm cảnh báo chuỗi redirect).
GET /api/seo/auditliệt kê tài liệu thiếu tiêu đề/mô tả, bịnoindexhoặc điểm dưới 50.- AI SEO (DeepSeek) là tùy chọn, bật bằng hai biến môi trường.

1. Đặt mẫu tiêu đề và mô tả cho cả site
Mô hình của KDIGI CMS mượn từ Rank Math: CMS lưu những gì biên tập viên gõ, phần còn lại là mẫu. Mẫu nằm ở Sites.seoTitles (tab Trang & SEO của site), gồm một separator và sáu nhóm: homepage, posts, pages, products, landings, taxonomies, mỗi nhóm có titleTemplate và descriptionTemplate.
Mặc định:
| Nhóm | Mẫu tiêu đề | Mẫu mô tả |
|---|---|---|
homepage |
%sitename% |
%excerpt% |
posts, pages, products, landings |
%title% %sep% %sitename% |
%excerpt% |
taxonomies |
%term% %sep% %sitename% |
%excerpt% |
Biến hỗ trợ: %title%, %sitename%, %sep%, %excerpt%, %category%, %focuskw%, %date%, %modified%, %term%, %currentyear%, %price%… Biến trống hoặc không biết sẽ bị bỏ, dấu phân cách thừa được dọn.
Thứ tự phân giải ở frontend:
title = seo.title || template(titleTemplate) || tiêu đề tài liệu
description = seo.description || template(descriptionTemplate) || excerpt
og:title = seo.openGraph.title || title
Việc nên làm:
- Giữ tiêu đề trong khoảng 40–60 ký tự: với mẫu
%title% | %sitename%, tên site dài sẽ ăn mất ngân sách ký tự — hãy rút gọnknowledgeGraph.namehoặc đổiseparator. - Chỉ ghi đè
seo.titleở những trang quan trọng (trang chủ, trang dịch vụ, bài trụ cột). - Đừng viết script “điền seo.title cho mọi bài”: nó đóng băng giá trị lẽ ra phải đi theo mẫu.
Lưu ý: trường seo.title trống sẽ khiến SEO audit báo missing-title. Hãy đọc là “chưa ghi đè”, không phải “trang không có title”.
2. Từ khóa chính, slug và độ dài
Mỗi tài liệu có seo.focusKeywords; từ khóa đầu tiên quyết định điểm SEO. Bảng chấm điểm trong editor kiểm tra:
| Tiêu chí | Ngưỡng tốt |
|---|---|
| Từ khóa chính trong tiêu đề, mô tả, slug | Có |
| Từ khóa trong 10% đầu nội dung | Có |
| Mật độ từ khóa | 1–1,5% |
| Độ dài tiêu đề / mô tả / URL | ≤ 60 / ≤ 160 / ≤ 75 ký tự |
| Liên kết nội bộ | Ít nhất một liên kết Markdown |
| Độ dài nội dung | Có bậc, hiệu chỉnh theo âm tiết tiếng Việt |
Slug tự sinh từ tiêu đề (bỏ dấu, đ → d, ký tự lạ → -), không dịch theo ngôn ngữ và duy nhất trong từng site. Hãy chốt slug ngắn, có từ khóa, trước khi đăng.
3. Open Graph và Twitter Card
Trường seo.openGraph.* có tiêu đề, mô tả, ảnh, alt. Ảnh được điền lúc đọc qua REST theo thứ tự: seo.openGraph.image → featuredImage của tài liệu → Sites.seoDefaults.ogImage. Giá trị này không ghi ngược vào database nên luôn theo ảnh đại diện hiện tại. twitterMeta.card mặc định là summary_large_image, và useFacebookData mặc định bật để Twitter dùng lại dữ liệu Open Graph.
Thực hành tốt: đặt seoDefaults.ogImage cho mọi site ngay từ đầu để không bài nào chia sẻ ra mạng xã hội mà thiếu ảnh.
4. JSON-LD và dữ liệu có cấu trúc
Hook makeGenerateJsonLdHook chạy sau mỗi lần lưu và ghi seo.jsonLd.raw — một thẻ <script type="application/ld+json"> hoàn chỉnh chứa một @graph. Mọi ký tự < bên trong được escape thành \u003c nên tiêu đề chứa </script> không phá được thẻ.
| Loại tài liệu | Các node chính |
|---|---|
| Bài viết | BlogPosting, Person, WebPage, ImageObject, BreadcrumbList, WebSite, Organization; FAQ lồng trong BlogPosting |
| Trang | WebPage (ContactPage/AboutPage cho slug quen thuộc), FAQPage, BreadcrumbList |
| Sản phẩm / landing | Product + Offer, ItemPage, FAQPage |
| Chuyên mục/thẻ | CollectionPage, BreadcrumbList |
Để node Organization có giá trị, hãy điền ở site: knowledgeGraph (tên, logo, businessType, địa chỉ, giờ mở cửa, telephone được chuẩn hóa E.164) và socialProfiles[] cho sameAs. Frontend chỉ cần chèn nguyên văn:
const jsonLd = post.seo?.jsonLd?.raw // đã gồm cả thẻ <script>
// <div dangerouslySetInnerHTML={{ __html: jsonLd ?? '' }} />
Giá trị này rỗng cho đến khi tài liệu được lưu ít nhất một lần với site hợp lệ. Quy tắc đáng nhớ với sản phẩm: offers chỉ xuất khi prices[0].currentPrice > 0, và aggregateRating chỉ xuất khi đủ điều kiện (số đánh giá ≥ minReviewsForAggregate và có bình luận được duyệt, hoặc bật aggregateRatingOverride). Xem thêm tại tính năng SEO & JSON-LD.
5. Breadcrumb
seo.breadcrumbs tự sinh khi lưu nếu đang trống (không bao giờ ghi đè breadcrumb do biên tập viên nhập hay nhập từ WordPress). Chuỗi gồm: tên site → chuyên mục chính và chuỗi cha → tài liệu hiện tại. Chọn loại taxonomy làm “mắt xích giữa” ở Sites.breadcrumbs (primaryTaxonomyPost, mặc định category). Chỉ bài viết và sản phẩm có mắt xích giữa; trang và landing phẳng. Frontend bỏ qua các mục có isHidden: true.
6. Redirect khi đổi slug
Đổi slug của một tài liệu hiện có khiến autoRedirectOnSlugChange tạo một dòng redirects (301, bật sẵn) từ đường dẫn cũ sang mới, đồng thời đưa một job revalidate cho slug cũ. Quy tắc cần nhớ:
fromphải bắt đầu bằng/,tochỉ nhận đường dẫn nội bộ,fromkhácto.- Chuỗi redirect chỉ bị cảnh báo, không bị chặn: hãy tự giới hạn số bước nhảy ở middleware.
- Script đổi slug ngoài admin phải tự tạo redirect.
curl -s 'https://cms.example.com/api/redirects?where[tenant][equals]=1&where[isEnabled][equals]=true&limit=1000&depth=0'
Khi chuyển từ WordPress, permalink cũ được sinh redirect 301 tự động — xem chuyển từ WordPress.
7. Liên kết nội bộ
Trong editor, gõ @ để chèn liên kết đến bài/trang/sản phẩm/landing cùng site (mặc định chỉ liệt kê nội dung đã live). Panel gợi ý (GET /api/seo/internal-link-suggest) chấm điểm 2 cho mỗi token khớp tiêu đề, 1 cho mỗi token khớp slug, tối đa 10 gợi ý. Mục tiêu thực tế: mỗi bài có ít nhất 3 liên kết nội bộ có ngữ cảnh, và không có trang “mồ côi”. Cách tổ chức nhóm bài ở cấu trúc nội dung.
8. Chạy SEO audit định kỳ
GET /api/seo/audit (cần đăng nhập) quét posts, pages, products, landings của một site (tối đa 200 tài liệu/collection mỗi lần) và trả về danh sách tài liệu yếu, tệ nhất trước, cùng reasons: missing-title, missing-desc, noindex, broken-canonical, low-score:<n>. Kết quả hiện luôn trên widget ở dashboard.

Quy trình gợi ý mỗi tuần:
- Mở dashboard, xem widget SEO audit.
- Với mục
noindexhoặcbroken-canonical: sửa ngay (canonical override phải bắt đầu bằnghttp). - Với
low-score: mở tài liệu, làm xanh checklist, ưu tiên bài đang có traffic. - Với
missing-title/missing-descở trang quan trọng: ghi đè thủ công hoặc dùng AI gợi ý.
9. AI SEO (tùy chọn)
Nút AI trong tab SEO gọi POST /api/seo/ai-generate (đăng nhập, giới hạn mặc định 20 lần/phút/người) để gợi ý tiêu đề, mô tả, FAQ hoặc alt ảnh bằng DeepSeek. Chỉ bật khi đặt DEEPSEEK_API_KEY và DEEPSEEK_MODEL; khóa không rời khỏi server. Coi đầu ra là bản nháp: tiêu đề nhắm 40–65 ký tự, mô tả 100–165 ký tự. Nút “Tạo FAQ” chỉ xem trước, vì FAQ nằm ở collection riêng.
Checklist 12 bước trước khi bấm Đăng
- Chọn từ khóa chính và nhập vào
seo.focusKeywords(từ khóa đầu tiên quyết định điểm). - Đặt từ khóa chính trong tiêu đề, slug và 10% đầu nội dung.
- Kiểm tra tiêu đề ≤ 60 ký tự; để mẫu site lo hoặc ghi đè
seo.titleở trang quan trọng. - Viết mô tả ≤ 160 ký tự, nêu lợi ích cụ thể (hoặc để mẫu
%excerpt%và kiểm tra bản resolve). - Dùng một H1 duy nhất (tiêu đề), các mục con bằng H2/H3 theo thứ tự logic.
- Đặt ảnh đại diện (để OG đúng) và
altmô tả cho mọi ảnh. - Thêm ít nhất 3 liên kết nội bộ có ngữ cảnh bằng bộ chọn
@và ít nhất một nguồn ngoài đáng tin nếu có số liệu. - Kiểm tra
seo.robotskhông dínhnoindexvàcanonicalOverride(nếu dùng) bắt đầu bằnghttp. - Điền FAQ (nếu có) và hiển thị chính nội dung đó ra trang, không chỉ trong JSON-LD.
- Xác nhận
knowledgeGraphvàsocialProfilescủa site đã đầy đủ để graph JSON-LD cóOrganizationvàsameAs. - Đăng, rồi mở URL công khai để kiểm tra title, mô tả, canonical, ảnh OG và JSON-LD trong HTML.
- Một tuần sau: xem widget SEO audit ở dashboard và sửa mọi mục
noindex,broken-canonical,low-score.
Sitemap, robots.txt và thẻ canonical trong HTML do frontend của bạn xuất ra; CMS cung cấp dữ liệu (sitemapPriority, seo.canonicalOverride, seo.robots) để frontend dựng chúng.
Thử toàn bộ quy trình trên bản demo hoặc tự host để làm trên dữ liệu của bạn.
Câu hỏi thường gặp
Vì sao seo.title của bài viết trong API thường để trống?
Điểm SEO trong editor có được lưu vào database không?
Đổi slug bài viết có làm mất thứ hạng không?
JSON-LD của KDIGI CMS có cần plugin hay code thêm không?
Có bắt buộc dùng AI để viết tiêu đề và mô tả không?
Đọc tiếp
SEO và JSON-LD
Trường SEO, mẫu title kiểu RankMath, đồ thị JSON-LD, ảnh OG dự phòng, kiểm tra SEO, gợi ý internal link và AI SEO tùy chọn ngay trong trình soạn thảo.
Nội dung và cấu trúc
Mô hình nội dung gồm trang, bài viết, sản phẩm, landing, taxonomy, tác giả, FAQ, menu dạng cây, redirect, bình luận, đánh giá, phiên bản và thùng rác.
Cấu trúc nội dung và taxonomy: danh mục, thẻ, pillar–cluster
Cách tổ chức loại nội dung, danh mục, thẻ và liên kết pillar–cluster trong KDIGI CMS để tránh nội dung trùng lặp và giúp Google lẫn AI hiểu chủ đề.
Chuyển từ WordPress
Hướng dẫn chuyển WordPress sang KDIGI CMS: bài viết, trang, media, menu, dữ liệu Yoast/RankMath, WooCommerce, redirect 301. Có checklist và giới hạn rõ ràng.