SEO Score Checker & Page Auditor

Paste your webpage's raw HTML source code to analyze SEO compliance, identify error attributes, and view instant optimization guides.

Use Tool Below ↓
Paste Raw HTML Source Code
0%
Needs Improvement

Your page structure has multiple critical SEO errors. Review the expanded issues below to fix meta configurations.

0 Errors 0 Warnings 0 Passed

How to Perform a Webpage SEO Audit

🖥️
1. Copy Source Code
Go to your page, open Source View (Ctrl+U or Right Click -> View Page Source), and select and copy everything (Ctrl+A, Ctrl+C).
📝
2. Paste and Audit
Paste the HTML code into our text editor box above and click the "Audit SEO Score" button.
🚀
3. Fix Recommendations
Inspect failures and warnings. Follow the generated guide details to boost search rankings.

Complete SEO Auditing Criteria

🔍 Tags Compliance
Checks title tags length, meta description availability, and absolute canonical tags definitions.
📱 Mobile Layout viewport
Ensures proper responsive viewport parameters are configured for flawless mobile render ranking.
🏷️ Media & Accessibility
Scans image tags for missing alt descriptions attributes to maintain accessibility standards.

Frequently Asked Questions

Why paste HTML instead of crawling a URL? +
Browser security constraints (CORS) block direct requests to foreign domains from clients. Direct code pasting allows deep, instantaneous parsing without backend proxy servers.
Does this tool check Open Graph attributes? +
Yes. It validates Facebook (og:title, og:description, og:image) and Twitter card configuration targets to optimize social share previews.
What is the ideal title tag length? +
For optimum SERP snippets display on search engines, titles should stay between 30 and 60 characters. Descriptions should be between 120 and 160 characters.

Explore Complementary SEO Tools

Ready to explore more free tools?

DevToolkit has 40+ utility modules waiting for you.

Explore All Tools →
`; document.getElementById('btn-sample').addEventListener('click', () => { document.getElementById('html-input').value = sampleHtml; }); document.getElementById('btn-clear').addEventListener('click', () => { document.getElementById('html-input').value = ''; document.getElementById('dashboard-panel').style.display = 'none'; }); // Active Tab tracking let currentTab = 'all'; let auditResults = []; // Analyze Engine Mechanics document.getElementById('btn-analyze').addEventListener('click', async () => { const rawHtml = document.getElementById('html-input').value.trim(); if (!rawHtml) { alert("Please paste your HTML source code to proceed."); return; } // DOM Parser Compilation const parser = new DOMParser(); const doc = parser.parseFromString(rawHtml, "text/html"); auditResults = []; // 1. Title Audit const titleNode = doc.querySelector('title'); if (!titleNode) { auditResults.push({ type: 'error', title: 'Missing Page Title Tag', body: 'The tag is completely missing from the HTML document.', recommendation: 'Add a <title>Your Title element in the block with a length between 30 and 60 characters.' }); } else { const titleLen = titleNode.textContent.trim().length; if (titleLen < 30 || titleLen > 60) { auditResults.push({ type: 'warning', title: `Title Length Sub-optimal (${titleLen} characters)`, body: `Your page title is ${titleLen} characters. Search engines typically truncate values longer than 60 or ignore short values under 30.`, recommendation: 'Modify your title length to stay within 30 to 60 characters (e.g. current target is ' + titleNode.textContent.trim() + ').' }); } else { auditResults.push({ type: 'pass', title: 'Optimal Title Tag Length', body: `Passed: The title length is ideal (${titleLen} characters): "${titleNode.textContent.trim()}".` }); } } // 2. Meta Description Audit const descNode = doc.querySelector('meta[name="description"]'); if (!descNode) { auditResults.push({ type: 'error', title: 'Missing Meta Description Tag', body: 'The description metadata parameter is missing from the document header.', recommendation: 'Add inside describing your page content within 120-160 characters.' }); } else { const descContent = descNode.getAttribute('content') || ''; const descLen = descContent.trim().length; if (descLen < 120 || descLen > 160) { auditResults.push({ type: 'warning', title: `Sub-optimal Meta Description Length (${descLen} characters)`, body: `Your description length is ${descLen} characters. Aim for 120-160 characters to optimize Google snippet previews.`, recommendation: 'Adjust description attributes to contain between 120 and 160 characters.' }); } else { auditResults.push({ type: 'pass', title: 'Optimal Description Tag Length', body: `Passed: Meta description is correctly configured (${descLen} characters).` }); } } // 3. Viewport Audit const viewNode = doc.querySelector('meta[name="viewport"]'); if (!viewNode) { auditResults.push({ type: 'error', title: 'Missing Mobile Viewport Tag', body: 'No responsive viewport layout tag was detected in your document header.', recommendation: 'Add to trigger responsive mobile viewport rendering.' }); } else { auditResults.push({ type: 'pass', title: 'Mobile Viewport Tag Detected', body: 'Passed: Responsive viewports are correctly configured for mobile devices.' }); } // 4. H1 Heading audit const h1s = doc.querySelectorAll('h1'); if (h1s.length === 0) { auditResults.push({ type: 'error', title: 'Missing H1 Primary Heading', body: 'Your document does not contain an

tag.', recommendation: 'Always introduce exactly one

element per page to act as the primary title header for search algorithms.' }); } else if (h1s.length > 1) { auditResults.push({ type: 'warning', title: `Multiple H1 Heading Tags Detected (${h1s.length})`, body: `Found ${h1s.length}

tags. Using multiple primary headings may confuse indexing algorithms mapping primary context.`, recommendation: 'Downgrade secondary

tags to

or

elements, keeping only one

at the top.' }); } else { auditResults.push({ type: 'pass', title: 'Single H1 Heading Configured', body: `Passed: Exact single

tag parsed successfully: "${h1s[0].textContent.trim()}".` }); } // 5. Canonical Url Audit const canonNode = doc.querySelector('link[rel="canonical"]'); if (!canonNode) { auditResults.push({ type: 'warning', title: 'Missing Canonical URL Link', body: 'No canonical URL link (rel="canonical") tag was detected.', recommendation: 'Add in your head to avoid duplicate content penalties.' }); } else { auditResults.push({ type: 'pass', title: 'Canonical URL Defined', body: `Passed: The canonical URL link is correctly defined: "${canonNode.getAttribute('href')}".` }); } // 6. Image alt attribute audit const imgs = doc.querySelectorAll('img'); if (imgs.length > 0) { let missingAlt = 0; imgs.forEach(i => { if (!i.hasAttribute('alt') || i.getAttribute('alt').trim() === '') { missingAlt++; } }); if (missingAlt > 0) { auditResults.push({ type: 'warning', title: `Missing Alt Text on Images (${missingAlt}/${imgs.length})`, body: `You have ${missingAlt} out of ${imgs.length} images missing "alt" text attributes. This degrades accessibility scores.`, recommendation: 'Loop through your image elements and append descriptive alt attributes (e.g. Description of image).' }); } else { auditResults.push({ type: 'pass', title: 'All Images Contain Alt Text', body: `Passed: All ${imgs.length} image tags have valid descriptive alt text definitions.` }); } } // 7. Open Graph metadata audit const ogTitle = doc.querySelector('meta[property="og:title"]'); const ogDesc = doc.querySelector('meta[property="og:description"]'); if (!ogTitle || !ogDesc) { auditResults.push({ type: 'warning', title: 'Incomplete Open Graph Metadata', body: 'Social share properties (og:title, og:description) are partially or fully missing.', recommendation: 'Include basic Open Graph header meta tags to generate professional cards on platforms like Facebook and LinkedIn.' }); } else { auditResults.push({ type: 'pass', title: 'Open Graph Metadata Complete', body: 'Passed: The page contains valid Facebook social share metadata.' }); } // Calculate score out of 100 based on weight logic let passes = auditResults.filter(r => r.type === 'pass').length; let warnings = auditResults.filter(r => r.type === 'warning').length; let errors = auditResults.filter(r => r.type === 'error').length; let totalChecks = auditResults.length; // Weighted score: error counts -15, warning counts -6 let scoreVal = 100 - (errors * 15) - (warnings * 6); scoreVal = Math.max(0, Math.min(100, scoreVal)); // Display Dashboard document.getElementById('dashboard-panel').style.display = 'flex'; // Update Radial const progressCircle = document.getElementById('score-progress'); const radius = 60; const circumference = 2 * Math.PI * radius; const offset = circumference - (scoreVal / 100) * circumference; progressCircle.style.strokeDashoffset = offset; document.getElementById('score-text').textContent = `${scoreVal}%`; // Status text updates const statusTitle = document.getElementById('score-status-title'); const statusDesc = document.getElementById('score-status-desc'); if (scoreVal >= 90) { statusTitle.textContent = 'Excellent SEO compliance!'; statusDesc.textContent = 'Your page conforms to major search engine guidelines. It is fully ready for high organic search rankings.'; progressCircle.setAttribute('stroke', '#00FF66'); } else if (scoreVal >= 70) { statusTitle.textContent = 'Good structure (Needs tweaks)'; statusDesc.textContent = 'You have minor warnings and attributes configurations missing. Adjust the warning components to maximize organic traffic.'; progressCircle.setAttribute('stroke', '#FF9900'); } else { statusTitle.textContent = 'Critical SEO issues found'; statusDesc.textContent = 'Your page has critical errors like missing titles or headings structures. Use the audit recommendations to fix these constraints immediately.'; progressCircle.setAttribute('stroke', '#FF0066'); } // Counter badges document.getElementById('cnt-errors').textContent = `${errors} Errors`; document.getElementById('cnt-warnings').textContent = `${warnings} Warnings`; document.getElementById('cnt-passed').textContent = `${passes} Passed`; // Render Issues renderIssues(); // Log usage await logToolUsage('SEO Score Checker', 'seo', 'seo-score-checker'); }); function renderIssues() { const listContainer = document.getElementById('audit-list'); listContainer.innerHTML = ''; let filtered = auditResults; if (currentTab === 'errors') filtered = auditResults.filter(r => r.type === 'error'); if (currentTab === 'warnings') filtered = auditResults.filter(r => r.type === 'warning'); if (currentTab === 'passed') filtered = auditResults.filter(r => r.type === 'pass'); if (filtered.length === 0) { listContainer.innerHTML = `
No audits match this filter group.
`; return; } filtered.forEach(item => { const card = document.createElement('div'); card.className = 'audit-item'; let typeBadge = ''; if (item.type === 'error') typeBadge = `Error`; if (item.type === 'warning') typeBadge = `Warning`; if (item.type === 'pass') typeBadge = `Passed`; card.innerHTML = `
${item.title} ${typeBadge}
${item.body}
${item.recommendation ? `
Fix: ${item.recommendation}
` : ''} `; listContainer.appendChild(card); }); // Update tab counts const tabs = document.getElementById('audit-tabs').querySelectorAll('.tab-btn'); tabs[0].textContent = `All Issues (${auditResults.length})`; tabs[1].textContent = `Errors (${auditResults.filter(r => r.type === 'error').length})`; tabs[2].textContent = `Warnings (${auditResults.filter(r => r.type === 'warning').length})`; tabs[3].textContent = `Passed (${auditResults.filter(r => r.type === 'pass').length})`; } // Tabs clicks document.getElementById('audit-tabs').querySelectorAll('.tab-btn').forEach(btn => { btn.addEventListener('click', (e) => { document.getElementById('audit-tabs').querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active')); btn.classList.add('active'); currentTab = btn.getAttribute('data-type'); renderIssues(); }); });