-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
99 lines (87 loc) · 3.53 KB
/
index.js
File metadata and controls
99 lines (87 loc) · 3.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import axios from 'axios';
import * as cheerio from 'cheerio';
import chalk from 'chalk';
import { program } from 'commander';
// Configure CLI
// Configura la CLI
program
.version('1.0.0')
.description('Simple SEO Analyzer Tool / Semplice Tool di Analisi SEO')
.argument('<url>', 'URL to analyze / URL da analizzare')
.action(async (url) => {
await analyzeSEO(url);
});
program.parse(process.argv);
async function analyzeSEO(targetUrl) {
// Ensure URL has protocol
if (!targetUrl.startsWith('http')) {
targetUrl = 'https://' + targetUrl;
}
console.log(chalk.cyan(`\nFetching ${targetUrl}...`));
try {
const { data } = await axios.get(targetUrl, {
headers: {
'User-Agent': 'Mozilla/5.0 (compatible; NodeSEOAnalyzer/1.0)'
}
});
const $ = cheerio.load(data);
console.log(chalk.green('Successfully fetched page.\n'));
// --- Title Analysis ---
console.log(chalk.bold('--- Title Analysis ---'));
const title = $('title').text().trim();
if (title) {
console.log(`Title: ${title}`);
console.log(`Length: ${title.length} characters`);
if (title.length >= 30 && title.length <= 60) {
console.log(chalk.green('✔ Length is optimal (30-60 chars).'));
} else {
console.log(chalk.yellow('⚠ Length could be improved (optimal: 30-60 chars).'));
}
} else {
console.log(chalk.red('✘ No title tag found!'));
}
// --- Meta Description Analysis ---
console.log(chalk.bold('\n--- Meta Description Analysis ---'));
const metaDesc = $('meta[name="description"]').attr('content');
if (metaDesc) {
console.log(`Description: ${metaDesc.trim()}`);
console.log(`Length: ${metaDesc.length} characters`);
if (metaDesc.length >= 120 && metaDesc.length <= 160) {
console.log(chalk.green('✔ Length is optimal (120-160 chars).'));
} else {
console.log(chalk.yellow('⚠ Length could be improved (optimal: 120-160 chars).'));
}
} else {
console.log(chalk.red('✘ No meta description found!'));
}
// --- Heading Analysis ---
console.log(chalk.bold('\n--- Heading Analysis ---'));
const h1Count = $('h1').length;
console.log(`Found ${h1Count} H1 tag(s).`);
if (h1Count === 1) {
console.log(chalk.green('✔ Perfect! Only one H1 tag found.'));
console.log(`Content: ${$('h1').first().text().trim()}`);
} else if (h1Count === 0) {
console.log(chalk.red('✘ No H1 tag found. This is bad for SEO.'));
} else {
console.log(chalk.yellow('⚠ Multiple H1 tags found. It is recommended to have only one main H1.'));
}
// --- Image Analysis ---
console.log(chalk.bold('\n--- Image Analysis ---'));
const images = $('img');
let missingAlt = 0;
images.each((i, img) => {
if (!$(img).attr('alt')) {
missingAlt++;
}
});
console.log(`Total Images: ${images.length}`);
if (missingAlt === 0) {
console.log(chalk.green('✔ All images have ALT attributes.'));
} else {
console.log(chalk.red(`✘ ${missingAlt} images are missing ALT attributes.`));
}
} catch (error) {
console.error(chalk.red(`Error fetching page: ${error.message}`));
}
}