2026-03-207 phút đọcVI
Debugging SEO Issues — Lighthouse, GSC & DevTools
Mở đầu
Anh đã biết cách khai báo metadata, Open Graph, sitemap. Nhưng khai báo đúng trong code không đảm bảo kết quả đúng trên production. Title có thể bị Google rewrite, canonical URL có thể conflict, OG image có thể 404. Debugging SEO là kỹ năng tìm và fix những lỗi này.
Trong bối cảnh leduykhuong.com — static export deploy trên Cloudflare Pages — debugging có thêm một layer: anh không có server logs. Mọi thứ phải verify từ HTML output hoặc external tools.
Mục tiêu: Thành thạo 3 công cụ debug SEO chính: Lighthouse (audit tự động), Google Search Console (dữ liệu thực từ Google), và Chrome DevTools (inspect trực tiếp).
Lighthouse SEO Audit
Lighthouse là tool audit tích hợp trong Chrome DevTools. SEO audit kiểm tra ~15 tiêu chí:
Cách chạy
- Mở Chrome → Navigate tới page cần kiểm tra
- F12 (DevTools) → Tab "Lighthouse"
- Chọn "SEO" category → "Analyze page load"
- Đọc report — mỗi tiêu chí Pass/Fail + explanation
Các tiêu chí quan trọng
| Tiêu chí | Kiểm tra gì | Lỗi phổ biến |
|---|---|---|
Document has a <title> | Trang có title tag | Title rỗng hoặc thiếu |
| Document has a meta description | Có meta description | Description thiếu hoặc quá dài |
| Page has successful HTTP status | Status 200 | 404, redirect loops |
| Links have descriptive text | Anchor text có ý nghĩa | "Click here", "Read more" |
| Document uses legible font sizes | Font ≥ 12px trên mobile | Font nhỏ trên mobile viewport |
| Tap targets are sized appropriately | Touch targets ≥ 48×48px | Buttons quá nhỏ trên mobile |
| Page isn't blocked from indexing | Không có noindex | robots meta hoặc robots.txt block |
Image elements have alt attributes | Ảnh có alt text | Ảnh trang trí thiếu alt |
Document has valid hreflang | hreflang tags hợp lệ | Sai format locale, thiếu x-default |
| Document has valid canonical | Canonical URL accessible | 404, redirect, hoặc self-referencing sai |
Chạy từ CLI (headless)
# Install Lighthouse CLI
npm install -g lighthouse
# Audit một URL
lighthouse https://leduykhuong.com/vi/blog/learning-in-public \
--only-categories=seo \
--output=json \
--output-path=./seo-report.json
# Hoặc audit HTML file local (sau build)
npx serve out -p 3001
lighthouse http://localhost:3001/vi/blog/learning-in-public \
--only-categories=seo --output=htmlLưu ý: Lighthouse audit local HTML khác production vì thiếu HTTPS, headers, và CDN behavior. Nhưng metadata checks (title, description, canonical) hoạt động bình thường.
Google Search Console (GSC) — Dữ liệu thực
Lighthouse là audit lý thuyết. GSC cho thấy Google thực sự thấy gì khi crawl site anh.
Coverage Report — Trang nào được index?
GSC → "Pages" (hoặc "Coverage" ở phiên bản cũ):
| Status | Ý nghĩa | Action |
|---|---|---|
| Valid (indexed) | Google đã index | Tốt — không cần làm gì |
| Valid with warnings | Index nhưng có issues | Xem chi tiết, fix nếu cần |
| Excluded | Google biết nhưng KHÔNG index | Kiểm tra lý do |
| Error | Google không crawl được | Fix ngay |
Excluded reasons phổ biến:
- "Crawled - currently not indexed" — Google crawl rồi nhưng cho rằng content không đủ giá trị. Cải thiện content hoặc tăng backlinks.
- "Duplicate without user-selected canonical" — Google tìm thấy 2+ URLs cùng content và tự chọn canonical. Check
alternates.canonicaltrong metadata. - "Excluded by robots.txt" — robots.txt chặn URL này. Kiểm tra
disallowrules. - "Alternate page with proper canonical tag" — Trang multilingual alternate, canonical trỏ đúng sang phiên bản chính. Đây là behavior mong muốn.
Performance Report — Từ khóa nào mang traffic?
GSC → "Performance":
- Queries — Từ khóa nào người dùng search để tìm thấy site
- Impressions — Bao nhiêu lần site xuất hiện trên kết quả tìm kiếm
- Clicks — Bao nhiêu lần người dùng click vào
- CTR — Click-through rate (clicks / impressions)
- Position — Vị trí trung bình trên kết quả tìm kiếm
Actionable insight: Nếu một query có nhiều impressions nhưng CTR thấp → title và description không hấp dẫn đủ → cải thiện seoTitle và seoDescription trong MDX frontmatter.
URL Inspection — Debug từng trang
GSC → nhập URL vào thanh Inspection:
- "URL is on Google" — Đã index ✅
- "Crawled - not indexed" — Google từ chối index ❌
- "Request Indexing" — Yêu cầu Google re-crawl (chỉ dùng sau khi fix issues)
- "View crawled page" — Xem HTML mà Google thực sự nhận được (quan trọng cho debugging)
Use case thực tế: Sau khi fix metadata cho một blog post, dùng "Request Indexing" để Google fetch phiên bản mới. Thường mất 1-3 ngày để reflect.
Chrome DevTools — Inspect trực tiếp
Elements tab — Xem rendered <head>
F12 → Elements → tìm <head>:
▼ <head>
<title>Learning in Public | Le Duy Khuong</title>
<meta name="description" content="Tại sao viết..." />
<meta property="og:title" content="Learning in Public | Le Duy Khuong" />
<meta property="og:image" content="https://leduykhuong.com/og-default.png" />
<meta name="twitter:card" content="summary_large_image" />
<link rel="canonical" href="https://leduykhuong.com/vi/blog/learning-in-public" />
<!-- ...more meta tags... -->
</head>
Kiểm tra:
- Title format đúng template
%s | Le Duy Khuong? - Description không quá 155 ký tự?
- OG image URL absolute (bắt đầu
https://)? - Canonical URL đúng?
- hreflang tags đủ (vi, en, x-default)?
Network tab — Verify image loads
- F12 → Network → filter "Img"
- Tìm OG image URL
- Check: Status 200? Content-Type đúng (image/png, image/webp)?
- Nếu 404 → image path sai hoặc file chưa được deploy
Console — Structured Data errors
Google's Rich Results Test report cũng xuất hiện trong console:
# Hoặc dùng grep trên build output
grep -n 'application/ld+json' out/vi/blog/learning-in-public.htmlLỗi SEO phổ biến và cách fix
1. Title bị Google rewrite
Triệu chứng: GSC hiển thị title khác với <title> tag anh khai báo.
Nguyên nhân: Google tự rewrite title nếu thấy title quá dài (>60 ký tự), không phản ánh nội dung, hoặc trùng với title page khác.
Fix: Giữ title dưới 60 ký tự, phản ánh đúng nội dung page. Dùng seoTitle trong MDX frontmatter nếu cần title khác title.
2. Canonical URL conflict
Triệu chứng: GSC báo "Duplicate without user-selected canonical."
Nguyên nhân trên leduykhuong.com: /vi/blog/slug và /en/blog/slug cùng nội dung nhưng canonical không rõ ràng.
Fix: Đảm bảo alternates.canonical khác nhau cho mỗi locale version. Code hiện tại đã xử lý:
alternates: {
canonical: `${BASE_URL}/${locale}/blog/${slug}`, // locale-specific
languages: {
vi: `${BASE_URL}/vi/blog/${slug}`,
en: `${BASE_URL}/en/blog/${slug}`,
"x-default": `${BASE_URL}/vi/blog/${slug}`,
},
},3. OG image 404
Triệu chứng: Social preview không có ảnh.
Debug:
# Check image file exists in build output
ls -la out/og-default.png
# Check URL trong meta tag
grep 'og:image' out/vi/blog/learning-in-public.html
# Verify URL accessible
curl -I https://leduykhuong.com/og-default.pngFix thường gặp: Image ở thư mục public/ nhưng path trong code thiếu / prefix, hoặc image chưa được commit.
4. Mobile usability issues
Triệu chứng: Lighthouse báo font size hoặc tap targets quá nhỏ.
Fix: Đảm bảo viewport meta tag tồn tại (Next.js tự thêm), font-size ≥ 16px cho body text, buttons ≥ 48×48px.
Workflow Debug SEO cho leduykhuong.com
Quy trình kiểm tra SEO sau mỗi deployment:
1. Build locally: npm run build
└── Check build output: grep '<title>' out/vi/blog/*.html | head
2. Lighthouse audit (local):
└── npx serve out -p 3001
└── Lighthouse → SEO category
3. Deploy to Cloudflare Pages
4. Social debuggers:
└── Facebook Debugger → Scrape Again
└── LinkedIn Post Inspector
5. GSC (sau 1-3 ngày):
└── URL Inspection → check indexing
└── Coverage → check excluded pages
Thực hành
Bài tập 1: Chạy Lighthouse SEO audit
cd ACE-component/ACE-leduykhuong-site && npm run build
npx serve out -p 3001
# Mở Chrome → http://localhost:3001/vi/blog/learning-in-public
# F12 → Lighthouse → SEO → AnalyzeCâu hỏi: Score bao nhiêu? Tiêu chí nào fail (nếu có)?
Bài tập 2: Inspect <head> tags
Mở DevTools → Elements → <head>:
- Đếm số lượng
<meta property="og:*">tags - Tìm
<link rel="canonical">— URL có đúng không? - Tìm
<link rel="alternate" hreflang="*">— có đủ vi, en, x-default?
Bài tập 3: Grep build output
# All meta tags cho 1 blog post
grep -E '<meta|<title>|<link rel' out/vi/blog/learning-in-public.html | head -20
# So sánh 2 locale versions
diff <(grep '<title>' out/vi/blog/learning-in-public.html) \
<(grep '<title>' out/en/blog/learning-in-public.html)Tóm tắt
- Lighthouse — Audit tự động 15 tiêu chí SEO, chạy từ DevTools hoặc CLI
- Google Search Console — Dữ liệu thực: pages indexed, queries, clicks, crawl errors
- Chrome DevTools — Inspect
<head>trực tiếp, verify image loads, check structured data - Title rewrite — Google có thể thay đổi title; giữ ≤60 ký tự và phản ánh đúng nội dung
- Canonical conflict — Multilingual sites cần canonical per-locale + hreflang tags
- OG image 404 — Luôn dùng absolute URL, verify file tồn tại sau deploy
Bài tiếp theo
Kết thúc series Next.js Metadata. Series tiếp theo: JSON-LD & Structured Data — Bài 5 sẽ giới thiệu Schema.org vocabulary, cách JSON-LD hoạt động, và tại sao structured data giúp Google hiểu content tốt hơn.