---
title: "Assessments for SEO and Readability"
description: "All 28 SEO and readability assessments from Yoast SEO v3, with three custom Kirby additions."
canonical_url: "https://kirby.tools/docs/seo-audit/guide/assessments"
---

# Assessments for SEO and Readability

> All 28 SEO and readability assessments from Yoast SEO v3, with three custom Kirby additions.

## Overview

Kirby SEO Audit comes with 28 comprehensive assessments that analyze your content for search engine optimization and readability:

- **17 SEO assessments**: Powered by Yoast SEO v3, focusing on keyword optimization, meta data, links, and technical SEO factors
- **8 Readability assessments**: Powered by Yoast SEO v3, analyzing content structure, sentence length, and overall readability
- **3 Custom SEO assessments**: Provided by Kirby SEO Audit to expand on Yoast SEO

Results are grouped into Good, OK, Bad, and Feedback, regardless of whether an assessment is SEO or readability – see [Introduction](/docs/seo-audit/getting-started) for what each category means.

## Complete Assessment List

### Yoast SEO v3 Assessments

#### SEO Assessments (17)

<table>
<thead>
  <tr>
    <th>
      Assessment
    </th>
    
    <th>
      Key
    </th>
    
    <th>
      What It Checks
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Introduction Keyword
    </td>
    
    <td>
      <code>
        introductionKeyword
      </code>
    </td>
    
    <td>
      Keyphrase appears in the first paragraph
    </td>
  </tr>
  
  <tr>
    <td>
      Keyphrase Length
    </td>
    
    <td>
      <code>
        keyphraseLength
      </code>
    </td>
    
    <td>
      Keyphrase is not too short or long
    </td>
  </tr>
  
  <tr>
    <td>
      Keyword Density
    </td>
    
    <td>
      <code>
        keyphraseDensity
      </code>
    </td>
    
    <td>
      Keyphrase frequency is optimal (not too low/high)
    </td>
  </tr>
  
  <tr>
    <td>
      Meta Description Keyword
    </td>
    
    <td>
      <code>
        metaDescriptionKeyword
      </code>
    </td>
    
    <td>
      Keyphrase is present in meta description
    </td>
  </tr>
  
  <tr>
    <td>
      Meta Description Length
    </td>
    
    <td>
      <code>
        metaDescriptionLength
      </code>
    </td>
    
    <td>
      Meta description is 120–156 characters
    </td>
  </tr>
  
  <tr>
    <td>
      Subheadings Keyword
    </td>
    
    <td>
      <code>
        subheadingsKeyword
      </code>
    </td>
    
    <td>
      Keyphrase appears in H2–H6 headings
    </td>
  </tr>
  
  <tr>
    <td>
      Text Competing Links
    </td>
    
    <td>
      <code>
        textCompetingLinks
      </code>
    </td>
    
    <td>
      No links compete with target keyphrase
    </td>
  </tr>
  
  <tr>
    <td>
      Image Keyphrase
    </td>
    
    <td>
      <code>
        imageKeyphrase
      </code>
    </td>
    
    <td>
      Images contain keyphrase in alt/title attributes
    </td>
  </tr>
  
  <tr>
    <td>
      Text Images
    </td>
    
    <td>
      <code>
        images
      </code>
    </td>
    
    <td>
      Content includes images
    </td>
  </tr>
  
  <tr>
    <td>
      Text Length
    </td>
    
    <td>
      <code>
        textLength
      </code>
    </td>
    
    <td>
      Content meets minimum word count
    </td>
  </tr>
  
  <tr>
    <td>
      Outbound Links
    </td>
    
    <td>
      <code>
        externalLinks
      </code>
    </td>
    
    <td>
      External links are present
    </td>
  </tr>
  
  <tr>
    <td>
      Title Keyword
    </td>
    
    <td>
      <code>
        keyphraseInSEOTitle
      </code>
    </td>
    
    <td>
      Keyphrase appears in page title
    </td>
  </tr>
  
  <tr>
    <td>
      Internal Links
    </td>
    
    <td>
      <code>
        internalLinks
      </code>
    </td>
    
    <td>
      Internal links are present
    </td>
  </tr>
  
  <tr>
    <td>
      Page Title Width
    </td>
    
    <td>
      <code>
        titleWidth
      </code>
    </td>
    
    <td>
      Title fits in search results (~60 chars)
    </td>
  </tr>
  
  <tr>
    <td>
      URL Keyword
    </td>
    
    <td>
      <code>
        slugKeyword
      </code>
    </td>
    
    <td>
      Keyphrase is in URL slug
    </td>
  </tr>
  
  <tr>
    <td>
      Function Words
    </td>
    
    <td>
      <code>
        functionWordsInKeyphrase
      </code>
    </td>
    
    <td>
      Keyphrase contains content words (not just "the", "a")
    </td>
  </tr>
  
  <tr>
    <td>
      Keyphrase Distribution
    </td>
    
    <td>
      <code>
        keyphraseDistribution
      </code>
    </td>
    
    <td>
      Keyphrase is evenly distributed throughout text
    </td>
  </tr>
</tbody>
</table>

#### Readability Assessments (8)

<table>
<thead>
  <tr>
    <th>
      Assessment
    </th>
    
    <th>
      Key
    </th>
    
    <th>
      What It Checks
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Subheading Distribution
    </td>
    
    <td>
      <code>
        subheadingsTooLong
      </code>
    </td>
    
    <td>
      No text blocks exceed 300 words without a subheading
    </td>
  </tr>
  
  <tr>
    <td>
      Paragraph Length
    </td>
    
    <td>
      <code>
        textParagraphTooLong
      </code>
    </td>
    
    <td>
      Paragraphs do not exceed 150 words
    </td>
  </tr>
  
  <tr>
    <td>
      Sentence Length
    </td>
    
    <td>
      <code>
        textSentenceLength
      </code>
    </td>
    
    <td>
      At most 25% of sentences exceed 20 words
    </td>
  </tr>
  
  <tr>
    <td>
      Transition Words
    </td>
    
    <td>
      <code>
        textTransitionWords
      </code>
    </td>
    
    <td>
      Content uses connective phrases
    </td>
  </tr>
  
  <tr>
    <td>
      Passive Voice
    </td>
    
    <td>
      <code>
        passiveVoice
      </code>
    </td>
    
    <td>
      Passive voice is used sparingly
    </td>
  </tr>
  
  <tr>
    <td>
      Text Presence
    </td>
    
    <td>
      <code>
        textPresence
      </code>
    </td>
    
    <td>
      Page contains text content
    </td>
  </tr>
  
  <tr>
    <td>
      Sentence Beginnings
    </td>
    
    <td>
      <code>
        sentenceBeginnings
      </code>
    </td>
    
    <td>
      Sentences do not start the same way repeatedly
    </td>
  </tr>
  
  <tr>
    <td>
      Word Complexity
    </td>
    
    <td>
      <code>
        wordComplexity
      </code>
    </td>
    
    <td>
      Vocabulary is not overly complex
    </td>
  </tr>
</tbody>
</table>

### Kirby SEO Audit Custom Assessments (3)

<table>
<thead>
  <tr>
    <th>
      Assessment
    </th>
    
    <th>
      Key
    </th>
    
    <th>
      What It Checks
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      Single H1
    </td>
    
    <td>
      <code>
        singleH1
      </code>
    </td>
    
    <td>
      Exactly one H1 heading exists
    </td>
  </tr>
  
  <tr>
    <td>
      Heading Structure
    </td>
    
    <td>
      <code>
        headingStructureOrder
      </code>
    </td>
    
    <td>
      H1–H6 headings follow sequential order (no skips like H1→H3)
    </td>
  </tr>
  
  <tr>
    <td>
      Image Alt Attributes
    </td>
    
    <td>
      <code>
        altAttribute
      </code>
    </td>
    
    <td>
      All images have alt text
    </td>
  </tr>
</tbody>
</table>

## Custom Assessment Selection

By default, all assessments are enabled. Pick which SEO and readability assessments to include in the report by adding an `assessments` property to your blueprint:

```yaml
# Select the assessments you want to include
assessments:
  - metaDescriptionKeyword
  - metaDescriptionLength
  - titleWidth
  - images
  - textLength
  - imageKeyphrase
```

Wrap the snippet under `buttons.seo-audit` (view button) or under `sections.<name>` with `type: seo-audit` (section) – see [Local Configuration](/docs/seo-audit/configuration/local) for the full scaffolds.

<note>

Assessment names are matched case-insensitively and a trailing `Assessment` suffix is ignored – `titleWidth`, `titlewidth`, and `titleWidthAssessment` all select the same check.

</note>

## Keyphrase-Dependent Assessments

The following SEO assessments require a keyphrase to be defined via [`keyphraseField`](/docs/seo-audit/configuration/local#keyphrasefield) or [`keyphrase`](/docs/seo-audit/configuration/local#keyphrase):

- `functionWordsInKeyphrase`
- `introductionKeyword`
- `keyphraseDensity`
- `keyphraseDistribution`
- `keyphraseInSEOTitle`
- `keyphraseLength`
- `metaDescriptionKeyword`
- `slugKeyword`
- `subheadingsKeyword`

If no keyphrase is provided, these assessments will be skipped unless explicitly enabled in the `assessments` property.

## Language-Specific Features

Some assessments are only available in certain languages. The plugin uses the `lang` attribute of the rendered page's HTML for analysis, while the translations of the SEO results are based on the language selected in the Kirby Panel.

<note>

Make sure that the language code in your `languages/xx.php` file matches the ISO 639-1 language code (e.g., use `de` for German, not `ger`).

</note>

<table>
<thead>
  <tr>
    <th>
      Assessment
    </th>
    
    <th>
      Supported Languages
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        wordComplexity
      </code>
    </td>
    
    <td>
      de, en, es, fr
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        keyphraseDistribution
      </code>
    </td>
    
    <td>
      ar, cs, de, el, en, es, fr, he, hu, id, it, ja, nb, nl, pl, pt, ru, sk, sv, tr
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        metaDescriptionLength
      </code>
    </td>
    
    <td>
      ar, cs, de, el, en, es, fa, fr, he, hu, id, it, ja, nb, nl, pl, pt, ru, sk, sv, tr
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        textParagraphTooLong
      </code>
    </td>
    
    <td>
      ar, cs, de, el, en, es, fa, fr, he, hu, id, it, ja, nb, nl, pl, pt, ru, sk, sv, tr
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        textSentenceLength
      </code>
    </td>
    
    <td>
      ar, cs, de, el, en, es, fa, fr, he, hu, id, it, ja, nb, nl, pl, pt, ru, sk, sv, tr
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        passiveVoice
      </code>
    </td>
    
    <td>
      ar, cs, de, el, en, es, fa, fr, he, hu, id, it, nb, nl, pl, pt, ru, sk, sv, tr
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        textTransitionWords
      </code>
    </td>
    
    <td>
      ar, ca, cs, de, el, en, es, fa, fr, he, hu, id, it, ja, nb, nl, pl, pt, ru, sk, sv, tr
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        functionWordsInKeyphrase
      </code>
    </td>
    
    <td>
      ar, cs, de, el, en, es, fa, fr, he, hu, id, it, ja, nb, nl, pl, pt, ru, sk, sv, tr
    </td>
  </tr>
</tbody>
</table>

Norwegian is listed as `nb`, the code the analysis ships its researcher under. A page marked `no` or `nn` resolves to it, so all three write their own language.

<note>

With no `assessments` list configured, an assessment that does not support your content's language is skipped silently. List it explicitly and the analysis aborts with an error naming the languages that assessment supports.

</note>

---

Every page of this site as Markdown: <https://kirby.tools/sitemap.md>
