{
if (style) {
console.log(`%c${text}`, style);
} else {
console.log(text);
}
};
// Divider
console.log('%c═══════════════════════════════════════════', styles.divider);
console.log('%c🔍 PAGE SEO ANALYSIS', styles.section);
console.log('%c═══════════════════════════════════════════\n', styles.divider);
// 1. TITLE ANALYSIS
console.log('%cTITLE', styles.title);
const pageTitle = document.title;
const titleLength = pageTitle.length;
const googleTitleMax = 60;
const googleTitleMin = 30;
console.log(`%c${pageTitle}`, styles.info);
if (titleLength === 0) {
console.log('%c❌ ERROR: Title is empty!', styles.error);
} else if (titleLength > googleTitleMax) {
console.log(`%c⚠️️ WARNING: Title might be cropped. ${titleLength}/${googleTitleMax} characters.`, styles.warning);
} else if (titleLength < googleTitleMin) {
console.log(`%c⚠️️ WARNING: Title is short. ${titleLength}/${googleTitleMin} characters.`, styles.warning);
} else {
console.log(`%c✅ Length: ${titleLength}/${googleTitleMax} characters.`, styles.success);
}
console.log('\n');
// 2. META DESCRIPTION ANALYSIS
console.log('%cDESCRIPTION', styles.title);
const metaDescription = document.querySelector('meta[name="description"]');
const googleDescMax = 160;
const googleDescMin = 30;
if (metaDescription) {
const descText = metaDescription.getAttribute('content') || '';
const descLength = descText.length;
console.log(`%c${descText}`, styles.info);
if (descLength === 0) {
console.log('%c❌ ERROR: Meta description is empty!', styles.error);
} else if (descLength > googleDescMax) {
console.log(`%c⚠️️ WARNING: Description might be cropped. ${descLength}/${googleDescMax} characters.`, styles.warning);
} else if (descLength < googleDescMin) {
console.log(`%c⚠️️ WARNING: Description is short. ${descLength}/${googleDescMin} characters.`, styles.warning);
} else {
console.log(`%c✅ Length: ${descLength}/${googleDescMax} characters.`, styles.success);
}
} else {
console.log('%c❌ ERROR: No meta description found on the page!', styles.error);
}
console.log('\n');
// 3. H1 TAGS ANALYSIS
console.log('%cH1 TAGS', styles.title);
const h1Tags = document.querySelectorAll('h1');
const h1Count = h1Tags.length;
// console.log(`%cFound: ${h1Count} H1 tag${h1Count !== 1 ? 's' : ''}`, styles.highlight);
if (h1Count === 0) {
console.log('%c❌ ERROR: No H1 tag found on the page', styles.error);
} else if (h1Count > 1) {
console.log('%c❌ ERROR: More than 1 H1 tag detected (Google recommends only one H1 per page)', styles.error);
console.log('%cH1 tags:', styles.info);
h1Tags.forEach((h1, index) => {
const h1Text = h1.textContent.trim();
const h1Length = h1Text.length;
console.log(`%c ${index + 1}. "${h1Text}" ${h1.offsetParent ? '' : '(⚠️ Not visible)'}`, styles.info);
});
} else {
const h1Text = h1Tags[0].textContent.trim();
const h1Length = h1Text.length;
console.log(`%c${h1Text}`, styles.info);
}
console.log('\n');
// 4. H2 TAGS ANALYSIS
console.log('%cH2 TAGS', styles.title);
const h2Tags = document.querySelectorAll('h2');
const h2Count = h2Tags.length;
// console.log(`%cFound: ${h2Count} H2 tag${h2Count !== 1 ? 's' : ''}`, styles.highlight);
if (h2Count === 0) {
console.log('%cNo H2 tags found on the page', styles.warning);
} else if (h2Count >= 1) {
console.log('%cH2 tags:', styles.info);
const maxH2ToShow = 25;
for (let index = 0; index < h2Tags.length; index++) {
if (index >= maxH2ToShow) {
console.log('%cStopped at 25 H2 tags', styles.warning);
break;
}
const h2 = h2Tags[index];
const h2Text = h2.textContent.trim();
console.log(`%c ${index + 1}. "${h2Text}" ${h2.offsetParent ? '' : '(⚠️ Not visible)'}`, styles.info);
}
}
console.log('\n');
// 4. SUMMARY
console.log('%cSUMMARY', styles.title);
let summary = [];
// Title check
if (titleLength > 0 && titleLength <= googleTitleMax && titleLength >= googleTitleMin) {
summary.push('%c✅ Title: Optimal length');
} else if (titleLength > googleTitleMax) {
summary.push('%c⚠️ Title: Will be cropped');
} else if (titleLength < googleTitleMin) {
summary.push('%c⚠️ Title: Short');
} else {
summary.push('%c❌ Title: Missing');
}
// Description check
if (metaDescription) {
const descText = metaDescription.getAttribute('content') || '';
if (descText.length > 0 && descText.length <= googleDescMax && descText.length >= googleDescMin) {
summary.push('%c✅ Description: Optimal length');
} else if (descText.length > googleDescMax) {
summary.push('%c⚠️ Description: Will be cropped');
} else if (descText.length < googleDescMin) {
summary.push('%c⚠️ Description: Short');
} else {
summary.push('%c❌ Description: Missing');
}
} else {
summary.push('%c❌ Description: Missing');
}
// H1 check
if (h1Count === 1) {
summary.push('%c✅ H1: Exactly one found');
} else {
summary.push(`%c${h1Count === 0 ? '❌' : '⚠️'} H1: ${h1Count === 0 ? 'Missing' : 'Multiple'}`);
}
// H2 check
if (h2Count >= 1) {
summary.push(`%c✅ H2: ${h2Count} found`);
} else {
summary.push(`%c⚠️ H2: Not found`);
}
// Display summary
summary.forEach((item, index) => {
const style = item.includes('✅') ? styles.success :
item.includes('⚠️') ? styles.warning :
item.includes('❌') ? styles.error : styles.info;
console.log(item, style);
});
console.log('\n');
// Check for important SEO meta tags
console.log('%cSEO META TAGS CHECK', styles.title);
// 1. Robots meta tags
const robotsMeta = document.querySelector('meta[name="robots"]');
const googlebotMeta = document.querySelector('meta[name="googlebot"]');
if (robotsMeta) {
const robotsContent = robotsMeta.getAttribute('content') || '';
console.log(`%c🤖 Robots: ${robotsContent}`, 'font-weight: bold; margin-left: 6px;');
if (robotsContent.includes('noindex')) {
console.log('%c❌ CRITICAL: Page is set to NOINDEX (will not appear in search results)', styles.error);
} else {
console.log('%c✅ Good: Page is indexable', styles.success);
}
if (robotsContent.includes('nofollow')) {
console.log('%c⚠️️ Links on this page will not be followed by search engines', styles.warning);
}
} else if (googlebotMeta) {
const googlebotContent = googlebotMeta.getAttribute('content') || '';
console.log(`%c🤖 Googlebot: ${googlebotContent}`, 'font-weight: bold; margin-left: 6px;');
} else {
console.log('%c✅ No robots restrictions found (page is indexable)', styles.success);
}
// 3. Viewport tag (mobile SEO)
const viewportMeta = document.querySelector('meta[name="viewport"]');
if (viewportMeta) {
const viewportContent = viewportMeta.getAttribute('content') || '';
if (viewportContent.includes('width=device-width') && viewportContent.includes('initial-scale=1')) {
console.groupCollapsed('%c✅ Good: Proper viewport for mobile', styles.success + 'margin-left: 0px;');
} else {
console.groupCollapsed('%c⚠️️ Viewport may not be optimal for mobile', styles.warning + 'margin-left: 0px;');
}
console.log(`%cViewport: ${viewportContent}`, 'color: #1a73e8;');
console.groupEnd();
} else {
console.log('%c❌ ERROR: No viewport meta tag (critical for mobile SEO)', styles.error);
}
// 4. Charset meta tag
const charsetMeta = document.querySelector('meta[charset]') || document.querySelector('meta[http-equiv="Content-Type"]');
if (charsetMeta) {
const charset = charsetMeta.getAttribute('charset') || charsetMeta.getAttribute('content')?.split('charset=')[1];
if (charset?.toLowerCase() === 'utf-8') {
console.log('%c✅ Good: UTF-8 charset', styles.success);
}
} else {
console.log('%c⚠️️ No charset specified', styles.warning);
}
// 2. Canonical URL
const canonicalLink = document.querySelector('link[rel="canonical"]');
if (canonicalLink) {
const canonicalUrl = canonicalLink.getAttribute('href');
// console.log(`%c🔗 Canonical URL: ${canonicalUrl}`, 'color: #1a73e8;');
// Check if canonical matches current URL
const currentUrl = window.location.href.split('#')[0];
if (canonicalUrl !== currentUrl) {
console.log(`%c⚠️️ Canonical points to different URL`, styles.warning);
console.log(`%c Current: ${currentUrl}`, 'color: #eeeeee;');
console.log(`%c Canonical: ${canonicalUrl}`, 'color: #eeeeee;');
} else {
console.log(`%c✅ Canonical matches current page`, styles.success);
}
} else {
console.log('%c⚠️️ No canonical URL specified', styles.warning);
}
// 7. Hreflang tags (multi-language)
const hreflangTags = document.querySelectorAll('link[rel="alternate"][hreflang]');
if (hreflangTags.length > 0) {
console.groupCollapsed(`%c✅ Hreflang tags: ${hreflangTags.length} found`, styles.success + 'margin-left: 0px;');
hreflangTags.forEach(tag => {
console.log(`%c • ${tag.getAttribute('hreflang')}: ${tag.getAttribute('href')}`, 'color: #eeeeee;');
});
console.groupEnd();
}
// 8. Structured Data (JSON-LD)
const jsonLdScripts = document.querySelectorAll('script[type="application/ld+json"]');
if (jsonLdScripts.length > 0) {
console.log(`%c✅ Structured Data: ${jsonLdScripts.length} JSON-LD script(s) found`, styles.success);
// Try to identify schema types
jsonLdScripts.forEach((script, index) => {
try {
const data = JSON.parse(script.textContent);
const schemaType = data['@type'] || data[0]?.['@type'] || 'Unknown';
console.log(`%c • Script ${index + 1}: ${schemaType}`, 'color: #eeeeee;');
} catch (e) {
console.log(`%c • Script ${index + 1}: Invalid JSON`, styles.warning);
}
});
} else {
console.log('%c⚠️️ No JSON-LD schema found', styles.warning);
}
// 5. Open Graph tags (social media)
const ogTitle = document.querySelector('meta[property="og:title"]');
const ogDescription = document.querySelector('meta[property="og:description"]');
const ogImage = document.querySelector('meta[property="og:image"]');
const ogUrl = document.querySelector('meta[property="og:url"]');
const ogTags = [ogTitle, ogDescription, ogImage, ogUrl].filter(tag => tag !== null);
if(ogTags.length) {
console.groupCollapsed(`%c📱 Open Graph Tags: ${ogTags.length} found`, styles.success + 'margin-left: 0px;');
if (ogTitle) console.log(`%c • og:title: "${ogTitle.getAttribute('content')}"`, 'color: #eeeeee;');
if (ogDescription) console.log(`%c • og:description: "${ogDescription.getAttribute('content')}"`, 'color: #eeeeee;');
if (ogImage) console.log(`%c • og:image: ${ogImage.getAttribute('content')}`, 'color: #eeeeee;');
console.groupEnd();
}
// 6. Twitter Cards
const twitterCard = document.querySelector('meta[name="twitter:card"]');
const twitterTitle = document.querySelector('meta[name="twitter:title"]');
const twitterDescription = document.querySelector('meta[name="twitter:description"]');
const twitterImage = document.querySelector('meta[name="twitter:image"]');
const twitterTags = [twitterCard, twitterTitle, twitterDescription, twitterImage].filter(tag => tag !== null);
if(twitterTags.length) {
console.groupCollapsed(`%c🐦 Twitter Cards: ${twitterTags.length} found`, styles.success + 'margin-left: 0px;');
if (twitterCard) console.log(`%c • twitter:card: "${twitterCard.getAttribute('content')}"`, 'color: #eeeeee;');
if (twitterTitle) console.log(`%c • twitter:title: "${twitterTitle.getAttribute('content')}"`, 'color: #eeeeee;');
if (twitterDescription) console.log(`%c • twitter:description: "${twitterDescription.getAttribute('content')}"`, 'color: #eeeeee;');
if (twitterImage) console.log(`%c • twitter:image: ${twitterImage.getAttribute('content')}`, 'color: #eeeeee;');
console.groupEnd();
}
// 9. Favicon
const favicon = document.querySelector('link[rel="icon"], link[rel="shortcut icon"]');
if (favicon) {
console.log(`%c✅ Favicon: Found`, styles.success);
} else {
console.log('%c⚠️️ No favicon found', styles.warning);
}
console.log('\n');
}
//-- End Basic SEO Analytics code --