Technical SEO Audit Checklist
A structured technical SEO audit checklist covering crawlability, canonicals, performance, structured data, security, and more — with direct links to every check.
A complete technical SEO audit covers 9 layers: crawlability, canonicalization, on-page signals, structured data, performance, JavaScript rendering, media, internationalization, and security. Miss any one and your rankings reflect the gap. This checklist maps 89 specific failure modes to the signals Google and other engines use to evaluate your site.
1. Crawlability & Indexing
Googlebot must reach your pages, parse them, and decide they are worth indexing. Failures here are silent — you may rank nowhere without a single visible error.
- Robots.txt exists and is valid. A missing file (robots.txt_missing) causes undefined crawler behavior. A broad
Disallow(robots.blocked) kills entire sections. Blocking CSS and JS (robots.blocks_css_js) prevents rendering. - Pages are reachable. Fetch errors (fetch.error), incomplete fetches (fetch.incomplete), access blocks (crawlability.access_blocked), and rate limiting (crawlability.rate_limited) stop crawlers before they see content.
- HTTP status codes are correct. 4xx responses (status.4xx) waste crawl budget. 5xx errors (status.5xx) signal unreliability. Any unexpected non-200 (status.non_200) needs review.
- Indexability signals are intentional.
noindex(index.noindex) ornoindex, nofollow(index.noindex_nofollow) drop pages from the index. A straynofollow(index.nofollow) on canonical pages kills PageRank flow. - Sitemaps are valid. A non-200 sitemap (sitemap.not_200) is ignored. Non-indexable URLs in sitemaps (sitemap.non_indexable) contradict your directives. Indexable pages absent from sitemaps (sitemap.orphan_not_listed) are crawled less often.
See also: Crawl Budget Guide | Robots.txt Guide
2. Duplicates & Canonicals
Duplicate content fragments authority across URLs. The canonical tag is the primary mechanism to consolidate it — when it's wrong, consolidation fails.
- Every indexable page has a self-referencing canonical. Missing canonicals (canonical.missing) leave the choice to Google. Relative values (canonical.relative) resolve differently across proxies and CDNs.
- Canonical targets are reachable and indexable. A canonical to a redirect (canonical.to_redirect) or to a noindexed URL (canonical.to_noindex) breaks consolidation. A malformed target (canonical.bad_target) or unintentional non-self canonical (canonical.non_self) loses equity to the wrong URL.
- Protocol, host, and trailing-slash variants are resolved. HTTP/HTTPS duplicates (duplicate.protocol_host) and trailing-slash variants (duplicate.trailing_slash) need a canonical or 301 to a single preferred form.
- Redirect chains are collapsed. A single redirect (redirect.single) is fine; chains (redirect.chain) dilute PageRank.
- Content, titles, and descriptions are unique. Duplicate content (duplicate.content), titles (duplicate.title), meta descriptions (duplicate.meta_desc), and near-duplicates (duplicate.near) signal canonicalization failures.
See also: Canonical Tags Guide
3. On-Page & Content
Title elements, headings, and body content are the primary on-page ranking signals. Missing or malformed tags cause immediate ranking loss.
- Title tags are present, unique, and sized correctly. Missing titles (title.missing) let Google generate its own. Too long (title.too_long) gets truncated; too short (title.too_short) wastes the most weighted tag. A title identical to the H1 (title.same_as_h1) misses variant queries.
- H1s are present and singular. Missing H1 (h1.missing) removes a relevance signal; multiple H1s (h1.multiple) create topic ambiguity.
- Meta descriptions are written and sized correctly. Missing descriptions (meta_desc.missing) let Google pull arbitrary body text. Too long (meta_desc.too_long) or too short (meta_desc.too_short) descriptions underperform. Descriptions identical to the title (content.title_meta_same) indicate template failures.
- Content meets minimum quality thresholds. Thin content (content.thin) triggers quality demotions. Low text-to-HTML ratio (content.low_ratio) buries content in markup. Placeholder text in production (content.lorem_ipsum) is a deployment error. Unedited AI phrases (ai.leftover_llm_phrase) harm perceived quality.
- Internal links are functional and well-distributed. Broken internal links (links.broken_internal) waste crawl budget. Broken external links (links.broken_external) signal neglect. Orphan pages (links.orphan) receive no equity. Links targeting redirects (links.redirect_target) dilute PageRank. Links to noindexed pages (links.to_noindex) leak equity with no return. Deep click depth (links.click_depth) reduces crawl frequency. Missing anchor text (links.no_anchor_text) and internal nofollows (links.nofollow_internal) are common templating errors.
- Legacy and low-value meta tags are absent. The
keywordsmeta tag (meta.keywords_present) is ignored by Google and signals outdated practice. Meta refresh redirects (meta.refresh_redirect) should be replaced with server-side 301s.
See also: Internal Linking SEO | Soft 404s Explained
4. Structured Data
Structured data is not a ranking factor directly, but it gates eligibility for rich results — and rich results improve click-through rates measurably.
- Pages have relevant Schema.org markup. Pages with no schema (schema.none) miss rich result eligibility. Missing breadcrumb markup (schema.breadcrumb_missing) removes sitelink breadcrumbs from SERPs.
- Markup is valid. Invalid schema (schema.invalid) disqualifies the page from rich results even if the type is appropriate. Deprecated schema types (schema.deprecated_type) or deprecated FAQ schema (schema.faq_deprecated) signal that your markup hasn't kept pace with Google's guidelines. Incomplete Product markup (schema.product_incomplete) fails Google's required-field validation for product rich results.
- Open Graph and Twitter Card tags are present. Missing OG tags (og.missing) and missing Twitter Card tags (twitter.missing) produce poor previews in social and messaging platforms, reducing referral traffic.
See also: Structured Data Guide
5. Performance
Page speed is a confirmed ranking signal for both desktop and mobile. It also directly affects crawl budget — slow pages get crawled less.
- Server response time is within range. Slow response (perf.slow_response) increases Time to First Byte, which cascades into all Core Web Vitals metrics.
- HTML payload is appropriately sized. Large HTML (perf.large_html) delays parsing and increases bandwidth costs, particularly on mobile connections.
- Render-blocking resources are minimized. Render-blocking scripts and stylesheets (perf.render_blocking) delay First Contentful Paint, directly harming LCP scores.
- Caching headers are set. Pages with no cache directives (cache.not_cacheable) force full re-fetches on every crawl, wasting crawl budget and slowing repeat user visits.
See also: Core Web Vitals
6. JavaScript Rendering
Google renders JavaScript, but the rendering pipeline is separate from crawling and operates at delay. Content or signals that exist only after rendering are second-class citizens.
- Core content is in the initial HTML. Content only available post-JS (render.content_js_only) and links only injected by JS (render.links_js_only) are second-class to Google's crawl pipeline.
- Critical tags are stable after rendering. Client-side changes to the
<title>(render.title_changed), canonical (render.canonical_changed), or robots meta (render.robots_changed) override the raw HTML — the rendered version wins, which frequently causes unexpected noindex or wrong-canonical issues. - Navigation does not require JavaScript. Fully JS-dependent navigation (rendering.js_dependent) is a significant crawlability risk for large sites.
See also: JavaScript SEO & Rendering
7. Media & Video
Images and video require explicit signals for search engines to surface them in image and video search.
- Images have descriptive alt text. Missing alt (images.missing_alt) removes image search eligibility and fails accessibility requirements. Alt text that is too long (images.alt_too_long) reads as keyword stuffing.
- Images load. Broken images (images.broken) cause layout shifts (CLS) and signal poor site maintenance. Missing width/height dimensions (images.missing_dimensions) cause layout shifts before load.
- Video is accessible and correctly described. Hidden video (video.hidden) — display-none or off-screen at load — is not eligible for video rich results. Video without a visible player (video.no_player) fails Google's player-on-page requirement. Using your own domain as
contentUrlinstead of the original video source (video.contenturl_self_host) misrepresents provenance and can cause validation failures.
8. Internationalization, URLs & Encoding
Hreflang and mobile-alternate signals must be reciprocal and consistent. URL structure affects crawl efficiency and link equity.
- Hreflang is complete and reciprocal. Pages missing a self-referencing hreflang (hreflang.missing_self), lacking an
x-defaulttag (hreflang.x_default_missing), using invalid language codes (hreflang.invalid_code), or missing return links from targets (hreflang.no_return) will have their hreflang sets ignored entirely. - Language is declared in HTML. Missing
langattribute (i18n.lang_missing) prevents browsers and assistive technology from language-switching correctly. - Mobile alternates match the canonical. Mismatches in canonical (mobile.canonical_mismatch), content (mobile.content_mismatch), robots (mobile.robots_mismatch), title (mobile.title_mismatch), meta (mobile.meta_mismatch), links (mobile.links_mismatch), or structured data (mobile.structured_data_missing) create indexability inconsistencies. Missing viewport meta (mobile.viewport_missing) and Vary headers (mobile.no_vary) are common dynamic-serving failures.
- URLs are clean and consistent. Non-ASCII characters (url.non_ascii), uppercase letters (url.uppercase), double slashes (url.double_slash), excessively long URLs (url.too_long), too many query parameters (url.many_params), and underscores instead of hyphens (url.underscores) all create unnecessary variant URLs or reduce readability.
- Document encoding is declared. Missing charset declaration (encoding.charset_missing) risks character rendering failures. Missing doctype (encoding.doctype_missing) triggers browser quirks mode, which changes layout behavior.
See also: Hreflang & International SEO
9. Security, Accessibility & AI Signals
Security headers, accessibility structure, and AI-crawler signals are increasingly part of technical hygiene that Google and AI-driven search engines evaluate.
- Security headers are present. Missing headers (security.missing_headers), mixed content (security.mixed_content), forms on HTTP (security.form_on_http), and unsafe cross-origin links (security.unsafe_cross_origin_links) are all baseline failures that erode user trust and signal poor maintenance.
- Accessibility landmarks and ARIA are correct. No main landmark (agent.no_main_landmark), skipped heading levels (agent.heading_skip), dialogs without accessible names (agent.dialog_no_name), controls without names (agent.control_no_name), and invalid ARIA roles (agent.aria_invalid_role) all fail WCAG criteria and signal poor rendering quality to search engines.
- AI crawler policy is defined. A missing
llms.txtfile (agent.llms_txt_missing) leaves AI agents without structured guidance on how to use your content. Blocking AI bots entirely (geo.ai_bots_blocked) opts you out of AI-driven search referrals. Pages with no structured answer blocks (geo.no_answer_block) are less likely to surface in AI-generated answers. - AI-generated content is edited. Unedited LLM phrases (ai.leftover_llm_phrase), low lexical variety (ai.low_variety), prompt leakage (ai.prompt_leak), and unreviewed AI self-disclosure (ai.self_disclosure) can trigger quality filters.
- Deprecated technologies are removed. AMP pages (amp.deprecated) are no longer a ranking signal and add maintenance overhead without benefit.
See also: AI Bot Crawling Policy | GEO & AEO for AI Search
How Crawlinx Covers This
Crawlinx checks every item in this list against the raw HTTP response and the rendered DOM — no sampling, no manual spot-checks. Each issue is classified by the codes above, so you can filter to the exact problem category. Run a crawl, export the issue list, and work through it theme by theme.
Audit your own site — free
77 checks, internal PageRank, render-diff. No signup, results in ~30s.