Why Auditing Matters
An on-page SEO audit identifies issues holding your pages back from ranking. It covers content quality, technical elements, user experience, and competitive gaps. Regular audits keep your site optimized and competitive.
The 20 Checks
Every check ranked by impact. Start at the top and work down.
| # | Check | Category | Impact | Difficulty |
|---|---|---|---|---|
| 1 | Audit title tags for all pages | Meta | Critical | Medium |
| 2 | Review meta descriptions | Meta | Critical | Medium |
| 3 | Check heading hierarchy | Content | Critical | Easy |
| 4 | Evaluate content quality and depth | Content | Critical | Hard |
| 5 | Audit internal linking structure | Links | High | Medium |
| 6 | Check image optimization | Media | High | Easy |
| 7 | Review schema markup | Schema | High | Easy |
| 8 | Analyze Core Web Vitals | Performance | High | Medium |
| 9 | Check mobile-friendliness | Mobile | High | Easy |
| 10 | Audit canonical tags | Technical | High | Easy |
| 11 | Review URL structure | URLs | Medium | Easy |
| 12 | Check for duplicate content | Content | Medium | Medium |
| 13 | Analyze competitor pages | Competitive | Medium | Hard |
| 14 | Review social meta tags | Social | Medium | Easy |
| 15 | Check accessibility compliance | Accessibility | Medium | Medium |
| 16 | Audit conversion elements | CRO | Medium | Easy |
| 17 | Review E-E-A-T signals | Trust | Low | Medium |
| 18 | Check content freshness | Content | Low | Easy |
| 19 | Analyze user engagement metrics | Analytics | Low | Easy |
| 20 | Create prioritized action plan | Planning | Low | Easy |
Full Audit Workflow: Step-by-Step
Follow this exact sequence to audit any page. Each step builds on the previous one.
Step 1: Crawl the Site
Run a full crawl with Screaming Frog or Sitebulb. Export every URL with its status code, title tag, meta description, H1, word count, and canonical URL. This gives you the raw data for every check that follows.
# Crawl a site and export to CSV screamingfrogseospider --crawl https://example.com \ --output-folder ./audit-results \ --export-format csv \ --headless # Key files to review: # - internal_all.csv (all pages) # - response_codes.csv (errors) # - page_titles.csv (title tags) # - meta_description.csv (meta descriptions)
Step 2: Pull Search Console Data
Export 16 months of data from Google Search Console: clicks, impressions, CTR, and average position for every URL. Merge this with your crawl data to identify pages with high impressions but low CTR (title tag opportunities) or declining clicks (content decay).
from google.oauth2 import service_account
from googleapiclient.discovery import build
credentials = service_account.Credentials.from_service_account_file(
'service-account.json',
scopes=['https://www.googleapis.com/auth/webmasters.readonly']
)
service = build('searchconsole', 'v1', credentials=credentials)
request = {
'startDate': '2025-04-01',
'endDate': '2026-08-01',
'dimensions': ['page', 'query'],
'rowLimit': 25000
}
response = service.searchanalytics().query(
siteUrl='https://example.com', body=request
).execute() Step 3: Run Lighthouse on Top Pages
Run Lighthouse on your top 20 pages by traffic. Record Performance, Accessibility, Best Practices, and SEO scores. Pay special attention to Core Web Vitals: LCP, INP, and CLS.
# Run Lighthouse and save JSON report lighthouse https://example.com/page \ --output json \ --output-path ./lighthouse-report.json \ --chrome-flags="--headless --no-sandbox" # Extract scores with jq cat lighthouse-report.json | jq '.categories | { performance: .performance.score, accessibility: .accessibility.score, seo: .seo.score, "best-practices": ."best-practices".score }'
Step 4: Check Indexing Status
For every important URL, verify it is indexed in Google. Use the URL Inspection API or check manually. Flag pages that are crawled but not indexed, or excluded by robots.txt or noindex tags.
# Check if URLs are indexed using site: search
# (Manual method - use for spot checks)
# Google: site:example.com/page-url
# Automated via GSC URL Inspection API
request = {
'inspectionUrl': 'https://example.com/page',
'siteUrl': 'https://example.com'
}
result = service.urlInspection().inspect(body=request).execute()
index_status = result['inspectionResult']['indexStatusResult']['verdict']
# VERDICT values: PASS, FAIL, NEUTRAL Step 5: Document Findings in a Spreadsheet
Create a master audit spreadsheet with columns: URL, Issue, Category, Impact (Critical/High/Medium/Low), Difficulty (Easy/Medium/Hard), Fix Description, Status. Sort by Impact descending. This becomes your action plan.
Step 6: Assign and Track Fixes
Assign each fix to a team member with a deadline. Track progress weekly. Re-audit fixed pages after 30 days to verify improvement. Update the spreadsheet with before/after metrics.
Title Tag Audit
Title tags are the single highest-impact on-page element. Audit every page systematically.
What to Check
- Length: Under 60 characters. Google truncates at ~600px (varies by character width).
- Keyword placement: Target keyword in the first 40 characters. Front-loading signals relevance.
- Uniqueness: Every page must have a unique title. Duplicates confuse crawlers and split CTR.
- Brand name: Append brand with pipe separator:
Keyword | Brand. Remove if over 60 chars. - Click appeal: Include a number, year, or power word (Ultimate, Complete, Free) when relevant.
- No keyword stuffing: One primary keyword max. Stuffing triggers truncation and looks spammy.
On-Page SEO Audit Checklist: 20 Steps for 2026 SEO | Search Engine Optimization | SEO Tips | SEO Guide 2026 - Best SEO Practices Technical SEO Audit Guide: Complete Checklist (2026) | Clienvora [Product Name] - [Key Feature] | [Brand] [Service] in [City] - [Differentiator] | [Brand]
How to Fix Title Tags
<!-- In your <head> tag --> <head> <title>On-Page SEO Audit Checklist: 20 Steps for 2026</title> <!-- Keep under 60 characters --> <!-- Place target keyword in first 40 characters --> <!-- Use pipe | or dash - to separate brand --> </head> <!-- In Astro (dynamic pages) --> --- const { title, keyword } = Astro.props; const pageTitle = `${keyword}: ${title} (2026) | Clienvora`; --- <head> <title>{pageTitle}</title> </head>
Tools for Title Tag Auditing
- Screaming Frog: Crawl and export all title tags. Filter by length, duplicates, and missing.
- Ahrefs Site Audit: Flags duplicate and missing titles automatically in the "On-page" report.
- Google Search Console: Check "Performance" report for pages with high impressions but low CTR.
- SERPSim.com: Preview how your title will look in Google SERPs before publishing.
Meta Description Audit
Meta descriptions don't affect rankings directly, but they control your SERP snippet and CTR.
What to Check
- Length: 120-155 characters. Under 120 is too thin. Over 155 gets truncated.
- Keyword inclusion: Include the target keyword once. Google bolds matching terms in snippets.
- Call to action: End with a CTA: "Learn more," "Get the checklist," "Start free."
- Uniqueness: Every page needs a unique description. Duplicates waste SERP real estate.
- Value proposition: Tell the reader what they will get, not what the page is about.
- No quotation marks: Google truncates at quotes. Use apostrophes if needed.
<meta name="description" content="20-step on-page SEO audit checklist with code examples, tools, and a prioritization framework. Free download. Start auditing today."> <meta name="description" content="SEO audit checklist."> <meta name="description" content="Learn how to [achieve X] with [this guide/tool]. [Number] steps, [timeframe] results. [CTA]."> <meta name="description" content="[Product] helps you [benefit]. [Social proof]. [CTA].">
How to Fix
<!-- In your <head> tag --> <meta name="description" content="Your 120-155 character description here."> <!-- In Astro (dynamic) --- --- const { description } = Astro.props; const metaDesc = description.length > 155 ? description.slice(0, 152) + '...' : description; --- <meta name="description" content={metaDesc} /> <!-- In Next.js / React --> <Head> <meta name="description" content={metaDesc} /> </Head>
Content Quality Audit (E-E-A-T)
Google's Quality Rater Guidelines emphasize Experience, Expertise, Authoritativeness, and Trustworthiness. Audit every page against this checklist.
Experience Checklist
- Does the content include first-hand experience (screenshots, case studies, personal results)?
- Are there specific examples from real projects, not generic advice?
- Does the author have demonstrable experience in this topic?
- Are there original images, data, or research instead of stock photos?
Expertise Checklist
- Is the author a recognized expert? Link to their bio, LinkedIn, or credentials.
- Does the content cover the topic in depth (not just surface-level)?
- Are claims backed by data, citations, or authoritative sources?
- Is the content technically accurate and free of errors?
- Does it answer related questions users actually ask?
Authoritativeness Checklist
- Does the page have a clear author byline with a bio?
- Is the site recognized as an authority in this niche (backlinks, mentions)?
- Are there external links to authoritative sources (studies, official docs)?
- Does the content cite primary sources instead of other blog posts?
Trustworthiness Checklist
- Is there a clear "About" page and contact information?
- Does the site have HTTPS enabled?
- Are there clear privacy policy and terms of service pages?
- For YMYL topics: is there editorial review or fact-checking mentioned?
- Are there fake testimonials, exaggerated claims, or misleading information?
Content Depth Audit
# Compare your content against top-ranking pages
# Uses Ahrefs API to pull word counts and heading structures
import requests
# Get top pages for target keyword
keyword = "on-page seo audit"
url = f"https://api.ahrefs.com/v3/serp/overview"
params = {
"keyword": keyword,
"country": "us",
"output": "json"
}
response = requests.get(url, params=params, headers={"Authorization": "Bearer YOUR_TOKEN"})
top_pages = response.json()["serp"]["overview"]
# Compare word counts
for page in top_pages[:5]:
print(f"{page['url']}: {page['word_count']} words")
# Your page should match or exceed the average Internal Link Audit
Internal links distribute authority and help Google understand your site structure. A weak internal link profile is one of the most common audit findings.
What to Check
- Orphan pages: Pages with zero internal links pointing to them. They are invisible to crawlers.
- Broken internal links: Links pointing to 404 pages. Wastes crawl budget and creates dead ends.
- Anchor text: Use descriptive anchor text, not "click here" or "read more."
- Link depth: Important pages should be reachable in 3 clicks or fewer from the homepage.
- Contextual links: Links within body content carry more weight than footer or sidebar links.
- Link equity flow: High-authority pages should link to pages that need a boost.
# After crawling, check these reports: # 1. Bulk Export > Links > All Inlinks # 2. Response Codes > Client Error (4xx) - broken links # 3. Orphan Pages (enable Google Analytics integration) # Find orphan pages (pages with 0 inlinks) # In the "Internal" tab, filter by "Inlinks" = 0 # Find pages with too many outbound links # Filter: Outlinks > 100 (may indicate link spam) # Check link depth # In the "Internal" tab, check "Crawl Depth" column # Pages with depth > 3 need more internal links
How to Fix Internal Link Issues
<!-- Bad: generic anchor text -->
<a href="/guide">Click here</a> to read the guide.
<!-- Good: descriptive anchor text with keyword -->
<a href="/checklists/on-page-seo/on-page-audit/">
on-page SEO audit checklist
</a>
<!-- Add contextual links in body content -->
<p>
After fixing title tags, move on to
<a href="/checklists/on-page-seo/meta-tags/">
meta description optimization
</a>
for higher click-through rates.
</p>
<!-- Link from high-authority pages to pages needing a boost -->
<!-- Find high-authority pages in Ahrefs: Pages > Best by Links --> Schema Markup Audit
Structured data helps Google understand your content and can trigger rich results like FAQ snippets, review stars, and how-to cards.
What to Check
- Presence: Does every page have at least one schema type?
- Validity: Is the JSON-LD error-free? Test with Google Rich Results Test.
- Relevance: Does the schema type match the page content (Article for blogs, Product for products)?
- Required properties: Does each schema type include all required fields?
- Nesting: Are related schemas properly nested (e.g., Author inside Article)?
- Breadcrumbs: Is BreadcrumbList schema present on all pages?
<!-- Article schema for blog posts -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "Your Title Here",
"author": { "@type": "Person", "name": "Author Name" },
"datePublished": "2026-08-01",
"dateModified": "2026-08-10",
"image": "https://example.com/image.jpg"
}
</script>
<!-- FAQPage schema for pages with FAQs -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [{
"@type": "Question",
"name": "Your question here?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Your answer here."
}
}]
}
</script>
<!-- BreadcrumbList for navigation -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{ "@type": "ListItem", "position": 1, "name": "Home", "item": "https://example.com/" },
{ "@type": "ListItem", "position": 2, "name": "Category", "item": "https://example.com/category/" }
]
}
</script> Schema Validation Tools
- Google Rich Results Test:
https://search.google.com/test/rich-results- Validates and previews rich results. - Schema Markup Validator:
https://validator.schema.org/- Checks all schema types, not just rich results. - Screaming Frog: Extracts and validates JSON-LD during a crawl. Filter by "Structured Data" tab.
Core Web Vitals Audit
Core Web Vitals are a ranking factor. Audit LCP, INP, and CLS on every important page.
The Three Metrics
- LCP (Largest Contentful Paint): How fast the main content loads. Target: under 2.5 seconds.
- INP (Interaction to Next Paint): How fast the page responds to clicks. Target: under 200ms.
- CLS (Cumulative Layout Shift): How much the page layout jumps. Target: under 0.1.
Common LCP Fixes
<!-- Preload the LCP image --> <link rel="preload" as="image" href="/hero.webp" fetchpriority="high"> <!-- Use responsive images with srcset --> <img src="/hero-800.webp" srcset="/hero-400.webp 400w, /hero-800.webp 800w, /hero-1200.webp 1200w" sizes="(max-width: 768px) 100vw, 800px" alt="Descriptive alt text" loading="eager" fetchpriority="high" width="800" height="450" > <!-- Remove render-blocking CSS --> <link rel="stylesheet" href="/critical.css"> <link rel="preload" href="/non-critical.css" as="style" onload="this.onload=null;this.rel='stylesheet'"> <!-- Inline critical CSS --> <style> /* Only the CSS needed for above-the-fold content */ .hero { display: flex; align-items: center; min-height: 80vh; } </style>
Common CLS Fixes
<!-- Always set width and height on images -->
<img src="/photo.jpg" alt="..." width="800" height="600">
<!-- Reserve space for dynamic content -->
<div style="min-height: 200px;">
<!-- Ad or embed loads here -->
</div>
<!-- Use aspect-ratio for responsive media -->
<style>
.video-container {
aspect-ratio: 16 / 9;
width: 100%;
}
</style>
<!-- Avoid inserting content above existing content -->
<!-- Load fonts with font-display: swap -->
<style>
@font-face {
font-family: 'Inter';
src: url('/inter.woff2') format('woff2');
font-display: swap;
}
</style> Common INP Fixes
<!-- Defer non-critical JavaScript -->
<script src="/analytics.js" defer></script>
<!-- Use requestIdleCallback for non-urgent work -->
<script>
requestIdleCallback(() => {
// Load non-critical features
loadChatWidget();
loadSocialButtons();
});
</script>
<!-- Break up long tasks with scheduler.yield() -->
<script>
async function processData(items) {
for (const item of items) {
processItem(item);
// Yield to main thread every iteration
await scheduler.yield();
}
}
</script> Mobile-Friendliness Audit
Google uses mobile-first indexing. Your mobile experience IS your ranking experience.
What to Check
- Viewport meta tag: Must be present:
<meta name="viewport" content="width=device-width, initial-scale=1"> - Text readability: Font size at least 16px for body text. No horizontal scrolling.
- Tap targets: Buttons and links at least 48x48px with 8px spacing between them.
- Responsive images: Images scale correctly. No images wider than viewport.
- No intrusive interstitials: Popups that cover content on mobile hurt rankings.
- Mobile page speed: Mobile LCP should be under 2.5 seconds on 4G.
<!-- Viewport meta tag (required) -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Responsive container -->
<style>
.container {
width: min(100% - 2rem, 1200px);
margin-inline: auto;
padding-inline: 1rem;
}
/* Mobile-first media queries */
.grid {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
}
@media (min-width: 768px) {
.grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
.grid { grid-template-columns: repeat(3, 1fr); }
}
/* Minimum tap target size */
button, a.button {
min-height: 48px;
min-width: 48px;
padding: 12px 24px;
}
</style> Prioritization Framework: Impact vs Effort
Not all audit findings are equal. Use this matrix to decide what to fix first.
Do First
High Impact, Low Effort
- Fix duplicate title tags
- Add missing meta descriptions
- Fix broken internal links
- Add alt text to images
- Add BreadcrumbList schema
Schedule
High Impact, High Effort
- Rewrite thin content pages
- Fix Core Web Vitals issues
- Build internal link structure
- Add E-E-A-T signals
- Competitive content gaps
Quick Wins
Low Impact, Low Effort
- Add Open Graph tags
- Update copyright year
- Add favicon
- Fix 301 redirect chains
- Update social links
Backlog
Low Impact, High Effort
- Full site redesign
- Migrate to new CMS
- Rebuild all schema
- Rewrite URL structure
- Merge duplicate pages
Monthly & Quarterly Audit Schedule
Audit frequency depends on page importance. Use this template to stay on track.
Weekly (5-10 minutes)
- Check Google Search Console for new crawl errors
- Monitor Core Web Vitals for regressions
- Review any pages that dropped in rankings
Monthly (1-2 hours)
- Audit title tags and meta descriptions on top 10 pages by traffic
- Check for new 404 errors and broken links
- Review new content before publishing for on-page basics
- Update internal links on recently published content
- Check indexing status of new pages
Quarterly (4-8 hours)
- Full site crawl with Screaming Frog or Sitebulb
- Content quality audit on all pages (E-E-A-T review)
- Schema markup validation across all templates
- Competitive analysis: compare top 5 competitors
- Core Web Vitals audit on top 20 pages
- Internal link structure review
- Update the prioritized action plan
After Google Core Updates
- Re-audit pages that lost rankings
- Check for new SERP features (AI Overviews, People Also Ask)
- Review content against updated quality guidelines
- Compare your E-E-A-T signals against new top-ranking pages
URL,Issue,Category,Impact,Difficulty,Fix,Status,Due Date,Assigned To https://example.com/page-1,Duplicate title tag,Meta,Critical,Easy,Rewrite title,To Do,2026-08-20,John https://example.com/page-2,Missing meta description,Meta,Critical,Easy,Write meta desc,To Do,2026-08-20,Jane https://example.com/page-3,LCP > 4s,Performance,High,Medium,Optimize images,In Progress,2026-08-25,John https://example.com/page-4,Thin content (<300 words),Content,High,Hard,Expand to 1500+ words,To Do,2026-09-01,Jane https://example.com/page-5,No schema markup,Schema,High,Easy,Add Article schema,Done,2026-08-15,John
Audit Tools
The right tools make audits faster and more thorough. Here are the ones we recommend.
Screaming Frog
Free up to 500 URLsThe industry standard desktop crawler. Exports title tags, meta descriptions, headings, status codes, canonical tags, and more. The free version handles small sites. Paid version (£199/year) removes the URL limit and adds scheduling, custom extraction, and JavaScript rendering.
Sitebulb
From $14/monthA desktop crawler with better visualizations than Screaming Frog. Generates crawl maps, priority hints, and color-coded issue reports. The hints system tells you exactly what to fix and why. Good for clients who need visual reports.
Ahrefs Site Audit
From $99/monthCloud-based crawler that runs scheduled audits. Tracks health score over time, flags new issues, and integrates with Ahrefs backlink data. The "Content" report shows thin content, duplicate content, and missing meta tags across your entire site.
Semrush Site Audit
From $119/monthSimilar to Ahrefs but with stronger on-page analysis. The "On Page SEO Checker" gives specific recommendations per page based on top-ranking competitors. Includes internal linking suggestions and content ideas.
Google Search Console
FreeYour direct line to Google's index. Shows crawl errors, indexing status, mobile usability issues, Core Web Vitals, and search performance data. No other tool gives you this data straight from Google. Essential for every audit.
Google Lighthouse
FreeBuilt into Chrome DevTools (F12 > Lighthouse tab). Audits performance, accessibility, best practices, and SEO. Runs locally or via CLI. Use it to test individual pages for Core Web Vitals, mobile-friendliness, and basic SEO checks.
PageSpeed Insights
FreePowered by Lighthouse but adds real-user Chrome User Experience Report (CrUX) data. Shows how actual users experience your page, not just lab scores. Use this alongside Lighthouse for a complete performance picture.
Frequently Asked Questions
Start by crawling your site with Screaming Frog or Sitebulb to surface technical errors. Then work through title tags, meta descriptions, heading hierarchy, content quality, internal links, schema markup, and Core Web Vitals in priority order. Document every finding in a spreadsheet, assign an impact score, and fix critical issues first before moving to medium- and low-priority items.
Run a full on-page audit once per quarter. For high-traffic or high-conversion pages, do a quick check every month covering title tags, meta descriptions, and Core Web Vitals. You should also audit new content before publishing and re-audit any page that drops in rankings after a Google core update.
At minimum you need Google Search Console (free) for search performance data and a crawler like Screaming Frog (free up to 500 URLs) or Sitebulb. For competitive analysis and backlink data, add Ahrefs or Semrush. Use Google Lighthouse and PageSpeed Insights for Core Web Vitals. All four together give you complete coverage of technical, content, and performance issues.
A basic audit for a small site (under 50 pages) takes 2-4 hours. A comprehensive audit for a 500+ page site with competitive analysis, content gap research, and a prioritized action plan can take 1-2 weeks. The biggest time sinks are content quality reviews and manual E-E-A-T checks, which cannot be fully automated.
Title tag optimization consistently delivers the highest ROI because it directly affects click-through rate and keyword relevance. A well-crafted title with the target keyword near the front, a compelling value proposition, and under 60 characters can lift organic traffic 10-30% on its own. After titles, internal linking and content depth are the next highest-impact fixes.
Yes. Analyzing the top 5-10 ranking pages for your target keyword reveals content gaps, missing subtopics, and structural patterns you need to match or exceed. Look at their word count, heading structure, schema usage, and internal link profiles. This competitive data turns your audit from a fix-it list into a strategic roadmap for outranking them.