🔬 SEO Lab Pro

Complete SEO Analysis & Optimization Toolkit - No APIs Required

🌐 URL Analyzer
📄 Page Data
0 chars
0 chars
0 words
📈 Overall SEO Score
0
out of 100
0%
Content
0%
Technical
0%
On-Page
0%
UX
⚠️ Penalty Risk Analysis
Keyword Stuffing

Avoid repeating keywords too frequently

Content Length

Aim for at least 300 words

Title Length

Optimize for 50-60 characters

Risk Level: Low
🔍 SERP Preview
example.com/page
Page Title Here
Meta description will appear here in search results...
📊 Keyword Density
Density: 0% Optimal
Detailed SEO Analysis

On-Page SEO

Content Analysis

🔑 Keyword Analysis
📋 Keyword Suggestions
LSI Keywords:
Semantic Keywords:
📈 Keyword Comparison
Keyword Difficulty Volume CPC Competition Opportunity
💾 Export Options
📄
PDF Report
Printable analysis report
🖥️
HTML Code
Implementation-ready code
📊
CSV Data
Spreadsheet format
🔧
JSON Data
Structured data export
📋 Implementation Code
<title>Your Page Title</title>
<meta name="description" content="Your meta description">
{ "@context": "https://schema.org", "@type": "Article" }

${h1 || title}

${content.replace(/\n/g, '\n ')}
`; } function generateCSVData() { let csv = 'Keyword,Appearances,Density,Status\n'; keywords.forEach(keyword => { const content = document.getElementById('contentInput').value; const contentLower = content.toLowerCase(); const keywordLower = keyword.toLowerCase(); const escapedKeyword = keywordLower.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); const wordCount = countWords(content); const keywordCount = (contentLower.match(new RegExp(escapedKeyword, 'g')) || []).length; const density = wordCount > 0 ? (keywordCount / wordCount) * 100 : 0; const status = density >= 0.5 && density <= 2.5 ? 'Optimal' : density < 0.5 ? 'Too Low' : 'Too High'; csv += `"${keyword}",${keywordCount},${density.toFixed(2)}%,${status}\n`; }); return csv; } function generateJSONData(title, meta, content, h1, primaryKeyword) { const wordCount = countWords(content); const date = new Date().toISOString(); const data = { analysis: { date: date, url: document.querySelector('input[name="url"]').value, score: document.getElementById('overallScore').textContent, riskLevel: document.getElementById('riskLevel').textContent }, page: { title: title, meta: meta, h1: h1, contentLength: wordCount, primaryKeyword: primaryKeyword }, keywords: keywords.map(keyword => { const content = document.getElementById('contentInput').value; const contentLower = content.toLowerCase(); const keywordLower = keyword.toLowerCase(); const escapedKeyword = keywordLower.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); const wordCount = countWords(content); const keywordCount = (contentLower.match(new RegExp(escapedKeyword, 'g')) || []).length; const density = wordCount > 0 ? (keywordCount / wordCount) * 100 : 0; return { keyword: keyword, appearances: keywordCount, density: density, status: density >= 0.5 && density <= 2.5 ? 'optimal' : density < 0.5 ? 'low' : 'high' }; }) }; return JSON.stringify(data, null, 2); } function downloadFile(filename, content, mimeType = 'text/plain') { const blob = new Blob([content], { type: mimeType }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } function copyToClipboard(elementId) { const element = document.getElementById(elementId); const text = element.textContent; navigator.clipboard.writeText(text).then(() => { showNotification('Copied to clipboard!', 'success'); }).catch(err => { // Fallback for older browsers const textArea = document.createElement('textarea'); textArea.value = text; document.body.appendChild(textArea); textArea.select(); document.execCommand('copy'); document.body.removeChild(textArea); showNotification('Copied to clipboard!', 'success'); }); } function animateNumber(element, start, end, duration) { const startTime = performance.now(); function update(currentTime) { const elapsed = currentTime - startTime; const progress = Math.min(elapsed / duration, 1); const easeOut = 1 - Math.pow(1 - progress, 3); const current = Math.floor(start + (end - start) * easeOut); element.textContent = current; if (progress < 1) { requestAnimationFrame(update); } } requestAnimationFrame(update); } function showNotification(message, type = 'info') { const notification = document.getElementById('notification'); notification.textContent = message; notification.className = 'notification'; if (type === 'success') { notification.classList.add('notification-success'); } else if (type === 'error') { notification.classList.add('notification-error'); } else if (type === 'warning') { notification.classList.add('notification-warning'); } else { notification.style.borderLeftColor = 'var(--info)'; } notification.classList.add('show'); setTimeout(() => { notification.classList.remove('show'); }, 3000); } function clearAllData() { if (confirm('Are you sure you want to clear all data? This cannot be undone.')) { // Clear form fields document.getElementById('titleInput').value = ''; document.getElementById('metaInput').value = ''; document.getElementById('h1Input').value = ''; document.getElementById('contentInput').value = ''; document.getElementById('primaryKeyword').value = ''; document.getElementById('secondaryKeywords').value = ''; document.querySelector('input[name="url"]').value = ''; // Clear keywords keywords = []; saveKeywords(); updateKeywordsList(); updateKeywordComparison(); // Clear counters updateCharCounter('titleCounter', 0, 'chars'); updateCharCounter('metaCounter', 0, 'chars'); updateCharCounter('contentCounter', 0, 'words'); // Clear session via PHP window.location.href = '?clear=1'; showNotification('All data cleared', 'info'); } } function openModal(modalId) { document.getElementById(modalId).style.display = 'flex'; } function closeModal(modalId) { document.getElementById(modalId).style.display = 'none'; }