@consilioweb/payload-seo-analyzer 1.7.1 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -208,6 +208,34 @@ All dashboard views automatically switch to the user's Payload admin locale (Fre
208
208
 
209
209
  <img src="https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png" alt="line">
210
210
 
211
+ ## ⚠️ Migration from `@consilioweb/seo-analyzer`
212
+
213
+ This package has been renamed from `@consilioweb/seo-analyzer` to `@consilioweb/payload-seo-analyzer`.
214
+
215
+ **Automatic migration (recommended):**
216
+
217
+ ```bash
218
+ npx @consilioweb/migrate
219
+ ```
220
+
221
+ This will update your `package.json` and all imports automatically.
222
+
223
+ **Manual migration:**
224
+
225
+ ```bash
226
+ npm uninstall @consilioweb/seo-analyzer
227
+ npm install @consilioweb/payload-seo-analyzer
228
+ ```
229
+
230
+ Then update your imports:
231
+
232
+ ```diff
233
+ - import { seoAnalyzerPlugin } from '@consilioweb/seo-analyzer'
234
+ + import { seoAnalyzerPlugin } from '@consilioweb/payload-seo-analyzer'
235
+ ```
236
+
237
+ ---
238
+
211
239
  ## Installation
212
240
 
213
241
  ```bash
@@ -458,6 +486,9 @@ type RuleGroup =
458
486
  | 'technical'
459
487
  | 'accessibility'
460
488
  | 'ecommerce'
489
+ | 'eeat' // SEO 2026 — E-E-A-T transparency signals (non-scoring, feeds AI-readiness)
490
+ | 'geo' // SEO 2026 — generative-engine extractability (non-scoring, feeds AI-readiness)
491
+ | 'hreflang' // reserved for multi-locale hreflang audit (roadmap)
461
492
  ```
462
493
 
463
494
  ### Advanced Configuration Example
@@ -597,6 +628,9 @@ All endpoints are prefixed with the configured `endpointBasePath` (default: `/se
597
628
  | `GET` `POST` | `/validate` | Run SEO analysis on a document |
598
629
  | `GET` | `/check-keyword` | Check for keyword duplication across collections |
599
630
  | `GET` | `/audit` | Full site-wide SEO audit |
631
+ | `GET` | `/indexation-audit` | Cross-page indexation hygiene — surfaces every `noindex` / canonical problem in one place |
632
+ | `GET` | `/core-web-vitals` | Real LCP/INP/CLS via PageSpeed Insights — informational, on-demand, SSRF-safe (own origin only) |
633
+ | `GET` `POST` | `/gsc/*` | Google Search Console OAuth (opt-in `features.gscApi`): `status`, `auth`, `callback`, `data`, `disconnect` |
600
634
  | `GET` | `/history` | Score history data for trend charts |
601
635
  | `GET` | `/sitemap-audit` | Sitemap structure audit |
602
636
  | `GET` `PATCH` | `/settings` | Read or update SEO settings |
@@ -634,6 +668,8 @@ Each check has a **weight** (1-5) and produces a **status** (`pass`, `warning`,
634
668
  | OK | >= 41 |
635
669
  | Poor | < 41 |
636
670
 
671
+ > **AI-readiness sub-score (SEO 2026).** `analyzeSeo()` also returns an optional `aiReadiness` ({ score, level }) — a **separate** indicator of how well the page is structured to be *cited* by generative engines (AI Overviews, ChatGPT, Perplexity). It aggregates the `geo` + `eeat` groups and the `schema-coverage` check. It is intentionally **decoupled from the SEO `score`** (those groups are weight 0 in the SEO score) because ranking and AI-citation are governed by different signals.
672
+
637
673
  ### Complete Check List
638
674
 
639
675
  <details>
@@ -642,7 +678,7 @@ Each check has a **weight** (1-5) and produces a **status** (`pass`, `warning`,
642
678
  | Check ID | Weight | Category | Description |
643
679
  |----------|--------|----------|-------------|
644
680
  | `title-missing` | 3 | Critical | Meta title is present |
645
- | `title-length` | 3 | Critical | Title between 30-60 characters |
681
+ | `title-length` | 1 | Bonus | Title 30-60 chars — SERP display hint, not a ranking factor (depondéré in the 2026 desintox pass) |
646
682
  | `title-keyword` | 3 | Critical | Focus keyword in title |
647
683
  | `title-keyword-position` | 2 | Important | Keyword in first half of title |
648
684
  | `title-duplicate-brand` | 2 | Important | No duplicate brand name |
@@ -699,10 +735,10 @@ Each check has a **weight** (1-5) and produces a **status** (`pass`, `warning`,
699
735
  |----------|--------|----------|-------------|
700
736
  | `content-wordcount` | 2 | Important | Meets minimum word count by page type |
701
737
  | `content-keyword-intro` | 2 | Important | Keyword in first paragraph |
702
- | `content-keyword-density` | 2-3 | Important/Critical | Density between 0.5%-2.5% |
738
+ | `content-keyword-density` | 0-3 | Bonus/Critical | Over-stuffing guard ONLY (warning >2.5%, fail >3%); low density is informational (weight 0), no minimum floor |
703
739
  | `content-no-placeholder` | 3 | Critical | No lorem ipsum, TODO, or placeholders |
704
740
  | `content-thin` | 2 | Important | Not thin content (>100 words) |
705
- | `content-keyword-distribution` | 2 | Important | Keyword in 2+ of 3 content tiers |
741
+ | `content-keyword-distribution` | 0 | Bonus | Informational only disguised density metric, not a ranking factor |
706
742
  | `content-has-lists` | 1 | Bonus | Contains ordered/unordered lists |
707
743
 
708
744
  </details>
@@ -743,11 +779,14 @@ Each check has a **weight** (1-5) and produces a **status** (`pass`, `warning`,
743
779
  </details>
744
780
 
745
781
  <details>
746
- <summary><strong>Schema (1 check)</strong></summary>
782
+ <summary><strong>Schema (page-type aware — SEO 2026)</strong></summary>
747
783
 
748
784
  | Check ID | Weight | Category | Description |
749
785
  |----------|--------|----------|-------------|
750
- | `schema-readiness` | 1 | Bonus | Page has enough metadata for JSON-LD generation |
786
+ | `schema-coverage` | 0-1 | Bonus | Determines the schema.org type expected for the page type, validates the required fields derivable from the CMS, and reminds about required fields it cannot verify (author, offers, address). A page with no usable structured-data signals no longer passes green. |
787
+ | `schema-faq-no-rich-result` | 0 | Bonus | FAQPage markup stays valid but no longer yields a SERP rich result (FAQ removed 2026) — informational, never recommends removing the markup. |
788
+
789
+ > Replaces the former single `schema-readiness` check (which passed green without ever reading any JSON-LD).
751
790
 
752
791
  </details>
753
792
 
@@ -759,8 +798,8 @@ Each check has a **weight** (1-5) and produces a **status** (`pass`, `warning`,
759
798
  | `readability-flesch` | 2 | Important | Flesch reading ease (FR: >= 40, EN: >= 60) |
760
799
  | `readability-long-sentences` | 2 | Important | Long sentence ratio < 30% (FR: >25 words, EN: >20 words) |
761
800
  | `readability-long-paragraphs` | 2 | Important | No paragraphs over 150 words |
762
- | `readability-passive` | 2 | Important | Passive voice ratio (FR: < 15%, EN: < 10%) |
763
- | `readability-transitions` | 1 | Bonus | Transition words (FR: 15%+, EN: 20%+) |
801
+ | `readability-passive` | 0 | Bonus | Passive voice ratio — informational only (Yoast heuristic, never a ranking factor) |
802
+ | `readability-transitions` | 0 | Bonus | Transition words — informational only (Yoast heuristic, never a ranking factor) |
764
803
  | `readability-consecutive-starts` | 1 | Bonus | No 3+ consecutive sentences with same first word |
765
804
  | `readability-long-sections` | 2 | Important | No sections >400 words without subheadings |
766
805
 
@@ -793,7 +832,7 @@ Each check has a **weight** (1-5) and produces a **status** (`pass`, `warning`,
793
832
 
794
833
  | Check ID | Weight | Category | Description |
795
834
  |----------|--------|----------|-------------|
796
- | `cornerstone-wordcount` | 4 | Important | 1500+ words for pillar content |
835
+ | `cornerstone-wordcount` | 4 | Important | Thin-content floor for pillar pages (no longer rewards an arbitrary 1500-word target) |
797
836
  | `cornerstone-internal-links` | 4 | Important | 5+ internal links |
798
837
  | `cornerstone-focus-keyword` | 5 | Critical | Focus keyword is defined |
799
838
  | `cornerstone-meta-description` | 5 | Critical | Meta description is present and optimized |