Professional SEO Meta Tag Generator

Create fully optimized meta tags for better search engine visibility and enhanced social media sharing

Basic Information

0 / 70 Recommended: 50-60 chars
0 / 200 Recommended: 150-160 chars

Generated Meta Tags

Copy and paste these tags inside the <head> section of your HTML document.

SEO Best Practices

  • Keep titles between 50-60 characters
  • Write descriptions between 150-160 characters
  • Use unique titles and descriptions for each page
  • Include primary keywords naturally
  • Use high-quality images (1200x630px for OG)

SEO Score & Analysis

Overall Score 0%
Title Length -
Description Length -
Open Graph -
Twitter Card -
Copied to clipboard!
\n`; } document.getElementById('generatedCode').textContent = metaTags; } updatePreviews() { const pageTitle = document.getElementById('pageTitle').value || 'Your Page Title Will Appear Here'; const metaDescription = document.getElementById('metaDescription').value || 'Your meta description will appear here. Make it compelling and informative to improve click-through rates.'; const pageUrl = document.getElementById('pageUrl').value || 'https://example.com'; const ogTitle = document.getElementById('ogTitle').value || pageTitle; const ogDescription = document.getElementById('ogDescription').value || metaDescription; const ogImage = document.getElementById('ogImage').value; const twitterTitle = document.getElementById('twitterTitle').value || pageTitle; const twitterDescription = document.getElementById('twitterDescription').value || metaDescription; const twitterImage = document.getElementById('twitterImage').value; document.getElementById('previewTitle').textContent = pageTitle; document.getElementById('previewDescription').textContent = metaDescription; document.getElementById('previewUrl').textContent = pageUrl; const domain = pageUrl.replace(/^https?:\/\//, '').replace(/\/.*$/, ''); document.getElementById('fbTitlePreview').textContent = ogTitle; document.getElementById('fbDescPreview').textContent = ogDescription; document.getElementById('fbUrlPreview').textContent = domain.toUpperCase(); const fbImagePreview = document.getElementById('fbImagePreview'); if (ogImage) { fbImagePreview.innerHTML = `Preview`; } else { fbImagePreview.innerHTML = ``; } document.getElementById('twitterTitlePreview').textContent = twitterTitle; document.getElementById('twitterDescPreview').textContent = twitterDescription; document.getElementById('twitterUrlPreview').textContent = domain; const twitterImagePreview = document.getElementById('twitterImagePreview'); if (twitterImage) { twitterImagePreview.innerHTML = `Preview`; } else { twitterImagePreview.innerHTML = ``; } } calculateSEOScore() { let score = 0; let maxScore = 5; // 5 categories // Title score (0-1) const titleLength = document.getElementById('pageTitle').value.length; let titleScore = 0; if (titleLength >= 50 && titleLength <= 60) { titleScore = 1; } else if (titleLength > 0) { titleScore = 0.5; } document.getElementById('titleScore').textContent = titleScore === 1 ? '✓' : titleScore === 0.5 ? '~' : '✗'; document.getElementById('titleScore').className = `text-xs font-medium ${titleScore === 1 ? 'text-green-600' : titleScore === 0.5 ? 'text-yellow-600' : 'text-red-600'}`; score += titleScore; // Description score (0-1) const descLength = document.getElementById('metaDescription').value.length; let descScore = 0; if (descLength >= 150 && descLength <= 160) { descScore = 1; } else if (descLength > 0) { descScore = 0.5; } document.getElementById('descScore').textContent = descScore === 1 ? '✓' : descScore === 0.5 ? '~' : '✗'; document.getElementById('descScore').className = `text-xs font-medium ${descScore === 1 ? 'text-green-600' : descScore === 0.5 ? 'text-yellow-600' : 'text-red-600'}`; score += descScore; // Open Graph score (0-1) const ogTitle = document.getElementById('ogTitle').value; const ogDescription = document.getElementById('ogDescription').value; let ogScore = 0; if (ogTitle && ogDescription) { ogScore = 1; } else if (ogTitle || ogDescription) { ogScore = 0.5; } document.getElementById('ogScore').textContent = ogScore === 1 ? '✓' : ogScore === 0.5 ? '~' : '✗'; document.getElementById('ogScore').className = `text-xs font-medium ${ogScore === 1 ? 'text-green-600' : ogScore === 0.5 ? 'text-yellow-600' : 'text-red-600'}`; score += ogScore; // Twitter score (0-1) const twitterTitle = document.getElementById('twitterTitle').value; const twitterDescription = document.getElementById('twitterDescription').value; let twitterScore = 0; if (twitterTitle && twitterDescription) { twitterScore = 1; } else if (twitterTitle || twitterDescription) { twitterScore = 0.5; } document.getElementById('twitterScore').textContent = twitterScore === 1 ? '✓' : twitterScore === 0.5 ? '~' : '✗'; document.getElementById('twitterScore').className = `text-xs font-medium ${twitterScore === 1 ? 'text-green-600' : twitterScore === 0.5 ? 'text-yellow-600' : 'text-red-600'}`; score += twitterScore; // URL score (0-1) const pageUrl = document.getElementById('pageUrl').value; let urlScore = 0; if (pageUrl && pageUrl.startsWith('http')) { urlScore = 1; } score += urlScore; // Calculate percentage const percentage = Math.round((score / maxScore) * 100); document.getElementById('seoScore').textContent = `${percentage}%`; document.getElementById('seoProgress').style.width = `${percentage}%`; // Update progress bar color based on score if (percentage >= 80) { document.getElementById('seoProgress').style.backgroundColor = '#10b981'; } else if (percentage >= 60) { document.getElementById('seoProgress').style.backgroundColor = '#f59e0b'; } else { document.getElementById('seoProgress').style.backgroundColor = '#ef4444'; } } escapeHtml(text) { const map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''', }; return text.replace(/[&<>"']/g, (m) => map[m]); } async copyToClipboard() { const code = document.getElementById('generatedCode').textContent; const copyBtn = document.getElementById('copyText'); try { await navigator.clipboard.writeText(code); this.showNotification('Meta tags copied to clipboard!', 'success'); copyBtn.innerHTML = ' Copied!'; setTimeout(() => { copyBtn.innerHTML = 'Copy'; }, 2000); } catch (err) { console.error('Failed to copy:', err); this.showNotification('Failed to copy to clipboard', 'error'); } } showNotification(message, type = 'success') { const notification = document.getElementById('notification'); const notificationText = document.getElementById('notificationText'); notificationText.textContent = message; notification.className = `notification ${type}`; notification.classList.add('show'); setTimeout(() => { notification.classList.remove('show'); }, 3000); } toggleDarkMode() { this.isDarkMode = !this.isDarkMode; document.body.classList.toggle('dark-mode', this.isDarkMode); const icon = document.querySelector('#darkModeToggle i'); if (this.isDarkMode) { icon.className = 'fas fa-sun'; this.showNotification('Dark mode enabled', 'success'); } else { icon.className = 'fas fa-moon'; this.showNotification('Light mode enabled', 'success'); } localStorage.setItem('seoDarkMode', this.isDarkMode); } resetForm() { if (confirm('Are you sure you want to reset all fields? This cannot be undone.')) { document.getElementById('pageTitle').value = ''; document.getElementById('metaDescription').value = ''; document.getElementById('keywords').value = ''; document.getElementById('pageUrl').value = ''; document.getElementById('author').value = ''; document.getElementById('ogTitle').value = ''; document.getElementById('ogDescription').value = ''; document.getElementById('ogImage').value = ''; document.getElementById('ogType').value = 'website'; document.getElementById('twitterCard').value = 'summary'; document.getElementById('twitterTitle').value = ''; document.getElementById('twitterDescription').value = ''; document.getElementById('twitterImage').value = ''; document.getElementById('twitterSite').value = ''; document.getElementById('robots').value = 'index, follow'; document.getElementById('canonical').value = ''; document.getElementById('language').value = 'en-US'; document.getElementById('schemaType').value = 'none'; document.getElementById('publishedDate').value = ''; document.getElementById('modifiedDate').value = ''; document.getElementById('authorName').value = ''; document.getElementById('schemaFields').classList.add('hidden'); this.generateMetaTags(); this.updatePreviews(); this.updateCharCount('pageTitle', 'titleCount', [50, 60]); this.updateCharCount('metaDescription', 'descCount', [150, 160]); this.calculateSEOScore(); this.saveToLocalStorage(); this.showNotification('Form reset successfully', 'success'); } } saveToLocalStorage() { const formData = {}; const inputIds = [ 'pageTitle', 'metaDescription', 'keywords', 'pageUrl', 'author', 'ogTitle', 'ogDescription', 'ogImage', 'ogType', 'twitterCard', 'twitterTitle', 'twitterDescription', 'twitterImage', 'twitterSite', 'robots', 'canonical', 'language', 'schemaType', 'publishedDate', 'modifiedDate', 'authorName' ]; inputIds.forEach(id => { const element = document.getElementById(id); if (element) { formData[id] = element.value; } }); localStorage.setItem('seoMetaGeneratorData', JSON.stringify(formData)); } loadFromLocalStorage() { const savedData = localStorage.getItem('seoMetaGeneratorData'); if (savedData) { const formData = JSON.parse(savedData); Object.keys(formData).forEach(id => { const element = document.getElementById(id); if (element) { element.value = formData[id]; } }); // Handle schema fields visibility if (formData.schemaType && formData.schemaType !== 'none') { document.getElementById('schemaFields').classList.remove('hidden'); } this.generateMetaTags(); this.updatePreviews(); this.calculateSEOScore(); } // Load dark mode preference const darkMode = localStorage.getItem('seoDarkMode') === 'true'; if (darkMode) { this.isDarkMode = true; document.body.classList.add('dark-mode'); document.querySelector('#darkModeToggle i').className = 'fas fa-sun'; } } } // Initialize the application const seoGenerator = new SEOMetaGenerator(); // Global function for copy to clipboard (for onclick attribute) function copyToClipboard() { seoGenerator.copyToClipboard(); } // Show scroll to top button when scrolling window.addEventListener('scroll', () => { const scrollButton = document.getElementById('scrollToTop'); if (window.scrollY > 300) { scrollButton.style.display = 'flex'; } else { scrollButton.style.display = 'none'; } });