SEO_Sniffer
Develop a Node.js package to let user can use this package to scan a HTML file and show all of the SEO defects.
Features
Implement following 5 pre-defined SEO rules for this package
- Detect if any
<img />
tag without alt attribute - Detect if any
<a />
tag without rel attribute - In
<head>
tag - Detect if header doesn’t have
<title>
tag - Detect if header doesn’t have
<meta name=“descriptions” ... />
tag - Detect if header doesn’t have
<meta name=“keywords” ... />
tag - Detect if there’re more than 15
<strong>
tag in HTML (15 is a value should be configurable by user) - Detect if a HTML have more than one
<H1>
tag.
Development Requirement
- User is free to chain any rules by themselves
- For example, they can only use the rule 1 and 4 or only use rule 2.
- The order of rules is doesn’t matter
- User can define and use their own rules easily
- The input can be:
- A HTML file (User is able to config the input path)
- Node Readable Stream
- The output can be:
- A file (User is able to config the output destination)
- Node Writable Stream
- Console
- Package should be flexible:
- When you want to implement additional rules for
<meta>
tag, The code changes should be small. Ex: Checking<meta name=“robots” />
existing or not?!
Prerequisites
Developing by the Node.js 11.5
Installation
npm install seo_sniffer
Initializing Input/Output
By Constructor
const sniffer = input: 'PathToFile' // 'PathToFile' or fs.ReadStream output: 'PathToFile' // 'PathToFile' or fs.WriteStream or 'console'
By setInput()/setOutput()
const sniffer = sniffer// 'PathToFile' or fs.ReadStream sniffer// 'PathToFile' or fs.WriteStream or 'console'
Check Methods & Export Reports
hasTagWithoutAttr()
Export Tag/Attribute:
`Has ${diff} ${tag} tag without ${attribute}.`
`No found any ${tag} tag without ${attribute}.`
Export Tag/Attribute/Value:
`Has ${diff} ${tag} tag without ${attribute}="${value}".`
`No found any ${tag} tag without ${attribute}="${value}".`
isTagNotExist()
Export Tag:
`Not find any match on the ${tag}!!`
`Find matches on the ${tag}: ${counter}`
Export Tag/Attribute:
`Not find any match on the ${tag} with ${attribute}!!`
`Find matches on the ${tag} with ${attribute}: ${counter}`
Export Tag/Attribute/Value:
`Not find any match on the ${tag} with ${attribute}="${value}"!!`
`Find matches on the ${tag} with ${attribute}="${value}": ${counter}`
isTagOverLimit()
Export Tag:
`There are ${counter} ${tag} tag, it's over the limit ${limit}!!`
`Find matches on the ${tag} tag: ${counter}`
Export Tag/Attribute:
`There are ${counter} ${tag} with ${attribute}, it's over the limit ${limit}!!`
`Find matches on the ${tag} with ${attribute}: ${counter}`
Export Tag/Attribute/Value:
`There are ${counter} ${tag} with ${attribute}="${value}", it's over the limit ${limit}!!`
`Find matches on the ${tag} with ${attribute}="${value}": ${counter}`
isTagNotOnly()
Export is the same with "isTagOverLimit"
detectSubRules()
Calling the other check methods to detect by the setting in the subRules.
Rule Set Format
rule: 'Check_Method_Name' tag: 'HTML_Tag_Name' attribute: 'Attribute_Name' value: 'Attribute_Value' subRules: Rule_set ... limit: Integer
- Must have: rule & tag
- If you want to use the subRules, the rule must be "detectSubRules" and the limit will be useless.
- The limit will be setting up with a default 0, if you are not setting a value.
Predefine Rules
isImageWithoutAlt
Detect if any <img />
tag without alt attribute
rule: 'hasTagWithoutAttr' tag: 'img' attribute: 'alt'
isAWithoutRel
Detect if any <a />
tag without rel attribute
rule: 'hasTagWithoutAttr' tag: 'a' attribute: 'rel'
isHeadLegal
In <head>
tag
- Detect if header doesn’t have
<title>
tag - Detect if header doesn’t have
<meta name=“descriptions” ... />
tag - Detect if header doesn’t have
<meta name=“keywords” ... />
tag
rule: 'detectSubRules' tag: 'head' subRules: rule: 'isTagNotExist' tag: 'title' rule: 'isTagNotExist' tag: 'meta' attribute: 'name' value: 'description' rule: 'isTagNotExist' tag: 'meta' attribute: 'name' value: 'keywords'
isStrongOverLimit
Detect if there’re more than 15 <strong>
tag in HTML (15 is a value should be configurable by user)
rule: 'isTagOverLimit' tag: 'strong' limit: 15
isH1NotOnly
Detect if a HTML have more than one <H1>
tag
rule: 'isTagNotOnly' tag: 'H1'
Example
Basic
By Constructor
const SnifferManager = const ioConfig = input: 'PathToFile' // input: fs.createReadStream('PathToFile'), output: 'PathToFile' // output: fs.createWriteStream('PathToFile') // output: 'console' const sniffer = ioConfig sniffer
By setInput()/setOutput()
const SnifferManager = const ioConfig = input: 'PathToFile' // input: fs.createReadStream('PathToFile'), output: 'PathToFile' // output: fs.createWriteStream('PathToFile') // output: 'console' const sniffer = sniffer// 'PathToFile' or fs.createReadStream(PathToFile) sniffer// 'PathToFile' or fs.createWriteStream(PathToFile) or 'console' sniffer
No Input/Output by console
const SnifferManager = const sniffer = sniffer// sniffer.check('YourContext', [Rules])
Choice from the Predefine Rules
const PredefineRules SnifferManager = const ioConfig = input: 'PathToFile' // input: fs.createReadStream('PathToFile'), output: 'PathToFile' // output: fs.createWriteStream('PathToFile') // output: 'console' const sniffer = ioConfig sniffer
Modify the Predefine Rules
If you want to implement additional rules for <meta>
tag.
Ex: Checking <meta name=“robots” />
const PredefineRules SnifferManager = const ioConfig = input: 'PathToFile' // input: fs.createReadStream('PathToFile'), output: 'PathToFile' // output: fs.createWriteStream('PathToFile') // output: 'console' const sniffer = ioConfig PredefineRulesisHeadLegalsubRules sniffer sniffer
If you want to reset the limit of <strong>
from 15 to 5
const PredefineRules SnifferManager = const ioConfig = input: 'PathToFile' // input: fs.createReadStream('PathToFile'), output: 'PathToFile' // output: fs.createWriteStream('PathToFile') // output: 'console' const sniffer = ioConfig PredefineRulesisStrongOverLimitlimit = 5 sniffer sniffer
Customize the rule
The Customize rules & the predefine rules can be used in the same time.
const SnifferManager = const ioConfig = input: 'PathToFile' // input: fs.createReadStream('PathToFile'), output: 'PathToFile' // output: fs.createWriteStream('PathToFile') // output: 'console' const sniffer = ioConfig sniffer
Mixed Customize/Predefine rules
const PredefineRules SnifferManager = const ioConfig = input: 'PathToFile' // input: fs.createReadStream('PathToFile'), output: 'PathToFile' // output: fs.createWriteStream('PathToFile') // output: 'console' const sniffer = ioConfig sniffer