SEO Troubleshooting
Diagnostic trees for common SEO problems. Start from the symptom, follow the tree to the fix.
"Page Not Indexed by Google"
Page not appearing in Google?
├─ Is the page in your sitemap?
│ └─ No → Add it to sitemap.ts, resubmit in GSC
├─ Does robots.txt block it?
│ └─ Check /robots.txt — is the path in Disallow?
├─ Does the page have noindex?
│ └─ Check metadata: robots.index should be true (or absent)
├─ Is there a canonical pointing elsewhere?
│ └─ Check alternates.canonical — must point to self
├─ Is the staging env blocking crawlers?
│ └─ Check robots.ts — VERCEL_ENV or NODE_ENV check
├─ Is the page behind JavaScript only?
│ └─ Use Server Components — content must be in initial HTML
├─ Is the page returning non-200 status?
│ └─ Google excludes non-200 pages from rendering queue (Dec 2025)
├─ Is the page new?
│ └─ Wait 2-4 weeks. Use GSC URL Inspection to request indexing
└─ Is the page thin or duplicate?
└─ Add unique, valuable content. Check for duplicate URLs
Quick fix: In Google Search Console → URL Inspection → paste the URL → "Request Indexing". This does not guarantee indexing but puts the URL in the crawl queue.
"No Rich Snippets / Rich Results"
Structured data not showing rich results?
├─ Is the JSON-LD valid?
│ └─ Test at https://search.google.com/test/rich-results
│ ├─ Errors found → Fix the JSON-LD (missing fields, wrong types)
│ └─ Valid but "not eligible" → Schema type restrictions apply
├─ Is the schema type still supported?
│ ├─ FAQPage → Restricted to gov/health sites since 2023
│ ├─ HowTo → Desktop removed in 2023, mobile/voice only
│ └─ Other types → Check Google's supported types list
├─ Does the schema match page content?
│ └─ Google verifies schema against visible content — mismatches are penalized
├─ Is the site new or low-authority?
│ └─ Rich results require page authority. New sites may wait 1-3 months
├─ Is there competing structured data?
│ └─ Don't use two identical @types on the same page
└─ Has it been enough time?
└─ Rich results take 2-4 weeks to appear after successful crawl
Common fix: Most rich result failures come from missing required fields. Run the Rich Results Test and fix every error and warning.
"Low PageSpeed / Lighthouse Score"
PageSpeed Insights score < 90?
├─ LCP > 2.5s?
│ ├─ Is the LCP element an image?
│ │ ├─ Missing priority prop → Add priority to hero/banner Image
│ │ ├─ Missing sizes prop → Add responsive sizes attribute
│ │ └─ Image too large → Use AVIF/WebP, configure formats in next.config
│ ├─ Is the LCP element text?
│ │ ├─ Font blocking render → Use next/font with display: swap
│ │ └─ Server response slow → Check API/database latency, use ISR
│ └─ Server-side rendering delay?
│ └─ Use Suspense with streaming, add loading.tsx skeletons
├─ INP > 200ms? (or high TBT in lab)
│ ├─ Long JavaScript tasks?
│ │ ├─ Heavy components → Use dynamic() imports with ssr: false
│ │ ├─ Large event handlers → Use startTransition, useDeferredValue
│ │ └─ Third-party scripts → Defer with next/script strategy="lazyOnload"
│ ├─ Large DOM?
│ │ └─ Target < 1500 nodes. Use virtual scrolling for long lists
│ └─ Large bundle?
│ └─ Run NEXT_BUNDLE_ANALYZE=true next build. Remove unused deps
├─ CLS > 0.1?
│ ├─ Images without dimensions → Add width/height to all Image components
│ ├─ Font flash (FOUT) → Use next/font (self-hosted, no FOUT)
│ ├─ Dynamic content injection → Reserve space with min-height or Suspense
│ └─ Ads or embeds loading late → Set explicit dimensions, use placeholder
└─ General slow?
├─ Not using ISR → Add revalidate to static pages
├─ No CDN → Deploy to Vercel or edge-enabled host
└─ Too many third-party scripts → Audit and remove unused scripts
"Duplicate Content"
Google reporting duplicate content?
├─ Same content, different URLs?
│ ├─ www vs non-www → 301 redirect to one version
│ ├─ HTTP vs HTTPS → 301 redirect HTTP → HTTPS
│ ├─ Trailing slash inconsistency → Set trailingSlash in next.config.ts
│ └─ Query parameters → Canonical to base URL (without params)
├─ Same content across pages?
│ ├─ Category/tag pages with overlap → Canonical to primary page
│ ├─ Pagination → Canonical to page 1 (or self-referencing)
│ └─ Translated content without hreflang → Add hreflang alternates
├─ Syndicated or republished content?
│ └─ Add canonical pointing to the original source
└─ Near-duplicate pages?
└─ Consolidate thin pages or add unique content to each
"OG Image Not Showing on Social Media"
Social media preview missing image?
├─ Is the image URL absolute?
│ └─ Must be full URL (https://...), not relative (/og.png)
│ Fix: Set metadataBase in root layout
├─ Is the image accessible?
│ └─ Try opening the URL directly in a browser
│ ├─ 404 → Image path is wrong or file missing
│ ├─ 403 → Server blocking social media crawlers
│ └─ Loads fine → Continue debugging
├─ Is the image the right size?
│ └─ Minimum 600x315, recommended 1200x630
├─ Is there a cache issue?
│ ├─ Facebook → Use Sharing Debugger to clear cache
│ ├─ Twitter/X → Use Card Validator to refresh
│ ├─ LinkedIn → Use Post Inspector to recrawl
│ └─ Slack → Append ?v=2 to URL to bust cache
├─ Is the og:image tag in the HTML?
│ └─ View page source, search for og:image
│ ├─ Missing → Check metadata export has openGraph.images
│ └─ Present but wrong URL → Check metadataBase configuration
└─ Using opengraph-image.tsx?
└─ Test by visiting /opengraph-image directly in browser
└─ Error → Check ImageResponse code for bugs
"Google Search Console Errors"
"Crawled - currently not indexed"
Google found the page but chose not to index it. Common reasons:
- Content is thin or duplicates another page
- Page has low quality signals
- Site has too many low-quality pages diluting crawl budget
Fix: Improve content quality, add unique value, ensure page has inbound internal links.
"Discovered - currently not indexed"
Google knows the URL exists but hasn't crawled it yet. This is normal for new pages.
Fix: Wait. Ensure the page is in the sitemap. Use URL Inspection to request crawling.
"Excluded by noindex tag"
Page has robots: { index: false } in metadata. If intentional, ignore. If not, remove the noindex.
"Page with redirect"
Page returns a 301/302 redirect. Google follows the redirect and indexes the destination instead.
Fix: If the redirect is correct, no action needed. If not, fix the redirect in next.config.ts.
"Server error (5xx)"
Page returned a 500 error when Googlebot crawled it.
Fix: Check server logs, fix the error. Common causes: missing env vars in production, database timeouts, unhandled exceptions in Server Components.
"Blocked by robots.txt"
The URL is disallowed in robots.txt.
Fix: Review robots.ts rules. Remove the page from Disallow if it should be indexed.
Diagnostic Tools
| Tool | URL | Use For |
|---|---|---|
| Google Search Console | search.google.com/search-console | Index status, crawl errors, performance |
| Google Rich Results Test | search.google.com/test/rich-results | Structured data validation |
| PageSpeed Insights | pagespeed.web.dev | Core Web Vitals, performance |
| Facebook Sharing Debugger | developers.facebook.com/tools/debug/ | OG tag preview |
| Twitter Card Validator | cards-dev.twitter.com/validator | Twitter Card preview |
| Schema.org Validator | validator.schema.org | JSON-LD syntax validation |
| Lighthouse (DevTools) | Chrome DevTools → Lighthouse tab | Full audit |