@power-seo/content-analysis 1.0.4 → 1.0.6

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.
Files changed (2) hide show
  1. package/README.md +239 -131
  2. package/package.json +29 -6
package/README.md CHANGED
@@ -1,114 +1,149 @@
1
- # @power-seo/content-analysis — Yoast-Style SEO Content Scoring Engine for React & Node.js
1
+ # @power-seo/content-analysis
2
+
3
+ ![content-analysis banner](../../image/content-analysis/banner.svg)
2
4
 
3
5
  Keyword-focused content analysis with real-time scoring, readability checks, and actionable feedback — like Yoast SEO, but as a standalone TypeScript library that works anywhere.
4
6
 
5
7
  [![npm version](https://img.shields.io/npm/v/@power-seo/content-analysis)](https://www.npmjs.com/package/@power-seo/content-analysis)
6
8
  [![npm downloads](https://img.shields.io/npm/dm/@power-seo/content-analysis)](https://www.npmjs.com/package/@power-seo/content-analysis)
9
+ [![Socket](https://socket.dev/api/badge/npm/package/@power-seo/content-analysis)](https://socket.dev/npm/package/@power-seo/content-analysis)
10
+ [![npm provenance](https://img.shields.io/badge/npm-provenance-enabled-blue)](https://github.com/CyberCraftBD/power-seo/actions)
7
11
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
12
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue)](https://www.typescriptlang.org/)
9
13
  [![tree-shakeable](https://img.shields.io/badge/tree--shakeable-yes-brightgreen)](https://bundlephobia.com/package/@power-seo/content-analysis)
10
14
 
11
- `@power-seo/content-analysis` gives you a complete Yoast-style SEO scoring pipeline for any text content. Feed it a page's title, meta description, body HTML, focus keyphrase, images, and links — get back structured `good` / `improvement` / `error` results for every SEO factor. Run it server-side in a CMS, client-side in a React editor, or inside a CI content quality gate. All checks are individually configurable and tree-shakeable.
15
+ `@power-seo/content-analysis` delivers a comprehensive, WordPress SEO plugin–style scoring pipeline for evaluating text content, comparable to Yoast SEO, All in One SEO (AIOSEO), Rank Math, SEOPress, and The SEO Framework. Provide a page title, meta description, body content, focus keyphrase, images, and links — get back structured `good` / `needs-improvement` / `poor` results across all critical SEO factors. Run it server-side in a CMS, client-side in a React editor, or inside a CI content quality gate. All 13 analysis checks are fully configurable and tree-shakeable.
12
16
 
13
17
  > **Zero runtime dependencies** — only `@power-seo/core` as a peer.
14
18
 
15
- ## Documentation
19
+ ---
20
+
21
+ ## Why @power-seo/content-analysis?
22
+
23
+ | | Without | With |
24
+ |---|---|---|
25
+ | Keyphrase check | ❌ Manual grep | ✅ Density + distribution scoring |
26
+ | Title validation | ❌ Eye-check only | ✅ Presence, length, keyphrase match |
27
+ | Meta description | ❌ Unchecked | ✅ Length (120–160 chars) + keyphrase |
28
+ | Heading structure | ❌ Missed H1s | ✅ H1 hierarchy + keyphrase in subheadings |
29
+ | Image alt text | ❌ Skipped | ✅ Alt presence + keyphrase in alt |
30
+ | Link analysis | ❌ Unknown | ✅ Internal + external link presence |
31
+ | SEO score | ❌ Guesswork | ✅ Aggregate score with per-check breakdown |
32
+ | Framework support | ❌ WordPress-only | ✅ Next.js, Remix, Vite, Node.js, Edge |
16
33
 
17
- - **Package docs:** [`apps/docs/src/content/docs/packages/content-analysis.mdx`](../../apps/docs/src/content/docs/packages/content-analysis.mdx)
18
- - **Ecosystem overview:** [`README.md`](../../README.md)
19
- - **Contributing guide:** [`CONTRIBUTING.md`](../../CONTRIBUTING.md)
34
+ ![SEO Score Dashboard](../../image/content-analysis/score-dashboard.svg)
35
+
36
+ ---
20
37
 
21
38
  ## Features
22
39
 
23
- - **Keyphrase density check** — scores optimal 0.5–3% keyword frequency in body copy
24
- - **Keyphrase distribution** — verifies the focus keyword appears in the first 10% of content
40
+ - **Keyphrase density check** — scores optimal 0.5–2.5% keyword frequency in body copy
41
+ - **Keyphrase distribution** — verifies the focus keyword appears in intro, headings, slug, and image alt
25
42
  - **Title checks** — detects missing titles and keyphrase absence in the `<title>` tag
26
- - **Meta description checks** — validates presence, length (120–158 chars), and keyphrase inclusion
27
- - **Heading structure** — ensures H1 exists and that the keyphrase appears in at least one heading
28
- - **Word count** — flags pages under the 300-word minimum threshold
43
+ - **Meta description checks** — validates presence, length (120–160 chars), and keyphrase inclusion
44
+ - **Heading structure** — validates H1 existence, hierarchy, and keyphrase in subheadings
45
+ - **Word count** — flags pages under 300 words (good at 1,000+)
29
46
  - **Image alt text** — scans all images for missing alt attributes
30
47
  - **Image keyphrase** — checks whether at least one image alt contains the focus keyphrase
31
- - **Internal and external link analysis** — verifies outbound and inbound link presence
32
- - **Configurable check suite** — disable any individual check via `disabledChecks` config
33
- - **Framework-agnostic** — works in Next.js, Remix, Gatsby, Vite, vanilla Node.js
48
+ - **Internal and external link analysis** — verifies inbound and outbound link presence
49
+ - **Per-check disable config** — skip irrelevant checks via `disabledChecks` config
50
+ - **React components** — pre-built `ScorePanel`, `CheckList`, and `ContentAnalyzer` UI components
51
+ - **Framework-agnostic** — works in Next.js, Remix, Gatsby, Vite, vanilla Node.js, Edge
34
52
  - **Full TypeScript support** — complete type definitions for all inputs, outputs, and check IDs
35
53
  - **Tree-shakeable** — import only the checks you use; zero dead code in your bundle
36
54
 
37
- ## Table of Contents
38
-
39
- - [Installation](#installation)
40
- - [Quick Start](#quick-start)
41
- - [Usage](#usage)
42
- - [Running All Checks at Once](#running-all-checks-at-once)
43
- - [Running Individual Checks](#running-individual-checks)
44
- - [Disabling Specific Checks](#disabling-specific-checks)
45
- - [Using in a React Editor](#using-in-a-react-editor)
46
- - [API Reference](#api-reference)
47
- - [`analyzeContent()`](#analyzecontent)
48
- - [Individual Check Functions](#individual-check-functions)
49
- - [Types](#types)
50
- - [The @power-seo Ecosystem](#the-power-seo-ecosystem)
51
- - [About CyberCraft Bangladesh](#about-cybercraft-bangladesh)
55
+ ![Google SERP Preview](../../image/content-analysis/serp-preview.svg)
56
+
57
+ ---
58
+
59
+ ## Comparison
60
+
61
+ | Feature | @power-seo/content-analysis | Yoast SEO | next-seo | seo-analyzer | react-helmet |
62
+ | ------------------------------ | :-------------------------: | :-------: | :------: | :----------: | :----------: |
63
+ | Keyphrase density check | ✅ | ✅ | ❌ | Partial | ❌ |
64
+ | Keyphrase distribution | ✅ | ✅ | ❌ | ❌ | ❌ |
65
+ | Title + meta validation | ✅ | ✅ | ❌ | Partial | ❌ |
66
+ | Heading structure check | ✅ | ✅ | ❌ | ❌ | ❌ |
67
+ | Image alt + keyphrase check | ✅ | ✅ | ❌ | ❌ | ❌ |
68
+ | Internal / external link check | ✅ | ✅ | ❌ | ❌ | ❌ |
69
+ | Aggregate SEO score | ✅ | ✅ | ❌ | Partial | ❌ |
70
+ | Per-check disable config | ✅ | ❌ | ❌ | ❌ | ❌ |
71
+ | Works outside WordPress | ✅ | ❌ | ✅ | ✅ | ✅ |
72
+ | TypeScript-first | ✅ | ❌ | Partial | ❌ | ❌ |
73
+ | Tree-shakeable | ✅ | ❌ | Partial | ❌ | ❌ |
74
+ | React UI components | ✅ | ✅ | ❌ | ❌ | ❌ |
75
+ | CI / Node.js usage | ✅ | ❌ | ❌ | ✅ | ❌ |
76
+ | Zero runtime dependencies | ✅ | ❌ | ❌ | ❌ | ❌ |
77
+
78
+ ![Keyword Density Analysis](../../image/content-analysis/keyword-density.svg)
79
+
80
+ ---
52
81
 
53
82
  ## Installation
54
83
 
55
84
  ```bash
56
- npm install @power-seo/content-analysis
85
+ npm install @power-seo/content-analysis @power-seo/core
57
86
  ```
58
87
 
59
88
  ```bash
60
- yarn add @power-seo/content-analysis
89
+ yarn add @power-seo/content-analysis @power-seo/core
61
90
  ```
62
91
 
63
92
  ```bash
64
- pnpm add @power-seo/content-analysis
93
+ pnpm add @power-seo/content-analysis @power-seo/core
65
94
  ```
66
95
 
96
+ ---
97
+
67
98
  ## Quick Start
68
99
 
69
100
  ```ts
70
101
  import { analyzeContent } from '@power-seo/content-analysis';
71
102
 
72
- const result = await analyzeContent({
73
- keyphrase: 'react seo',
74
- title: 'How to Add SEO to React Apps',
75
- metaDescription:
76
- 'A complete guide to adding SEO meta tags, Open Graph, and structured data in React.',
77
- bodyHtml: '<h1>React SEO Guide</h1><p>Search engine optimization for React...</p>',
78
- images: [{ src: '/hero.jpg', alt: 'React SEO diagram' }],
79
- links: {
80
- internal: ['https://example.com/blog'],
81
- external: ['https://developers.google.com/search'],
82
- },
103
+ const result = analyzeContent({
104
+ title: 'Best Running Shoes for Beginners',
105
+ metaDescription: 'Discover the best running shoes for beginners with our expert guide.',
106
+ keyphrase: 'running shoes for beginners',
107
+ content: '<h1>Best Running Shoes</h1><p>Finding the right running shoes...</p>',
108
+ url: 'https://example.com/best-running-shoes',
83
109
  });
84
110
 
85
- console.log(result.score); // e.g. 82
86
- console.log(result.results); // array of { id, status, message }
111
+ console.log(result.overallStatus); // "good" | "needs-improvement" | "poor"
112
+ console.log(result.results);
113
+ // [{ id: 'title-presence', status: 'good', message: '...' }, ...]
87
114
  ```
88
115
 
116
+ ![SEO Check Results](../../image/content-analysis/check-results.svg)
117
+
118
+ **Status thresholds (per check):**
119
+ - `good` — check fully passes
120
+ - `needs-improvement` — check partially passes
121
+ - `poor` — check fails
122
+
123
+ ---
124
+
89
125
  ## Usage
90
126
 
91
127
  ### Running All Checks at Once
92
128
 
93
- `analyzeContent()` runs all 13 built-in checks and returns an aggregated score (0–100) along with per-check results.
129
+ `analyzeContent()` runs all 13 built-in checks and returns an aggregated status along with per-check results.
94
130
 
95
131
  ```ts
96
132
  import { analyzeContent } from '@power-seo/content-analysis';
97
133
 
98
- const output = await analyzeContent({
99
- keyphrase: 'next.js seo',
134
+ const output = analyzeContent({
100
135
  title: 'Next.js SEO Best Practices',
101
- metaDescription:
102
- 'Learn how to optimize your Next.js app for search engines with meta tags and structured data.',
103
- bodyHtml: htmlString,
104
- wordCount: 1250,
136
+ metaDescription: 'Learn how to optimize your Next.js app for search engines with meta tags and structured data.',
137
+ keyphrase: 'next.js seo',
138
+ content: htmlString,
139
+ url: 'https://example.com/nextjs-seo',
105
140
  images: imageList,
106
- links: { internal: internalLinks, external: externalLinks },
141
+ internalLinks: internalLinks,
142
+ externalLinks: externalLinks,
107
143
  });
108
144
 
109
- // output.score number 0–100
110
- // output.results → AnalysisResult[]
111
- // output.status → 'good' | 'improvement' | 'error'
145
+ // output.overallStatus 'good' | 'needs-improvement' | 'poor'
146
+ // output.results → AnalysisResult[]
112
147
  ```
113
148
 
114
149
  ### Running Individual Checks
@@ -126,121 +161,190 @@ import {
126
161
  checkLinks,
127
162
  } from '@power-seo/content-analysis';
128
163
 
129
- const titleResult = checkTitle({ keyphrase: 'react seo', title: 'React SEO Guide' });
130
- // { id: 'title-keyphrase', status: 'good', message: 'Focus keyphrase found in title.' }
164
+ const titleResults = checkTitle({
165
+ title: 'React SEO Guide',
166
+ keyphrase: 'react seo',
167
+ content: '',
168
+ });
169
+ // [{ id: 'title-presence', status: 'good', message: '...' },
170
+ // { id: 'title-keyphrase', status: 'good', message: '...' }]
131
171
 
132
- const wc = checkWordCount({ wordCount: 250 });
133
- // { id: 'word-count', status: 'improvement', message: 'Word count is below 300 words.' }
172
+ const wcResult = checkWordCount({ content: shortHtml });
173
+ // { id: 'word-count', status: 'poor', message: 'Content is 180 words, below minimum of 300.' }
134
174
  ```
135
175
 
136
176
  ### Disabling Specific Checks
137
177
 
138
- Pass `config.disabledChecks` to skip checks that don't apply to your content type (e.g. skip image checks on text-only pages):
178
+ Pass `config.disabledChecks` to skip checks that don't apply to your content type:
139
179
 
140
180
  ```ts
141
181
  import { analyzeContent } from '@power-seo/content-analysis';
142
182
 
143
- const output = await analyzeContent(input, {
183
+ const output = analyzeContent(input, {
144
184
  disabledChecks: ['image-alt', 'image-keyphrase', 'external-links'],
145
185
  });
146
186
  ```
147
187
 
148
- ### Using in a React Editor
188
+ ### React Components
149
189
 
150
- Integrate live scoring into a content editor — re-run analysis on every keystroke or debounced change:
190
+ Import from the `/react` entry point for pre-built analysis UI components:
151
191
 
152
192
  ```tsx
153
- import { useState, useEffect } from 'react';
154
- import { analyzeContent } from '@power-seo/content-analysis';
155
- import type { ContentAnalysisOutput } from '@power-seo/content-analysis';
193
+ import { ContentAnalyzer, ScorePanel, CheckList } from '@power-seo/content-analysis/react';
194
+ import type { ContentAnalysisInput } from '@power-seo/content-analysis';
156
195
 
157
- function SeoScorePanel({ content }: { content: EditorContent }) {
158
- const [analysis, setAnalysis] = useState<ContentAnalysisOutput | null>(null);
159
-
160
- useEffect(() => {
161
- analyzeContent({
162
- keyphrase: content.keyphrase,
163
- title: content.title,
164
- metaDescription: content.description,
165
- bodyHtml: content.html,
166
- }).then(setAnalysis);
167
- }, [content]);
168
-
169
- if (!analysis) return null;
196
+ // All-in-one component
197
+ function Editor({ input }: { input: ContentAnalysisInput }) {
198
+ return <ContentAnalyzer input={input} />;
199
+ }
170
200
 
201
+ // Or compose individually
202
+ function SeoPanel({ input }: { input: ContentAnalysisInput }) {
203
+ const result = analyzeContent(input);
171
204
  return (
172
- <div>
173
- <p>SEO Score: {analysis.score}/100</p>
174
- {analysis.results.map((r) => (
175
- <div key={r.id} className={`check-${r.status}`}>
176
- {r.message}
177
- </div>
178
- ))}
179
- </div>
205
+ <>
206
+ <ScorePanel score={result.score} maxScore={result.maxScore} />
207
+ <CheckList results={result.results} />
208
+ </>
180
209
  );
181
210
  }
182
211
  ```
183
212
 
213
+ ### Inside a CI Content Quality Gate
214
+
215
+ Block deploys when SEO checks fail:
216
+
217
+ ```ts
218
+ import { analyzeContent } from '@power-seo/content-analysis';
219
+
220
+ const output = analyzeContent({ title, metaDescription, keyphrase, content });
221
+
222
+ const failures = output.results.filter((r) => r.status === 'poor');
223
+
224
+ if (failures.length > 0) {
225
+ console.error('SEO checks failed:');
226
+ failures.forEach((r) => console.error(' ✗', r.message));
227
+ process.exit(1);
228
+ }
229
+ ```
230
+
231
+ ---
232
+
184
233
  ## API Reference
185
234
 
235
+ ### Entry Points
236
+
237
+ | Import | Description |
238
+ | --- | --- |
239
+ | `@power-seo/content-analysis` | Core analyzer and individual check functions |
240
+ | `@power-seo/content-analysis/react` | React components for analysis UI |
241
+
186
242
  ### `analyzeContent()`
187
243
 
188
244
  ```ts
189
245
  function analyzeContent(
190
246
  input: ContentAnalysisInput,
191
247
  config?: AnalysisConfig,
192
- ): Promise<ContentAnalysisOutput>;
248
+ ): ContentAnalysisOutput;
193
249
  ```
194
250
 
195
251
  #### `ContentAnalysisInput`
196
252
 
197
- | Prop | Type | Description |
198
- | ----------------- | ------------------------------------------ | ---------------------------------------------------------------------------- |
199
- | `keyphrase` | `string` | Focus keyphrase to analyze against |
200
- | `title` | `string` | Page `<title>` content |
201
- | `metaDescription` | `string` | Meta description content |
202
- | `bodyHtml` | `string` | Full body HTML string |
203
- | `wordCount` | `number` | Pre-computed word count (optional; auto-detected from `bodyHtml` if omitted) |
204
- | `images` | `Array<{src: string; alt?: string}>` | Images found on the page |
205
- | `links` | `{internal: string[]; external: string[]}` | Internal and external link URLs |
253
+ | Prop | Type | Required | Description |
254
+ | ----------------- | -------------------------------------- | -------- | ---------------------------------------------- |
255
+ | `content` | `string` | ✅ | Body HTML string |
256
+ | `title` | `string` | — | Page `<title>` content |
257
+ | `metaDescription` | `string` | — | Meta description content |
258
+ | `keyphrase` | `string` | — | Focus keyphrase to analyze against |
259
+ | `url` | `string` | — | Page URL (used for slug analysis) |
260
+ | `images` | `Array<{ src: string; alt?: string }>` | — | Images found on the page |
261
+ | `internalLinks` | `string[]` | | Internal link URLs |
262
+ | `externalLinks` | `string[]` | — | External link URLs |
206
263
 
207
264
  #### `ContentAnalysisOutput`
208
265
 
209
- | Field | Type | Description |
210
- | --------- | ------------------ | ---------------------------------------------------------- |
211
- | `score` | `number` | Aggregate score 0–100 |
212
- | `status` | `AnalysisStatus` | `'good'` (≥70) \| `'improvement'` (≥40) \| `'error'` (<40) |
213
- | `results` | `AnalysisResult[]` | Per-check results |
266
+ | Field | Type | Description |
267
+ | --------------- | ------------------ | --------------------------------------------------------- |
268
+ | `overallStatus` | `AnalysisStatus` | `'good'` \| `'needs-improvement'` \| `'poor'` |
269
+ | `score` | `number` | Sum of all individual check scores |
270
+ | `maxScore` | `number` | Maximum possible score (varies by enabled checks) |
271
+ | `results` | `AnalysisResult[]` | Per-check results |
272
+ | `recommendations` | `string[]` | Descriptions from all failed or partial checks |
214
273
 
215
274
  #### `AnalysisResult`
216
275
 
217
- | Field | Type | Description |
218
- | --------- | ---------------- | ---------------------------------------- |
219
- | `id` | `CheckId` | Unique check identifier |
220
- | `status` | `AnalysisStatus` | `'good'` \| `'improvement'` \| `'error'` |
221
- | `message` | `string` | Human-readable feedback |
276
+ | Field | Type | Description |
277
+ | --------- | ---------------- | --------------------------------------------- |
278
+ | `id` | `CheckId` | Unique check identifier (see table below) |
279
+ | `status` | `AnalysisStatus` | `'good'` \| `'needs-improvement'` \| `'poor'` |
280
+ | `message` | `string` | Human-readable actionable feedback |
281
+ | `score` | `number` | Points earned for this check |
282
+ | `maxScore`| `number` | Maximum points for this check |
283
+
284
+ #### `AnalysisConfig`
285
+
286
+ | Field | Type | Description |
287
+ | ---------------- | ----------- | ----------------------------------------- |
288
+ | `disabledChecks` | `CheckId[]` | List of check IDs to skip during analysis |
222
289
 
223
290
  ### Individual Check Functions
224
291
 
225
- | Function | Checks For |
226
- | ----------------------------- | --------------------------------------- |
227
- | `checkTitle(input)` | Title presence and keyphrase inclusion |
228
- | `checkMetaDescription(input)` | Description presence, length, keyphrase |
229
- | `checkKeyphraseUsage(input)` | Density (0.5–3%) and distribution |
230
- | `checkHeadings(input)` | H1 existence and keyphrase in headings |
231
- | `checkWordCount(input)` | Minimum 300-word threshold |
232
- | `checkImages(input)` | Alt text presence and keyphrase in alt |
233
- | `checkLinks(input)` | Internal and external link presence |
292
+ | Function | Check ID(s) | Checks For |
293
+ | ----------------------------- | -------------------------------------------------------------- | -------------------------------------------------- |
294
+ | `checkTitle(input)` | `title-presence`, `title-keyphrase` | Title presence, length (30–60 chars), keyphrase |
295
+ | `checkMetaDescription(input)` | `meta-description-presence`, `meta-description-keyphrase` | Description presence, length (120–160 chars), keyphrase |
296
+ | `checkKeyphraseUsage(input)` | `keyphrase-density`, `keyphrase-distribution` | Density (0.5–2.5%) and occurrence in key areas |
297
+ | `checkHeadings(input)` | `heading-structure`, `heading-keyphrase` | H1 presence, hierarchy, keyphrase in subheadings |
298
+ | `checkWordCount(input)` | `word-count` | Min 300 words (good at 1,000+) |
299
+ | `checkImages(input)` | `image-alt`, `image-keyphrase` | Alt text presence and keyphrase in alt |
300
+ | `checkLinks(input)` | `internal-links`, `external-links` | Internal and external link presence |
234
301
 
235
302
  ### Types
236
303
 
237
- | Type | Description |
238
- | ----------------------- | ------------------------------------ |
239
- | `CheckId` | Union of all 13 built-in check IDs |
240
- | `AnalysisConfig` | `{ disabledChecks?: CheckId[] }` |
241
- | `AnalysisStatus` | `'good' \| 'improvement' \| 'error'` |
242
- | `ContentAnalysisInput` | Input shape for `analyzeContent()` |
243
- | `ContentAnalysisOutput` | Output shape from `analyzeContent()` |
304
+ | Type | Description |
305
+ | ----------------------- | --------------------------------------------------------- |
306
+ | `CheckId` | Union of all 13 built-in check IDs |
307
+ | `AnalysisConfig` | `{ disabledChecks?: CheckId[] }` |
308
+ | `AnalysisStatus` | `'good' \| 'needs-improvement' \| 'poor'` |
309
+ | `ContentAnalysisInput` | Input shape for `analyzeContent()` |
310
+ | `ContentAnalysisOutput` | Output shape from `analyzeContent()` |
311
+ | `AnalysisResult` | Single check result with id, status, message, score |
312
+
313
+ ---
314
+
315
+ ## Use Cases
316
+
317
+ - **Headless CMS** — score content as editors write, before publishing
318
+ - **Next.js / Remix apps** — run analysis server-side per route and expose scores in admin dashboards
319
+ - **SaaS landing pages** — enforce SEO quality programmatically across all marketing pages
320
+ - **eCommerce product pages** — validate product titles, descriptions, and image alt text at scale
321
+ - **Blog platforms** — provide real-time Yoast-style feedback in the post editor
322
+ - **CI/CD content gates** — block deploys when SEO checks fail
323
+
324
+ ---
325
+
326
+ ## Architecture Overview
327
+
328
+ - **Pure TypeScript** — no compiled binary, no native modules
329
+ - **Zero runtime dependencies** — only `@power-seo/core` as a peer dependency
330
+ - **Framework-agnostic** — works in any JavaScript environment
331
+ - **SSR compatible** — safe to run in Next.js Server Components, Remix loaders, or Express handlers
332
+ - **Edge runtime safe** — no Node.js-specific APIs; runs in Cloudflare Workers, Vercel Edge, Deno
333
+ - **Tree-shakeable** — `"sideEffects": false` with named exports per check function
334
+ - **Dual ESM + CJS** — ships both formats via tsup for any bundler or `require()` usage
335
+
336
+ ---
337
+
338
+ ## Supply Chain Security
339
+
340
+ - No install scripts (`postinstall`, `preinstall`)
341
+ - No runtime network access
342
+ - No `eval` or dynamic code execution
343
+ - npm provenance enabled — every release is signed via Sigstore through GitHub Actions
344
+ - CI-signed builds — all releases published via verified `github.com/CyberCraftBD/power-seo` workflow
345
+ - Safe for SSR, Edge, and server environments
346
+
347
+ ---
244
348
 
245
349
  ## The [@power-seo](https://www.npmjs.com/org/power-seo) Ecosystem
246
350
 
@@ -268,15 +372,19 @@ All 17 packages are independently installable — use only what you need.
268
372
 
269
373
  ---
270
374
 
375
+ ## Keywords
376
+
377
+ seo content analysis · yoast seo alternative · content scoring typescript · keyword density checker · react seo scoring · nextjs content analysis · seo score npm · focus keyphrase checker · meta description validator · heading seo checker · content quality gate · headless cms seo · seo readability checker · content optimization library · programmatic seo · keyphrase density analyzer · seo audit npm package · typescript seo library · content seo automation · react editor seo · ci seo check · edge runtime seo
378
+
379
+ ---
380
+
271
381
  ## About [CyberCraft Bangladesh](https://ccbd.dev)
272
382
 
273
- **[CyberCraft Bangladesh](https://ccbd.dev)** is a Bangladesh-based enterprise-grade software engineering company specializing in ERP system development, AI-powered SaaS and business applications, full-stack SEO services, custom website development, and scalable eCommerce platforms. We design and develop intelligent, automation-driven SaaS and enterprise solutions that help startups, SMEs, NGOs, educational institutes, and large organizations streamline operations, enhance digital visibility, and accelerate growth through modern cloud-native technologies.
383
+ **[CyberCraft Bangladesh](https://ccbd.dev)** is a Bangladesh-based enterprise-grade software development and Full Stack SEO service provider company specializing in ERP system development, AI-powered SaaS and business applications, full-stack SEO services, custom website development, and scalable eCommerce platforms. We design and develop intelligent, automation-driven SaaS and enterprise solutions that help startups, SMEs, NGOs, educational institutes, and large organizations streamline operations, enhance digital visibility, and accelerate growth through modern cloud-native technologies.
274
384
 
275
- | | |
276
- | -------------------- | -------------------------------------------------------------- |
277
- | **Website** | [ccbd.dev](https://ccbd.dev) |
278
- | **GitHub** | [github.com/cybercraftbd](https://github.com/cybercraftbd) |
279
- | **npm Organization** | [npmjs.com/org/power-seo](https://www.npmjs.com/org/power-seo) |
280
- | **Email** | [info@ccbd.dev](mailto:info@ccbd.dev) |
385
+ [![Website](https://img.shields.io/badge/Website-ccbd.dev-blue?style=for-the-badge)](https://ccbd.dev)
386
+ [![GitHub](https://img.shields.io/badge/GitHub-cybercraftbd-black?style=for-the-badge&logo=github)](https://github.com/cybercraftbd)
387
+ [![npm](https://img.shields.io/badge/npm-power--seo-red?style=for-the-badge&logo=npm)](https://www.npmjs.com/org/power-seo)
388
+ [![Email](https://img.shields.io/badge/Email-info@ccbd.dev-green?style=for-the-badge&logo=gmail)](mailto:info@ccbd.dev)
281
389
 
282
390
  © 2026 [CyberCraft Bangladesh](https://ccbd.dev) · Released under the [MIT License](../../LICENSE)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@power-seo/content-analysis",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "Yoast-style SEO content analysis engine with scoring, checks, and React components",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -55,11 +55,26 @@
55
55
  "vitest": "^2.1.0"
56
56
  },
57
57
  "keywords": [
58
- "seo",
59
- "content-analysis",
60
- "scoring",
61
- "react",
62
- "typescript"
58
+ "seo-content-analysis",
59
+ "yoast-seo-alternative",
60
+ "keyword-density-checker",
61
+ "focus-keyphrase",
62
+ "react-seo",
63
+ "nextjs-seo",
64
+ "meta-description-validator",
65
+ "heading-seo-checker",
66
+ "content-quality-gate",
67
+ "headless-cms-seo",
68
+ "programmatic-seo",
69
+ "keyphrase-density",
70
+ "seo-audit",
71
+ "typescript-seo",
72
+ "content-seo-automation",
73
+ "react-editor-seo",
74
+ "ci-seo",
75
+ "edge-runtime-seo",
76
+ "seo-scoring",
77
+ "content-analysis"
63
78
  ],
64
79
  "sideEffects": false,
65
80
  "author": "CyberCraft Bangladesh <info@ccbd.dev>",
@@ -70,5 +85,13 @@
70
85
  },
71
86
  "publishConfig": {
72
87
  "access": "public"
88
+ },
89
+ "bugs": {
90
+ "url": "https://github.com/CyberCraftBD/power-seo/issues"
91
+ },
92
+ "homepage": "https://github.com/CyberCraftBD/power-seo/tree/main/packages/content-analysis#readme",
93
+ "funding": {
94
+ "type": "github",
95
+ "url": "https://github.com/sponsors/cybercraftbd"
73
96
  }
74
97
  }