The SEO panel runs 26 rules. This page lists each one with what it checks, where the thresholds sit and how much it’s worth. The thresholds are hard-coded; the only things you can change are whether a rule runs and how much it weighs.
Rules come in two flavours. Most are pass or fail: you get the full weight or nothing. A few are graduated, awarding a percentage of the weight depending on how close you are, and those are marked below. A rule that can’t be evaluated at all (no images for the alt-text rule, no sentences for readability) drops out of the score rather than counting against you.
Keyword rules#
All nine of these are skipped when there’s no focus keyword.
| Rule | Checks | Weight |
|---|---|---|
keywordInTitle |
Keyword appears in the title | 6 |
keywordInMetaDescription |
Keyword appears in description |
2 |
keywordInPermalink |
Keyword appears in the slug, after stripping stop words like “the” and “of” from the keyword and treating hyphens as spaces | 5 |
keywordInContent |
Keyword appears anywhere in the body | 3 |
keywordIn10Percent |
Keyword appears in the first 10% of the words | 3 |
keywordInSubheadings |
Keyword appears in at least one H2 to H6 | 3 |
keywordInImageAlt |
Keyword appears in the alt text of at least one image (Markdown, HTML or the thumbnail) | 2 |
keywordDensity |
Graduated. Keyword occurrences as a share of total words: 1.0% to 2.5% is full marks, 0.5% to 1.0% half, below 0.5% a third, and 0% or above 2.5% nothing | 6 |
titleStartWithKeyword |
Title begins with the keyword, at a word boundary | 3 |
Title rules#
| Rule | Checks | Weight |
|---|---|---|
titleLength |
Graduated. 30 to 60 characters is full marks, 20 to 29 or 61 to 70 is 75%, anything else nothing | 3 |
titleHasNumber |
Title contains a digit | 1 |
titleHasPowerWords |
Title contains a word from a built-in list of persuasive words | 1 |
titleSentiment |
Title contains a word with positive or negative sentiment, i.e. isn’t neutral | 1 |
The last three are worth a point each, which is about right for how seriously to take them.
Content rules#
| Rule | Checks | Weight |
|---|---|---|
contentHasShortParagraphs |
No paragraph is longer than 120 words. Headings, lists, quotes, code and images don’t count as paragraphs | 3 |
contentHasAssets |
Graduated. Images score 1, 2, 4 or 6 for one, two, three or four-plus; videos (<video>, YouTube or Vimeo embeds, and youtube, vimeo or video shortcodes) add 1 for one or 2 for more. Capped at 6. The thumbnail counts as an image |
6 |
lengthPermalink |
Slug is 75 characters or fewer | 4 |
descriptionLength |
Graduated. 120 to 160 characters is full marks, 80 to 119 is 75%, 161 to 200 is half, anything else nothing | 3 |
contentLength |
Graduated. 1000 words or more is full marks, 600 is 75%, 300 is half, and anything shorter still gets a quarter | 4 |
imagesHaveAlt |
Every image in the body has non-empty alt text. Dropped from scoring if there are no images | 2 |
Link rules#
A link is internal if it starts with /, ./ or ../, or with your site.url. Hugo ref and relref shortcodes also count as internal. Anything else starting with http is external; anchors and anything stranger are ignored.
| Rule | Checks | Weight |
|---|---|---|
linksHasInternal |
At least one internal link | 5 |
linksHasExternals |
At least one external link | 4 |
linksNotAllExternals |
Not every link is external. Passes if there’s an internal link or no links at all | 2 |
Readability rules#
All four are graduated and all four are skipped when the body has no sentences.
| Rule | Checks | Weight |
|---|---|---|
readabilitySentenceLength |
Average words per sentence. 15 to 20 is full marks, 12 to 14 or 21 to 25 is 75%, 10 to 11 or 26 to 30 is half, anything else a quarter | 4 |
readabilityPassiveVoice |
Share of sentences in the passive voice. 10% or less is full marks, then 75% at 15%, half at 20%, a quarter at 25% and nothing above that | 3 |
readabilityTransitionWords |
Share of sentences that use a transition word (“however”, “for example”, etc.). 30% or more is full marks, 20% is 75%, 10% is half, less is a quarter | 3 |
readabilityFleschScore |
Flesch reading ease. 60 to 70 is full marks, 50 to 60 or 70 to 80 is 75%, 40 to 50 or 80 to 90 is half, 30 to 40 or above 90 a quarter, below 30 nothing | 5 |
The passive voice and transition word detectors are pattern matchers over English text, so expect some noise, particularly on technical writing with a lot of code in it.
Configuring rules#
Rule configuration lives under seo in admin/cms.yaml, not site.yaml:
seo:
enabled: true
rules:
titleHasPowerWords:
enabled: false
titleSentiment:
enabled: false
keywordDensity:
weight: 10Each rule takes enabled and weight. Disabled rules disappear from the panel and from the denominator, so turning off a rule you always fail will raise your score; whether that’s cheating is between you and your conscience. Weights are relative to each other, so doubling one rule’s weight halves everyone else’s share.
Older configs used snake_case ids like keyword_in_title and title_length. Those still work and map onto the current names. There’s a params key in the schema too, but no rule reads it, so leave it out.
seo.enabled: false removes the SEO tab altogether.
Rules skipped by page type#
As explained in the overview, the homepage and section index pages get a reduced set:
| Page type | Skipped |
|---|---|
Homepage (content/_index.md) |
keywordInPermalink, lengthPermalink, linksHasExternals, linksNotAllExternals, titleSentiment, titleHasPowerWords, titleHasNumber, contentLength and all four readability rules |
Section index (any other _index.md) |
contentHasShortParagraphs, keywordIn10Percent, keywordInContent, keywordInSubheadings, keywordDensity, linksHasInternal, linksHasExternals, linksNotAllExternals, contentLength and all four readability rules |