SEO Score
Get a 0-100 SEO score with letter grade based on title, description, OG tags, Twitter cards, and 15+ other factors.
Analyze any webpage's meta tags, get an instant SEO score, preview social cards, and receive actionable optimization recommendations.
Fetching and analyzing meta tags...
A comprehensive SEO toolkit to audit, validate, and optimize your website's meta tags for better search visibility and social sharing.
Get a 0-100 SEO score with letter grade based on title, description, OG tags, Twitter cards, and 15+ other factors.
Extract every meta tag including OG, Twitter Cards, viewport, robots, canonical, hreflang, theme-color, and more.
See exactly how your page appears in Google search, Facebook shares, and Twitter cards before you publish.
Instant visual feedback with green (good), amber (warning), and red (error) indicators for every checked element.
Prioritized, actionable suggestions to fix issues and improve your SEO with specific guidance for each problem.
Copy all tags as text or JSON. Export full reports as TXT or HTML files for documentation and team sharing.
Analyze live URLs via CORS proxy or paste raw HTML directly. Works with any web page, even behind authentication.
Auto-saves your last 5 analyses with scores. Revisit previous results instantly without re-analyzing.
All processing happens in your browser. No data is sent to any server except the URL being fetched for analysis.
URL: ${escapeHtml(d.url || 'N/A')}
`; html += `Date: ${new Date().toLocaleString()}
`; html += `Score: ${score}/100 (${grade.grade})
`; html += `No Open Graph tags found.
`; } html += `No Twitter Card tags found.
`; } html += `Generated by Tool Xeno Meta Tag Analyzer
`; html += ``; downloadFile(html, 'meta-tag-report.html', 'text/html'); showToast('Report exported as HTML', '🌐'); } /* ------------------------------------------- ACTION BUTTONS ------------------------------------------- */ $('#btn-copy').addEventListener('click', () => { if (!currentData) return; const text = getAllTagsText(); copyToClipboard(text); showToast('All meta tags copied!', '📋'); }); $('#btn-copy-json').addEventListener('click', () => { if (!currentData) return; const json = getAllTagsJson(); copyToClipboard(json); showToast('Copied as JSON!', '{ }'); }); $('#btn-export-txt').addEventListener('click', exportTxtReport); $('#btn-export-html').addEventListener('click', exportHtmlReport); $('#btn-reset').addEventListener('click', () => { currentData = null; els.urlInput.value = ''; els.htmlInput.value = ''; els.resultsSection.classList.remove('active'); els.errorSection.classList.remove('active'); els.loadingSection.classList.remove('active'); showToast('Analysis cleared', '🔄'); }); $('#btn-clear-html').addEventListener('click', () => { els.htmlInput.value = ''; els.htmlInput.focus(); }); function copyToClipboard(text) { if (navigator.clipboard) { navigator.clipboard.writeText(text).catch(() => fallbackCopy(text)); } else { fallbackCopy(text); } } function fallbackCopy(text) { const ta = document.createElement('textarea'); ta.value = text; ta.style.position = 'fixed'; ta.style.opacity = '0'; document.body.appendChild(ta); ta.select(); document.execCommand('copy'); document.body.removeChild(ta); } /* ------------------------------------------- HISTORY ------------------------------------------- */ function getHistory() { try { return JSON.parse(localStorage.getItem(STORAGE_KEY)) || []; } catch { return []; } } function saveToHistory(data, score) { let history = getHistory(); const entry = { url: data.url || 'HTML Paste', score: score, title: data.title || '', timestamp: Date.now() }; history.unshift(entry); // Remove duplicate URLs history = history.filter((h, i) => history.findIndex(x => x.url === h.url) === i); history = history.slice(0, MAX_HISTORY); localStorage.setItem(STORAGE_KEY, JSON.stringify(history)); } function renderHistory() { const history = getHistory(); if (history.length === 0) { els.historyPanel.classList.remove('active'); return; } els.historyPanel.classList.add('active'); els.historyCount.textContent = history.length; const frag = document.createDocumentFragment(); history.forEach((entry, idx) => { const item = document.createElement('div'); item.className = 'history-item'; const scoreClass = entry.score >= 80 ? 'good' : (entry.score >= 60 ? 'warn' : 'error'); const timeStr = formatTime(entry.timestamp); item.innerHTML = `