/** * E-E-A-T Analyzer Plugin for LibreCrawl * Analyzes Experience, Expertise, Authoritativeness, Trust signals on crawled pages * * @author LibreCrawl Community * @version 1.0.0 */ LibreCrawlPlugin.register({ // Plugin metadata id: 'e-e-a-t', name: 'E-E-A-T Analyzer', version: '1.0.0', author: 'LibreCrawl Community', description: 'Analyzes Experience, Expertise, Authoritativeness, Trust (E-E-A-T) signals on your website', // Tab configuration tab: { label: 'E-E-A-T', icon: '🎓', position: 'end' // Appears after all built-in tabs }, // Plugin initialization onLoad() { console.log('📊 E-E-A-T Analyzer loaded'); }, // Called when tab becomes active onTabActivate(container, data) { console.log('🎓 E-E-A-T tab activated with', data.urls.length, 'URLs'); this.render(container, data); }, // Called during live crawls when data updates onDataUpdate(data) { if (this.isActive && this.container) { this.render(this.container, data); } }, // Called when crawl completes onCrawlComplete(data) { console.log('✅ E-E-A-T analysis complete for', data.urls.length, 'URLs'); if (this.isActive && this.container) { this.render(this.container, data); } }, // Main render function render(container, data) { const { urls, links } = data; if (!urls || urls.length === 0) { container.innerHTML = this.renderEmptyState(); return; } // Analyze E-E-A-T signals const analysis = this.analyzeEEAT(urls, links); // Render the analysis container.innerHTML = `
${this.renderHeader(analysis)} ${this.renderScoreCards(analysis)} ${this.renderSignalsBreakdown(analysis)} ${this.renderTopPages(analysis)} ${this.renderRecommendations(analysis)}
`; }, // Render header section renderHeader(analysis) { return `

🎓 E-E-A-T Analysis

Experience, Expertise, Authoritativeness, and Trust signals across your website

`; }, // Render score cards renderScoreCards(analysis) { const scoreClass = this.getScoreClass(analysis.overallScore); const scoreColor = this.getScoreColor(analysis.overallScore); return `
Overall E-E-A-T Score
${analysis.overallScore}
Out of 100
Pages with Author Info
${analysis.pagesWithAuthor}
${this.getPercentage(analysis.pagesWithAuthor, analysis.totalPages)}% of pages
Pages with Schema Markup
${analysis.pagesWithSchema}
${this.getPercentage(analysis.pagesWithSchema, analysis.totalPages)}% of pages
External Citations
${analysis.externalCitations}
Average ${analysis.avgExternalLinks.toFixed(1)} per page
`; }, // Render signals breakdown renderSignalsBreakdown(analysis) { return `

Trust Signals Breakdown

${this.renderSignalItem('✍️', 'Author Attribution', analysis.pagesWithAuthor, analysis.totalPages)} ${this.renderSignalItem('📊', 'Structured Data', analysis.pagesWithSchema, analysis.totalPages)} ${this.renderSignalItem('🔗', 'External Links', analysis.pagesWithExternalLinks, analysis.totalPages)} ${this.renderSignalItem('🏷️', 'Open Graph Tags', analysis.pagesWithOGTags, analysis.totalPages)} ${this.renderSignalItem('🔒', 'HTTPS Secure', analysis.securePages, analysis.totalPages)} ${this.renderSignalItem('📝', 'Sufficient Content', analysis.pagesWithGoodContent, analysis.totalPages)}
`; }, // Render individual signal item renderSignalItem(icon, label, count, total) { const percentage = this.getPercentage(count, total); const barColor = percentage >= 75 ? '#10b981' : percentage >= 50 ? '#f59e0b' : '#ef4444'; return `
${icon}
${label}
${count}/${total}
${percentage}%
`; }, // Render top pages by E-E-A-T score renderTopPages(analysis) { return `

Top Pages by E-E-A-T Score

${analysis.topPages.slice(0, 10).map(page => this.renderPageRow(page)).join('')}
URL Score Author Schema Ext. Links
`; }, // Render individual page row renderPageRow(page) { const scoreColor = this.getScoreColor(page.score); return ` ${this.utils.escapeHtml(page.url)} ${page.score} ${page.hasAuthor ? '✅' : '❌'} ${page.hasSchema ? '✅' : '❌'} ${page.externalLinks} `; }, // Render recommendations renderRecommendations(analysis) { const recommendations = this.generateRecommendations(analysis); return `

💡 Recommendations to Improve E-E-A-T

${recommendations.map(rec => this.renderRecommendation(rec)).join('')}
`; }, // Render individual recommendation renderRecommendation(rec) { const priorityColors = { high: '#ef4444', medium: '#f59e0b', low: '#3b82f6' }; return `
${rec.icon}
${rec.title}
${rec.description}
${rec.priority}
`; }, // Empty state renderEmptyState() { return `
🎓

No Data Yet

Start crawling to analyze E-E-A-T signals on your website

`; }, // Analyze E-E-A-T signals across all URLs analyzeEEAT(urls, links) { let totalScore = 0; let pagesWithAuthor = 0; let pagesWithSchema = 0; let pagesWithExternalLinks = 0; let pagesWithOGTags = 0; let securePages = 0; let pagesWithGoodContent = 0; let externalCitations = 0; const pageScores = []; urls.forEach(url => { let score = 0; const urlData = { url: url.url, score: 0, hasAuthor: false, hasSchema: false, externalLinks: url.external_links || 0 }; // Check for HTTPS (10 points) if (url.url && url.url.startsWith('https://')) { score += 10; securePages++; } // Check for author information (20 points) if (url.meta_author || (url.og_tags && url.og_tags.author)) { score += 20; pagesWithAuthor++; urlData.hasAuthor = true; } // Check for structured data/schema markup (25 points) if (url.json_ld && url.json_ld.length > 0) { score += 25; pagesWithSchema++; urlData.hasSchema = true; } // Check for external links/citations (15 points) const extLinks = url.external_links || 0; if (extLinks > 0) { score += Math.min(15, extLinks * 3); // Up to 15 points pagesWithExternalLinks++; externalCitations += extLinks; } // Check for Open Graph tags (10 points) if (url.og_tags && url.og_tags.title) { score += 10; pagesWithOGTags++; } // Check for sufficient content (20 points) const wordCount = url.word_count || 0; if (wordCount >= 300) { score += 20; pagesWithGoodContent++; } else if (wordCount >= 150) { score += 10; } urlData.score = Math.min(100, score); totalScore += urlData.score; pageScores.push(urlData); }); // Sort pages by score pageScores.sort((a, b) => b.score - a.score); return { totalPages: urls.length, overallScore: urls.length > 0 ? Math.round(totalScore / urls.length) : 0, pagesWithAuthor, pagesWithSchema, pagesWithExternalLinks, pagesWithOGTags, securePages, pagesWithGoodContent, externalCitations, avgExternalLinks: urls.length > 0 ? externalCitations / urls.length : 0, topPages: pageScores }; }, // Generate recommendations based on analysis generateRecommendations(analysis) { const recommendations = []; const total = analysis.totalPages; // Author attribution if (analysis.pagesWithAuthor < total * 0.5) { recommendations.push({ icon: '✍️', title: 'Add Author Information', description: `Only ${analysis.pagesWithAuthor} out of ${total} pages have author information. Add author bylines with credentials to demonstrate expertise.`, priority: 'high' }); } // Schema markup if (analysis.pagesWithSchema < total * 0.3) { recommendations.push({ icon: '📊', title: 'Implement Structured Data', description: `${analysis.pagesWithSchema} pages have schema markup. Add JSON-LD structured data (Article, Person, Organization schemas) to improve E-E-A-T.`, priority: 'high' }); } // External citations if (analysis.avgExternalLinks < 2) { recommendations.push({ icon: '🔗', title: 'Add External Citations', description: `Average of ${analysis.avgExternalLinks.toFixed(1)} external links per page. Link to authoritative sources to support your claims and demonstrate research.`, priority: 'medium' }); } // Content depth if (analysis.pagesWithGoodContent < total * 0.7) { recommendations.push({ icon: '📝', title: 'Improve Content Depth', description: `${analysis.pagesWithGoodContent} pages have sufficient content (300+ words). Create comprehensive, in-depth content to demonstrate expertise.`, priority: 'medium' }); } // HTTPS if (analysis.securePages < total) { recommendations.push({ icon: '🔒', title: 'Enable HTTPS Everywhere', description: `${total - analysis.securePages} pages are not using HTTPS. Ensure all pages use HTTPS for trust and security.`, priority: 'high' }); } // If no recommendations, add a positive message if (recommendations.length === 0) { recommendations.push({ icon: '🎉', title: 'Great E-E-A-T Signals!', description: 'Your website demonstrates strong Experience, Expertise, Authoritativeness, and Trust signals. Keep up the good work!', priority: 'low' }); } return recommendations; }, // Helper: Get score class getScoreClass(score) { if (score >= 80) return 'score-good'; if (score >= 60) return 'score-needs-improvement'; return 'score-poor'; }, // Helper: Get score color getScoreColor(score) { if (score >= 80) return '#10b981'; if (score >= 60) return '#f59e0b'; return '#ef4444'; }, // Helper: Get percentage getPercentage(count, total) { return total > 0 ? Math.round((count / total) * 100) : 0; } }); console.log('✅ E-E-A-T Analyzer plugin registered');