npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@starstack/strapi-plugin-content-optimizer

v1.0.1

Published

Real-time SEO and readability analysis for Strapi v5. Inline field stats, content validation, and readability checks - live as you type.

Downloads

184

Readme

Content Optimizer - Strapi Plugin

Real-time SEO and readability analysis for Strapi v5. Inline field stats, content validation, and readability checks - all updating live as you type, directly inside the Content Manager.


Features

  • Inline field feedback - character count, word count, and a status indicator injected below the title and description fields
  • Pixel-accurate truncation warnings - uses the Canvas API to measure rendered width the same way Google does, so truncation warnings are reliable rather than character-count approximations
  • Readability analysis - average sentence length, average paragraph length, paragraph density, and longest-sentence callouts
  • Content validation - hard errors for missing or undersized content, warnings for long sentences
  • Context-aware sidebar panel - switches between title stats, description stats, and full content stats depending on which field is active
  • Two-path content extraction - reads Strapi Blocks JSON directly when available; falls back to DOM extraction for unsaved documents

Requirements

| Dependency | Version | | --------------------- | -------- | | Strapi | ^5.0.0 | | React | ^18.0.0 | | @strapi/design-system | ^2.0.0 | | Node.js | ≥18, ≤24 |


Installation

1. Install the package

npm install @starstack/strapi-plugin-content-optimizer

2. Enable the plugin

In config/plugins.ts:

export default {
  "content-optimizer": {
    enabled: true,
  },
};

Or in config/plugins.js:

module.exports = {
  "content-optimizer": {
    enabled: true,
  },
};

3. Rebuild and start

npm run build
npm run develop

Where It Appears

Once installed, two UI elements appear inside any Content Manager edit view:

Inline field stats

Injected directly below the Title and Description fields:

142 characters  |  23 words  |  Optimal ●
┌─────────────────────────────────────────┐
│ ✅ Optimal                              │
└─────────────────────────────────────────┘

Right sidebar panel

A Content Statistics panel in the right sidebar that switches context based on the active field:

  • Title / Description active → shows character count, word count, reading time
  • Content editor active → shows word count (colour-coded), sentence count, paragraph count, and reading time.

How Content Is Extracted

The plugin uses a two-path extraction strategy for Strapi Blocks fields:

Path 1 - Blocks JSON (preferred): Reads the structured JSON from unstable_useContentManagerContext directly. Accurate for saved and unsaved content.

Path 2 - DOM fallback: Walks the live Slate editor DOM when JSON is unavailable. Uses a leaf-block filter to avoid double-counting Slate's nested <li><p> structure.

Content is classified into three buckets:

  • headingBlocks (h1–h6) - contribute to word count only
  • paragraphBlocks (p, blockquote) - used for paragraph metrics and sentence metrics
  • listBlocks (li) - used for word count and sentence metrics, not paragraph count

Field Detection

Fields are located by querying the live DOM in priority order:

Title:

  1. [data-strapi-field="title"] input
  2. input[name="title"]
  3. Label-text match for "meta title"

Description:

  1. [data-strapi-field="metaDescription"] textarea
  2. [data-strapi-field="description"] textarea
  3. textarea[name="metaDescription"]
  4. textarea[name="description"]
  5. Label-text match for "meta description"

Content editors:

  1. All [data-strapi-field] wrappers with a contenteditable child, excluding known SEO fields
  2. Any remaining contenteditable elements not under a [data-strapi-field] wrapper (covers dynamic zones)

Known Limitations

  • Uses unstable_useContentManagerContext - this is an internal Strapi API marked unstable. It works across current Strapi 5.x releases but may require an update on future Strapi versions.
  • Inline stats are injected via DOM manipulation (not React portals) to work reliably across Strapi's CSS grid layout. This means they are not rendered by React and won't appear in server-side renders.
  • Field name detection is heuristic-based. Custom field names that don't match the standard patterns (title, description, metaDescription) may require the Strapi data-strapi-field attribute to be present.

License

MIT © Starstack