![]() |
| A vibrant, modern image showing five men in a meeting room, their backs to the viewer, gathered around a large monitor displaying lines of code and data graphs. |
@import url(‘https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap’);
body {
font-family: ‘Inter’, sans-serif;
background-color: transparent;
}
.container {
width: 100%;
max-width: 768px;
margin: auto;
border-radius: 1.5rem;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
padding: 2rem;
background-color: #fff;
color: #1a202c;
}
.score-box {
background-color: #f7fafc;
border: 1px solid #e2e8f0;
border-radius: 0.75rem;
padding: 1rem;
}
.score-gauge {
width: 100%;
height: 12px;
background-color: #e2e8f0;
border-radius: 9999px;
overflow: hidden;
}
.score-fill {
height: 100%;
transition: width 0.5s ease-in-out;
background-color: #48bb78; /* Green */
}
.score-fill.low { background-color: #fc8181; } /* Red */
.score-fill.medium { background-color: #f6ad55; } /* Yellow */
.loading-spinner {
border: 4px solid #f3f3f3;
border-top: 4px solid #3498db;
border-radius: 50%;
width: 24px;
height: 24px;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
AI + SEO Post Analyzer
Enter your blog post to get a simple analysis of its AI likelihood and SEO health.
document.addEventListener(‘DOMContentLoaded’, () => {
const contentTextarea = document.getElementById(‘blog-post-content’);
const keywordInput = document.getElementById(‘focus-keyword’);
const analyzeButton = document.getElementById(‘analyze-button’);
const resultsContainer = document.getElementById(‘results-container’);
const loadingIndicator = document.getElementById(‘loading-indicator’);
const messageBox = document.getElementById(‘message-box’);
const overallScoreDisplay = document.getElementById(‘overall-score-display’);
const overallScoreGauge = document.getElementById(‘overall-score-gauge’);
const overallScoreMessage = document.getElementById(‘overall-score-message’);
const aiScoreDisplay = document.getElementById(‘ai-score-display’);
const aiScoreGauge = document.getElementById(‘ai-score-gauge’);
const aiScoreMessage = document.getElementById(‘ai-score-message’);
const keywordDensityEl = document.getElementById(‘keyword-density’);
const wordCountEl = document.getElementById(‘word-count’);
const headingCountEl = document.getElementById(‘heading-count’);
const readabilityGradeEl = document.getElementById(‘readability-grade’);
const keywordDensityMessage = document.getElementById(‘keyword-density-message’);
const wordCountMessage = document.getElementById(‘word-count-message’);
const headingCountMessage = document.getElementById(‘heading-count-message’);
const readabilityMessage = document.getElementById(‘readability-message’);
analyzeButton.addEventListener(‘click’, () => {
const content = contentTextarea.value;
const keyword = keywordInput.value.trim().toLowerCase();
messageBox.classList.add(‘hidden’);
resultsContainer.classList.add(‘hidden’);
loadingIndicator.classList.remove(‘hidden’);
if (!content || !keyword) {
messageBox.textContent = ‘Please enter both your blog post content and a focus keyword.’;
messageBox.classList.remove(‘hidden’);
loadingIndicator.classList.add(‘hidden’);
return;
}
// Simulate a brief delay to show the loading indicator
setTimeout(() => {
const seoResults = analyzeSEO(content, keyword);
const aiResults = analyzeAILikelihood(content);
displayResults(seoResults, aiResults);
loadingIndicator.classList.add(‘hidden’);
resultsContainer.classList.remove(‘hidden’);
}, 1000);
});
// Helper function to count syllables in a word (simplified heuristic)
const countSyllables = (word) => {
word = word.toLowerCase().replace(/[^a-z]/g, “”);
if (word.length === 0) return 0;
let syllableCount = 0;
let isVowel = (char) => “aeiouy”.includes(char);
if (isVowel(word[0])) {
syllableCount++;
}
for (let i = 1; i text.trim().split(/s+/).filter(word => word.length > 0).length;
const countSentences = (text) => text.split(/[.!?]+/).filter(sentence => sentence.length > 0).length;
// Flesch-Kincaid Readability Formula
const calculateReadability = (text) => {
const words = text.trim().split(/s+/).filter(word => word.length > 0);
const sentences = text.split(/[.!?]+/).filter(sentence => sentence.length > 0);
const wordCount = words.length;
const sentenceCount = sentences.length;
let totalSyllables = 0;
words.forEach(word => {
totalSyllables += countSyllables(word);
});
if (wordCount === 0 || sentenceCount === 0) return { grade: 0, message: ‘Not enough content to analyze readability.’ };
const grade = 0.39 * (wordCount / sentenceCount) + 11.8 * (totalSyllables / wordCount) – 15.59;
let message = “”;
if (grade < 5) message = "Very easy to read, suitable for a young audience.";
else if (grade < 8) message = "Easy to read, suitable for most audiences.";
else if (grade < 12) message = "Fairly easy to read, good for a general audience.";
else if (grade {
const wordList = content.toLowerCase().split(/W+/).filter(word => word.length > 0);
const wordCount = wordList.length;
const keywordCount = wordList.filter(word => word === keyword.toLowerCase()).length;
const keywordDensity = wordCount > 0 ? (keywordCount / wordCount) * 100 : 0;
const tempDiv = document.createElement(‘div’);
tempDiv.innerHTML = content;
const headingTags = [‘h1’, ‘h2’, ‘h3’, ‘h4’, ‘h5’, ‘h6’];
let headingCount = 0;
headingTags.forEach(tag => {
headingCount += tempDiv.getElementsByTagName(tag).length;
});
const readability = calculateReadability(content);
return {
keywordDensity,
wordCount,
headingCount,
readability
};
};
// Analyze AI likelihood based on simple heuristics
const analyzeAILikelihood = (content) => {
const words = content.toLowerCase().split(/W+/).filter(word => word.length > 0);
const sentences = content.split(/[.!?]+/).filter(sentence => sentence.length > 0);
const wordCount = words.length;
const sentenceCount = sentences.length;
if (wordCount === 0 || sentenceCount < 5) return { score: 0, message: 'Not enough content for AI analysis.' };
let score = 0;
const maxScore = 100;
// Heuristic 1: Lack of word variation
const uniqueWords = new Set(words).size;
const wordVarietyRatio = uniqueWords / wordCount;
if (wordVarietyRatio < 0.35) score += 20;
else if (wordVarietyRatio s.trim().split(/s+/).filter(w => w.length > 0).length);
const avgLength = sentenceLengths.reduce((a, b) => a + b, 0) / sentenceLengths.length;
const stDev = Math.sqrt(sentenceLengths.map(len => Math.pow(len – avgLength, 2)).reduce((a, b) => a + b, 0) / sentenceLengths.length);
if (stDev personalPronouns.includes(word)).length;
if ((pronounCount / wordCount) content.toLowerCase().includes(phrase)).length;
score += phraseCount * 5;
const finalScore = Math.min(score, maxScore);
let message = “”;
if (finalScore < 20) message = "Looks very human-like. Keep up the great work!";
else if (finalScore {
// Overall Score (blend of SEO and AI, subjective)
const readabilityWeight = Math.min(1, Math.max(0, (seo.readability.grade – 8) / -8 + 1));
const seoScore = (Math.min(1, seo.keywordDensity / 2.5) * 50) + (Math.min(1, seo.headingCount / 3) * 20) + (readabilityWeight * 30);
const aiInfluence = ai.score * 0.5; // AI score negatively impacts overall score
const overallScore = Math.max(0, seoScore – aiInfluence);
overallScoreDisplay.textContent = `${overallScore.toFixed(0)}%`;
overallScoreGauge.style.width = `${overallScore.toFixed(0)}%`;
if (overallScore < 40) {
overallScoreGauge.className = 'h-full transition-all duration-500 ease-out bg-red-500';
overallScoreMessage.textContent = "Your post needs significant improvement for SEO and originality.";
} else if (overallScore < 70) {
overallScoreGauge.className = 'h-full transition-all duration-500 ease-out bg-yellow-500';
overallScoreMessage.textContent = "Your post is on the right track, but has room for improvement.";
} else {
overallScoreGauge.className = 'h-full transition-all duration-500 ease-out bg-green-500';
overallScoreMessage.textContent = "Great job! Your post is well-optimized and original.";
}
// AI Likelihood
aiScoreDisplay.textContent = `${ai.score.toFixed(0)}%`;
aiScoreGauge.style.width = `${ai.score.toFixed(0)}%`;
if (ai.score < 20) {
aiScoreGauge.className = 'h-full transition-all duration-500 ease-out bg-green-500';
} else if (ai.score < 50) {
aiScoreGauge.className = 'h-full transition-all duration-500 ease-out bg-yellow-500';
} else {
aiScoreGauge.className = 'h-full transition-all duration-500 ease-out bg-red-500';
}
aiScoreMessage.textContent = ai.message;
// SEO Metrics
keywordDensityEl.textContent = `${seo.keywordDensity.toFixed(2)}%`;
if (seo.keywordDensity 3) {
keywordDensityMessage.textContent = ‘Ideal density is 1-3%. Adjust for better ranking.’;
keywordDensityMessage.classList.add(‘text-red-600’);
keywordDensityMessage.classList.remove(‘text-gray-600’);
} else {
keywordDensityMessage.textContent = ‘Looks good! Your keyword density is in the sweet spot.’;
keywordDensityMessage.classList.add(‘text-green-600’);
keywordDensityMessage.classList.remove(‘text-gray-600’);
}
wordCountEl.textContent = seo.wordCount;
if (seo.wordCount < 300) {
wordCountMessage.textContent = 'Aim for at least 300 words for better SEO. Longer is often better.';
wordCountMessage.classList.add('text-red-600');
wordCountMessage.classList.remove('text-gray-600');
} else {
wordCountMessage.textContent = 'Excellent word count for a blog post!';
wordCountMessage.classList.add('text-green-600');
wordCountMessage.classList.remove('text-gray-600');
}
headingCountEl.textContent = seo.headingCount;
if (seo.headingCount < 1) {
headingCountMessage.textContent = 'Add at least one H1, and H2/H3 for structure.';
headingCountMessage.classList.add('text-red-600');
headingCountMessage.classList.remove('text-gray-600');
} else {
headingCountMessage.textContent = 'Good use of headings for readability and SEO.';
headingCountMessage.classList.add('text-green-600');
headingCountMessage.classList.remove('text-gray-600');
}
readabilityGradeEl.textContent = seo.readability.grade;
readabilityMessage.textContent = seo.readability.message;
};
});
This tool is designed to analyses a few key metrics for both SEO and AI-like patterns and provides a summary score.


