generated from wanghaisheng/a_websim-website-starter
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
seoChecker.js
127 lines (107 loc) · 4.12 KB
/
seoChecker.js
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
const axios = require('axios');
const cheerio = require('cheerio');
const { JSDOM } = require('jsdom');
const url = require('url');
const fs = require('fs');
// List of pages to check (can be extended)
const pages = [
'https://mood-island.heytcm.com',
'https://mood-island.heytcm.com/en',
'https://mood-island.heytcm.com/fr',
'https://mood-island.heytcm.com/zh',
];
const defaultLang = 'en'; // The default language
const resultsFile = './seo-check-results.txt'; // File to save SEO check results
// Create or overwrite the results file
fs.writeFileSync(resultsFile, 'SEO Check Results:\n\n', 'utf-8');
async function checkPageSEO(pageUrl) {
try {
// Fetch HTML content
const response = await axios.get(pageUrl);
const html = response.data;
// Parse the HTML with Cheerio
const $ = cheerio.load(html);
// SEO Checks
const results = [];
results.push(`Checking SEO for: ${pageUrl}\n`);
// 1. Title Tag
const title = $('head title').text();
if (!title) {
results.push('[Warning] Missing <title> tag');
} else if (title.length < 30 || title.length > 60) {
results.push('[Suggestion] <title> should be between 30-60 characters.');
}
// 2. Meta Description
const description = $('head meta[name="description"]').attr('content');
if (!description) {
results.push('[Warning] Missing <meta name="description"> tag');
} else if (description.length < 50 || description.length > 160) {
results.push('[Suggestion] <meta name="description"> should be between 50-160 characters.');
}
// 3. H1 Tag
const h1 = $('h1').text();
if (!h1) {
results.push('[Warning] Missing <h1> tag');
} else if (h1.length < 10) {
results.push('[Suggestion] <h1> should be more descriptive, at least 10 characters.');
}
// 4. Missing or incorrect canonical tag
const canonical = $('head link[rel="canonical"]').attr('href');
if (!canonical) {
results.push('[Warning] Missing <link rel="canonical"> tag');
} else if (canonical !== pageUrl) {
results.push('[Suggestion] The <link rel="canonical"> tag should point to the correct page URL: ', pageUrl);
}
// 5. Base Tag Issues
const baseHref = $('head base').attr('href');
if (baseHref && baseHref !== '/') {
results.push('[Suggestion] <base href="/"> should be used for root-level pages to avoid relative URL issues.');
}
// 6. Broken Links (Internal Links)
const links = $('a[href]');
for (let i = 0; i < links.length; i++) {
const link = links[i];
const href = $(link).attr('href');
// Ignore external links
if (!href || href.startsWith('http') || href.startsWith('https')) continue;
// Check if internal links are valid (not broken)
const linkUrl = url.resolve(pageUrl, href);
try {
const linkResponse = await axios.head(linkUrl); // Perform a HEAD request to check if the link exists
if (linkResponse.status !== 200) {
results.push(`[Warning] Broken link found: ${linkUrl}`);
}
} catch (error) {
results.push(`[Warning] Broken link found: ${linkUrl}`);
}
}
// 7. Missing Alt Text for Images
const images = $('img');
images.each(function () {
const altText = $(this).attr('alt');
if (!altText) {
results.push('[Warning] Image missing <alt> attribute:', $(this).attr('src'));
}
});
// 8. Check Page Load Time (Basic Check)
const start = Date.now();
await axios.get(pageUrl); // Measure the time for a full page load
const loadTime = (Date.now() - start) / 1000;
if (loadTime > 3) {
results.push('[Suggestion] Page load time is too slow, consider optimizing resources. Time:', loadTime, 's');
}
results.push('\n--- End of SEO Check ---\n');
// Save the results to the file
fs.appendFileSync(resultsFile, results.join('\n'), 'utf-8');
} catch (error) {
console.error(`[Error] Unable to fetch or check page: ${pageUrl}`);
}
}
// Run SEO checks for all pages
async function checkAllPages() {
for (const page of pages) {
await checkPageSEO(page);
}
}
// Run the script
checkAllPages();