@scorpion2272/seo-defect-scanner v1.1.3
SEO-defect-scanner
A npm module that let developers use this package to scan a HTML file and show all of the SEO defects.
Quick Start
npm install @scorpion2272/seo-defect-scanner
- Use the pre-defined rule 1 mentioned above
var fs = require('fs'); var seoScanner = require("@scorpion2272/SEO-defect-scanner") new seoScanner() .addPredefinedRule1() .scan('input.html') // html file to be scanned
- The console output should be like this:
There are 2 tag without alt attribute
Pre-defined Rules
There are 5 pre-defined SEO rules here:
addPredefinedRule1()
Detect if any<img/>
tag without alt attribute
new seoScanner().addPredefinedRule1()
addPredefinedRule2()
Detect if any<a />
tag without rel attribute
new seoScanner().addPredefinedRule2()
addPredefinedRule3()
Contains 3 subrules:
In <head>
tag
1. Detect if header doesn’t have <title>
tag
2. Detect if header doesn’t have <meta name=“descriptions” … />
tag
3. Detect if header doesn’t have <meta name=“keywords” … />
tag
new seoScanner().addPredefinedRule3()
addPredefinedRule4(N)
Detect if there’re more than N <strong>
tag in HTML (N is configurable)
new seoScanner().addPredefinedRule4(15) // Detect if there're more than 15 <strong> tag
addPredefinedRule5()
Detect if a HTML have more than one <H1>
tag.
new seoScanner().addPredefinedRule5()
Customized Rule
You can manage your customized rule
addRule(rule, id)
Register a rule to scanner
new seoScanner()
.addRule(CustomizedRule1, "MoreThanOneH2Tag")
Your customized rule should be implemented like this:
function CustomizedRule1($) {
if($('h2').length > 1) {
return "HTML have more than one <H2> tag";
}
}
- The input parameter $ will be passed by the scanner. It's similar to the jQuery DOM object, so you can search for the DOM element via jQuery selector syntax.
- Return a message when the defect is found.
removeRule(id)
Remove specified registered rule in scanner
new seoScanner()
.addRule(CustomizedRule1, "MoreThanOneH2Tag")
.removeRule("MoreThanOneH2Tag")
resetRule()
Clear all rules registered in scanner
new seoScanner()
.addRule(CustomizedRule1, "MoreThanOneH2Tag")
.resetRule()
Chained Rule Scanning
You can chain any pre-defined rules and customized rules to do the scan.
new seoScanner()
.addPredefinedRule1()
.addPredefinedRule4(10)
.addRule(CustomizedRule1, "MoreThanOneH2Tag")
.scan('input.html')
Configuration
When you create an instance of the scanner, you can pass a object as config:
var config = {
inputType:'file', // file (default) or stream
outputType:'console' // console (default) or file or stream
};
new seoScanner(config)
inputType: 'file' (Default)
You should pass the file path as the first parameter of scan()
new seoScanner({inputType:'file'}).scan('input.html')
inputType: 'stream'
You should pass a Node readable stream as the first parameter of scan()
var inputStream = fs.createReadStream('input.html')
new seoScanner({inputType:'stream'}).scan(inputStream)
outputType: 'console' (Default)
The scan output will be shown in the console.
new seoScanner({outputType:'console'}).scan('input.html')
outputType: 'file'
You should pass the file path as the second parameter of scan()
new seoScanner({outputType:'file'}).scan('input.html', 'output')
outputType: 'stream'
You should pass a Node writable stream as the second parameter of scan()
const outputStream = new Writable({
write(chunk, encoding, callback) {
console.log(chunk.toString())
}
});
new seoScanner({outputType:'stream'}).scan('input.html', outputStream)
Appendix
Flexibility of pre-defined rule 3:
Use a object to define the jQuery selector, condition and message when defect is scanned, so developers who want to add additional subrules can just extend the object.
this.subRules = [
{
selector: 'head title',
shouldExist: true,
message: 'Header doesn’t have <title> tag'
},
{
selector: 'head meta[name="descriptions"]',
shouldExist: true,
message: 'Header doesn’t have <meta name=“descriptions” … /> tag'
},
{
selector: 'head meta[name="keywords"]',
shouldExist: true,
message: 'Header doesn’t have <meta name=“keywords” … /> tag'
}
];
function scan($, subRules) {
var result = [];
subRules.forEach(function(subRule) {
if($(subRule.selector).length!=0 != subRule.shouldExist) {
result.push(subRule.message);
}
});
return result;
}