Description
Your AI content strategist for WordPress. Content Performance Analyzer finds the pages that are quietly losing traffic, rankings, or conversions — and tells you exactly how to fix each one. It connects your Google Analytics 4 (GA4) and Google Search Console accounts, joins that data with the actual content of each page, and lets AI turn it into specific, page-level recommendations — so you spend your time refreshing content that matters instead of digging through spreadsheets.
Everything needed to find problems and get clear recommendations is free, with no URL limits. Bring an OpenAI, Groq, or Gemini key for free page-level AI recommendations. The optional Pro plan adds hosted AI with no provider key, ready-to-use draft assets, and full WordPress draft writing.
Every scan checks each page for three common problems:
- Content decay — pages that used to rank and are now losing traffic. Refreshing an old post is far cheaper than writing a new one, and these are the fastest wins.
- SEO opportunities — pages with strong impressions but weak click-through or ranking, where a title or heading change has outsized impact.
- Conversion gaps — pages getting real traffic but few conversions, often just missing a clear call to action.
For each flagged page, the built-in AI analysis writes a specific recommendation you can act on — not generic advice. Add an optional Serper API key and it also compares your page against the pages currently ranking for your keyword, so you can see what top results cover that you don’t. It also maps the likely information branches behind each page’s main search — the query fan-out that AI Mode and AI Overviews run — and marks each branch covered, buried, or missing.
This plugin is a strong fit for blogs, resource libraries, and content-heavy sites with dozens to a few hundred posts, and for freelancers or agencies managing content for clients.
What You Get
- AEO readiness score — every page rated 0-100 on a structural readiness checklist for AI search (question headings, direct answers, schema, dates), with each failed check named
- Question gaps — real Search Console queries you rank for that no heading on the page answers, plus one-click AI answer blocks with FAQ schema
- Coverage map — the likely information branches behind a page’s main search intent, built from real Search Console queries, People Also Ask questions, and the headings of the pages that rank, each marked covered, buried, or missing on your page with the one action to take. Google does not publish the exact sub-queries, so every branch is labeled an estimate
- AI referral tracking — see which pages get visitors from ChatGPT, Perplexity, Copilot, and Gemini
- llms.txt — optional machine-readable site guide for AI crawlers, generated from your analyzed pages
- One-click Google connection — connect Analytics and Search Console with a single sign-in, then pick your property and site from dropdowns. No Google Cloud setup required
- One-click page import — load every published page and post from your site with checkboxes, instead of pasting URLs
- Works before any setup — content-only mode checks pages for missing alt text, thin content, and heading problems with zero credentials
- Performance flagging — every page automatically labeled for decay, SEO opportunity, or conversion gap
- AI content recommendations — specific, page-level refresh guidance powered by OpenAI, Groq, or Google Gemini (free tier)
- AI alt text fixes — lists the exact images missing alt text and writes and applies alt text for you, using image recognition
- Competitor gap analysis — optional Serper integration compares your content against top-ranking pages
- GA4 conversion tracking — uses your GA4 key events by default, with support for custom conversion events like demo or trial signups
- Keyword insights — shows the primary keyword each page ranks for, pulled from Search Console
- Recovery tracking — mark a page as fixed and the plugin watches it for 28-60 days, then tells you whether the fix worked: recovered, improving, or no lift
- One-click refresh drafts — create a draft copy of any flagged page with its fix plan embedded at the top, so a refresh starts in the editor, not in a spreadsheet
- Dashboard widget — your top priority pages and fix results, right on the WordPress dashboard
- Freshness at a glance — published date, last WordPress edit, the last meaningful content change the plugin detected (with or without WordPress revisions), and a refresh-due status on every page
- AI crawler rules — allow or block each AI crawler in robots.txt from a checklist, with a recommended preset that welcomes AI search engines and turns away training-only crawlers
- IndexNow — tells Bing, Yandex, Seznam, Naver, and Yep the moment you publish, update, or unpublish a page, instead of waiting for the next crawl
- Smart interlinking — safe, AI-suggested internal links inserted only on exact anchor matches
- PageSpeed Insights without a key — Core Web Vitals and performance scores through the free hosted service, or your own API key if you prefer
- Background processing — analyzes hundreds of URLs in batches without timeouts, with live progress
- CSV export — download the full insights table for reporting or further analysis
Optional Pro Workflow
Pro does not lock the audit or diagnosis. It removes setup and writing work:
- Hosted AI with no provider key — recommendations work immediately after license activation
- 200 included AI generations per month — the latest remaining allowance is visible in the page-plan modal
- Competitor gap analysis with no Serper key — 600 included searches a month compare your pages against what currently ranks
- Ready-to-use draft assets — finished titles, meta descriptions, question headings, FAQ answers, quotable passages, and evidence-based internal-link suggestions
- Smart relevance and verification notes — only justified assets are generated, and missing or unverified facts are called out for review
- Full draft writing — creates a separate 600–900 word WordPress draft for editorial review; the live page is not changed
- One-click apply — writes the suggested title and meta description straight into Rank Math, Yoast SEO, or SEOPress, with undo
- Evidence audit and section drafts — the claims on a page that need backing, each with what would support it; 40–90 word draft sections for the branches your page misses; and a copyable writer brief that says what to keep, add, restructure, link, or split out
- Bring your own assistant (MCP) — connect Claude Code, Cursor or Claude Desktop to your site’s audit over the Model Context Protocol; your assistant reads the diagnosis, writes the fix plan or draft assets, and saves them back — on your own subscription, with no API key and no hosted-AI usage
Nothing here requires a Google Cloud project. The Google connection and PageSpeed both run through a free hosted service, so setup is a single sign-in. If you would rather run everything yourself, every hosted convenience has a self-hosted alternative: add your own PageSpeed or AI API key in Settings, and enable the cpanalyzer_show_byo_oauth_fields filter to use your own Google OAuth client.
External Services
This plugin connects to the external services below. The full privacy policy — covering the plugin and auth.cpanalyzer.com, data handling, security, and deletion requests — is at https://cpanalyzer.com/privacy.
1. Content Performance Analyzer Hosted Service (auth.cpanalyzer.com)
What it does: The plugin author’s own service. It holds the Google OAuth client so you do not need a Google Cloud project, runs PageSpeed lookups without your own key, and provides the optional hosted AI and competitor search included with a Pro license.
Data sent:
- Registration — your site’s home URL, once, to obtain an installation token
- Google sign-in — the WordPress admin URL to return you to, and the one-time handoff code Google issues
- Token refresh — your Google refresh token, forwarded to Google for a new access token
- PageSpeed — the URL being analyzed, mobile/desktop strategy, and your installation token
- Hosted AI (Pro) — your installation token and license key, plus the page URL, performance metrics, search queries, content structure, and page-text excerpts described in section 5. No site visitor personal data is sent
- Competitor search (Pro) — your installation token and license key, plus the page’s primary keyword, forwarded to Serper.dev (section 6) when no personal Serper key is saved
What is stored: Your Google tokens live in your own WordPress database, not on the service. A one-time sign-in handoff entry expires after five minutes. For hosted AI and competitor search, the service stores request counts only — no prompts, page content, metrics, queries, or generated output are retained.
When: On „Connect with Google,” token refresh, keyless PageSpeed analysis, and Pro hosted AI or competitor search.
How to avoid it entirely: Enable the cpanalyzer_show_byo_oauth_fields filter and supply your own Google OAuth client, add your own PageSpeed API key, and use OpenAI, Groq, or Gemini with your own key. The plugin then talks to those providers directly and never uses this service.
Service URL: https://auth.cpanalyzer.com (endpoints: /auth/start, /api/v1/register, /token/exchange, /token/refresh, /api/v1/pagespeed, /api/v1/ai/chat/completions, /api/v1/serper)
Terms: https://cpanalyzer.com/terms — Privacy: https://cpanalyzer.com/privacy
2. Google Analytics 4
What it does: Retrieves traffic and engagement metrics for your pages, and lists your GA4 properties for the settings dropdown.
Data sent: Your GA4 property ID, date ranges, requested URL paths and metrics, and any custom conversion event names, authenticated with an OAuth 2.0 access token — obtained through the hosted service above by default, or directly from Google if you supply your own OAuth client.
When: Manual data collection, the scheduled daily refresh, or URL uploads.
Service URLs: https://analyticsdata.googleapis.com/, https://analyticsadmin.googleapis.com/, https://accounts.google.com/o/oauth2/v2/auth, https://oauth2.googleapis.com/, https://www.googleapis.com/oauth2/v3/tokeninfo
Terms: https://marketingplatform.google.com/about/analytics/terms/ — Privacy: https://policies.google.com/privacy
3. Google Search Console
What it does: Retrieves clicks, impressions, CTR, average position, and search queries for your verified site, and lists your sites for the settings dropdown.
Data sent: Your verified site URL, date ranges, and performance queries, with the same OAuth token as GA4.
When: Manual data collection, the scheduled daily refresh, or URL uploads.
Service URLs: https://searchconsole.googleapis.com/, https://www.googleapis.com/webmasters/v3/sites
Terms: https://support.google.com/webmasters/answer/4559176 — Privacy: https://policies.google.com/privacy
4. Google PageSpeed Insights (Optional)
What it does: Fetches performance scores and Core Web Vitals for specific URLs. Off by default.
Data sent: The URL being analyzed and the mobile/desktop strategy. By default the request rides the hosted relay (section 1), which supplies the API key; add your own key in Settings and the plugin calls Google directly instead.
When: Only when you enable PageSpeed analysis and trigger it.
Service URLs: https://www.googleapis.com/pagespeedonline/v5/runPagespeed (own key), https://auth.cpanalyzer.com/api/v1/pagespeed (default relay)
Terms: https://developers.google.com/terms — Privacy: https://policies.google.com/privacy
5. AI Providers — OpenAI, Groq, or Google Gemini (Optional)
What it does: Generates content recommendations, answer blocks, alt text, and interlinking suggestions from your performance data and page content. You choose one provider and supply its key; without a key, no AI requests are made and the plugin runs in content-check-only mode.
Data sent: Page URLs, performance metrics (traffic, engagement, search queries and rankings), content structure, excerpts of your page text, and up to a few thousand characters of post text for Smart Interlinking. For AI alt text, the image itself is sent for recognition (OpenAI and Gemini only). Your API key is sent with each request. No site visitor data is ever sent.
When: AI analysis of flagged pages (manual, batch, or the background queue), Smart Interlinking, answer blocks, and alt text generation.
Included AI service (Pro): With a Pro license you can select „Content Performance AI” instead of supplying a key. Requests go to https://auth.cpanalyzer.com/api/v1/ai/chat/completions, a relay run by the plugin author, which authenticates the request, counts it against your monthly allowance, and forwards it to Kimi K3, an open-weight model the plugin author deploys and runs on Modal, a serverless compute platform, in the United States. Modal supplies servers only; no AI company receives the data. The relay never receives your Google credentials or license key, stores request counts only, and nothing sent is used by the plugin author to train any model. If a request cannot be answered, it fails and is not sent to any other provider. Modal terms: https://modal.com/legal/terms — privacy: https://modal.com/legal/privacy
Service URLs: https://api.openai.com/v1/chat/completions, https://api.groq.com/openai/v1/chat/completions, https://generativelanguage.googleapis.com/v1beta/openai/chat/completions, and for the included Pro service https://auth.cpanalyzer.com/api/v1/ai/chat/completions (relay) the plugin author’s Modal deployment
Terms and privacy: OpenAI https://openai.com/policies/terms-of-use and https://openai.com/policies/privacy-policy — Groq https://groq.com/terms/ and https://groq.com/privacy-policy/ — Gemini https://ai.google.dev/gemini-api/terms and https://policies.google.com/privacy
6. Serper.dev (Optional)
What it does: Retrieves the top Google results for your page’s primary keyword so the plugin can compare your content against ranking competitors, then fetches the public HTML of those competitor pages to extract headings and structure.
Data sent: The search keyword derived for your page, with your Serper API key — or through the hosted relay on Pro.
When: Only when a Serper key is saved, or an active Pro license uses the included service. Otherwise no Serper requests or competitor fetches are made.
Included with Pro: With no personal key saved, searches are relayed through https://auth.cpanalyzer.com/api/v1/serper using the author’s Serper account — 600 searches per license per month. The relay forwards only the query, result count, country, and language, and stores request counts only. A personal key always takes precedence and bypasses the relay entirely.
Service URL: https://google.serper.dev/search — Terms: https://serper.dev/terms — Privacy: https://serper.dev/privacy
7. IndexNow (Optional)
What it does: Notifies participating search engines that one of your pages was published, updated, or unpublished, so they can recrawl it without waiting. One submission to api.indexnow.org is relayed to Bing, Yandex, Seznam, Naver, and Yep. Google does not participate in IndexNow.
Data sent: The URL of the page that changed, your site’s host name, and the IndexNow key the plugin generated for your site, together with the public address of that key’s verification file. No page content, metrics, or visitor data is sent.
When: Only when the IndexNow setting is on, and only as a page is published, updated, or unpublished. Nothing is sent from staging or local sites, or while Settings, Reading discourages search engines. Repeat changes to the same URL are held for ten minutes so one edit session sends one notification.
Service URL: https://api.indexnow.org/indexnow — About: https://www.indexnow.org/ — Terms: https://www.bing.com/indexnow
Important Notes
- All communication uses HTTPS. No data is sent without your configuration and action, and no site visitor personal data is ever transmitted to any of these services
- Every hosted convenience has a self-hosted alternative: your own Google OAuth client, PageSpeed key, AI provider key, and Serper key
- Disable any optional service and the plugin still performs content checks
Screenshots







Installation
- Install and activate the plugin through the ‚Plugins’ screen in WordPress
- Go to Content Insights URL Management and click „Load Pages From Your Site” to import your pages, then start a scan — the content check works with no setup at all
- To add traffic data, go to Content Insights Settings and click „Connect with Google,” then pick your GA4 property and Search Console site from the dropdowns
- Optional: add an OpenAI, Groq, or Google Gemini API key for AI recommendations, and toggle on PageSpeed analysis (no key needed)
FAQ
-
Can I use my own Claude or ChatGPT subscription instead of an API key?
-
Yes, with Pro. Turn on the MCP endpoint in Settings, create a token, and point your assistant at it: Claude Code, Cursor and Claude Desktop (through the mcp-remote bridge) all connect today. Your assistant reads the same audit the dashboard shows — the page list, the diagnosis and its evidence, the content analysis — and writes the fix plan, the coverage map or the draft assets on your own subscription, so it costs no hosted generations. Writing back is opt-in twice over: the site needs „Allow write tools” turned on and the token needs the write scope, or the connection stays read-only. The endpoint requires HTTPS and is off until you turn it on. claude.ai web connectors and ChatGPT need OAuth sign-in, which arrives in a later release.
-
Does the coverage map show Google’s real fan-out queries?
-
No. Google does not publish them. The map estimates them from the real searches your page appears for in Search Console, People Also Ask questions, and the headings of the pages that currently rank, and labels every branch an estimate.
-
Do I need a Google Cloud project or API keys to start?
-
No. Click „Connect with Google,” sign in, and pick your GA4 property and Search Console site from dropdowns. There is no Cloud Console setup, no OAuth client to create, and no PageSpeed key to obtain. You can also run the content check with no credentials at all.
-
Is it really free?
-
The complete audit and recommendation workflow is free, with no URL limits: Google data, decay diagnosis, SEO and conversion flags, AEO checks, question gaps, exports, recovery tracking, and page-level AI recommendations with your own OpenAI, Groq, or Gemini key. Pro is optional and adds hosted AI with no provider key, ready-to-use draft assets, and complete draft writing.
-
Do I need to pay for AI?
-
Not necessarily. Groq and Google Gemini offer free tiers that handle typical sites, and Groq is the recommended free provider based on output-quality testing. OpenAI is another BYOK option. Pro includes hosted AI if you do not want a provider account or key. Without any AI key or Pro license, the plugin still imports traffic data, flags decaying pages, diagnoses why they dropped, and runs every content check — you just do not get the AI-written output.
-
What is content decay?
-
Content decay is when a page that used to perform well gradually loses traffic and rankings, usually without anything visibly breaking. It is the most common reason older posts quietly stop earning traffic, and refreshing a decayed page is typically far cheaper than writing a new one. This plugin finds those pages and classifies why each one dropped — ranking slide, zero-click capture, falling demand, a self-inflicted edit, or a drop that was never about search at all.
-
Does this work alongside Google Site Kit?
-
Yes, and they do different jobs. Site Kit reports your GA4 and Search Console numbers. This plugin joins those numbers to the actual content of each page, works out which pages are losing ground and why, and writes a specific fix for each. Running both is fine — they do not conflict, and each maintains its own Google connection.
-
What data leaves my site?
-
Page URLs, performance metrics, content structure, and excerpts of page text go to the BYOK AI provider you configure, or to the hosted service when an active Pro user selects hosted AI. Your site URL and PageSpeed test URLs also go to the hosted service for the no-key Google connection and PageSpeed relay. No site visitor personal data is transmitted. The External Services section documents each endpoint and payload category.
-
How long does analysis take for large sites?
-
Most sites see AI suggestions within roughly 6 to 40 minutes for 200 URLs, depending on your AI provider’s rate limits. Progress is shown live and refreshes automatically. If a run hits provider rate limits, the remaining pages fill in on their own in the background, roughly one page every couple of minutes.
-
Does this plugin slow down my site?
-
No. All heavy processing runs asynchronously in the background through WordPress cron, so visitors are unaffected.
-
It is built for it. Work is processed in small batches with dynamic timeout prediction and a safety buffer, and processing continues even if you close the browser. Very restrictive hosts can still interrupt a batch — if that happens, the next scheduled run picks up where it stopped.
-
Can I use this on multisite?
-
Yes, the plugin is multisite compatible.
-
How do I access the plugin settings after activation?
-
After activation you will see „View Insights” and „Settings” links directly on the WordPress plugins page, or navigate to Content Insights in your admin menu.
Reviews
There are no reviews for this plugin.
Contributors & Developers
“Content Performance Analyzer – GA4 & Search Console Content Audit” is open source software. The following people have contributed to this plugin.
ContributorsTranslate “Content Performance Analyzer – GA4 & Search Console Content Audit” into your language.
Interested in development?
Browse the code, check out the SVN repository, or subscribe to the development log by RSS.
Changelog
1.9.1
- Coverage labels match their evidence: Covered (an exact phrase, or a heading an AI verdict named), Likely covered (every meaningful word matched a heading), Mentioned in text, and No heading found. The summary reads „3 covered (1 exact), 9 mentioned, 2 not found”, and the dashboard badge counts only exact matches
- A sibling page appears, and turns the advice into a link, only when it also ranks for one of the branch’s queries, the query is not only brand words, and the page earns clicks on it. It is shown as „Also ranks for”, never as already covering the branch
- A „What is …” H1 can answer a definition branch
- With an AI key, the branch call also returns a verdict per branch; a verdict whose heading the page does not have is rejected and the rules verdict stands. Each branch shows whether AI or the rules judged it, and flags a covered-vs-missing disagreement as disputed. A connected assistant can send verdicts through save_coverage_map under the same check
- Competitor search never counts the site’s own pages, even when called with a bare path, and cached results are filtered on read; caches from before 1.8.9 are cleared on update
- The plan-date line names the site’s timezone
1.9.0
- Sibling pages come from Search Console: a page that ranks for one of a branch’s own queries is its sibling, the most clicks winning. The title fallback now needs every specific label word, never matches on one word, and never picks a product page for an article branch. Each sibling says why (shared query or title) in the coverage table, the writer brief and the connected assistant
- Covered verdicts take an exact phrase first, compare words on light stems (detect/detecting, policy/policies), use each heading for one branch only, and need a real definition heading for „X definition” and „what is X” branches. Each covered branch says whether a phrase or its words matched
- Call-to-action headings inside articles („Future-proof your workforce …”, „Get started today”) no longer count as sections, on new scans and on stored pages (filter: cpanalyzer_cta_patterns)
- Title variations keep only the year, brand-position and trimmed forms; a trimmed title cuts at a colon, comma, dash or bar or not at all, and „vs.”, „vs” and „v.” are written „vs.”
- Search Console query text is cleaned once (trailing punctuation and parentheticals dropped, the raw text kept). Primary keywords go to the most-clicked relevant query, and a brand-only query stays with the page that ranks best for it
- A page whose impressions halved at a steady position reads demand decay, not zero-click
- Cannibalization also reads each page’s stored query rows, so two pages sharing a query at 50 or more impressions each, or three smaller ones, list each other
1.8.9
- The scraper reads section headings and page text from the article itself: notice bars, chat modals, tables of contents, related-article cards and calls to action are left out, and everything from a „What to read next” style heading on is dropped. Stored page text grows from 5,000 to 12,000 characters (filters: cpanalyzer_chrome_markers, cpanalyzer_tail_markers)
- Coverage maps ignore headings that are another page’s title, read up to 120 headings, and are re-checked in the background after the update. Stored pages are cleaned without a rescan
- A sibling page needs the branch’s words in its title or H1, not one shared word
- A question branch is covered only by a question or definition heading, and a one-word branch only by a short heading
- Keyword selection skips version-number, overlong and language-tail queries, brand-only queries on pages that do not own the brand, and queries past position 30 when closer ones exist; it prefers the whole phrase over a truncated one and needs a word from the title or H1. Coverage maps use the 90-day queries when the 30-day rows are empty
- Title variations keep acronyms and the page’s own spelling (ADA, TimeClock), write „vs.”, skip question forms that read wrong, and never exceed 70 characters
- Search Console keyword recovery continues across runs from where it stopped (50 pages per run by default) until every page missing queries has been tried
- A page whose impressions fell by half from 1,000 or more is no longer called low volume because its clicks were few
- The fix-plan tool schema states each text field’s length limit; competitor search skips the site’s own brand domains, login and error pages, and pages under 200 words; the details panel shows when the plan was written and which timezone it uses
1.8.8
- The refresh brief sends the page’s top 10 Search Console queries with every column, its stored coverage map, cached competitor headings for its primary keyword, and a structured page excerpt (title, headings, intro, question answers, close) in place of the first 1,500 characters. A competitor gap claimed with no competitor data is removed
- Fix plans send 10 Search Console queries per page instead of 5
- GA4 reads the same 30 complete days as Search Console, ending at the same lag date, for views, engagement, conversions and the previous period
- Search Console keyword recovery is capped at 25 pages per scan by default (filter: cpanalyzer_gsc_keyword_recovery_limit, 0 lifts the cap)
- Every AI payload and the connected assistant’s page output carry an evidence block: queries sent against queries stored, page text sent against stored, competitor pages analyzed against attempted, where search data came from, and how the freshness date is known
- Deterministic title variations (year, brand last, trimmed; the keyword-first and question forms were retired in 1.9.0) appear in the details panel, the connected assistant’s page output, and Pro draft assets
- Pro draft assets now send each Search Console query’s text; it was sent empty
1.8.7
- Coverage maps use word boundaries, ignore site-wide heading words for sibling suggestions, and require one heading to answer a branch before marking it covered. Existing maps refresh in the background.
- Primary keywords skip operator queries and unrelated Search Console terms. Coverage inputs label title fallbacks and do not search competitors with them.
- Coverage inputs merge up to 100 longer-window queries with sync queries; inbound links include rendered content links.
- MCP output explains why page impressions exceed listed queries and shows local dates alongside UTC dates.
- Scraped and stored titles, descriptions and headings decode HTML entities. Existing stored content is updated without a rescan.
1.8.6
- Sites in a subdirectory (a subdirectory multisite subsite, or WordPress installed under a folder) now resolve analyzed URLs to their posts: the site folder was being added twice, so every per-page feature reported no post there. Root-domain sites are unaffected
1.8.5
- Durable freshness: the plugin keeps its own per-page record of meaningful content changes, compared on every save of a tracked page, so revisions are optional evidence instead of a requirement. Cleaning revisions or deleting the history cache can no longer erase a detected refresh
- A meaningful change is measured, not guessed: formatting, block markup, punctuation, link targets, tracking parameters, a title edit or one changed year never count; several rewritten paragraphs, a new section, a material expansion, replaced statistics, or small edits that add up do. A lone revision with nothing to compare against is no longer treated as proof of a change
- Pages with no change on record get a baseline estimated from the last WordPress edit (or the publish date), frozen when the record is created, so later minor saves no longer keep pushing the refresh date back. Every place that shows freshness – the table, the details panel, the dashboard widget, the CSV export, AI fix plans and the connected assistant – says whether the date was detected, confirmed by you, or estimated
- The details panel now shows the publish date, the last WordPress edit, the last meaningful refresh (or „Unknown”), and the freshness baseline as separate facts, with revision and change-detection coverage
- New „I refreshed the content” control in the details panel records a manually confirmed refresh, shown as such and reversible. Mark fixed keeps its recovery tracking but no longer resets the refresh clock; existing Mark fixed entries keep their recovery verdicts and are not treated as content refreshes
- Freshness safeguards: paragraph splitting and source-line reflow do not count as rewrites; partial content cannot verify a whole-page refresh; the first small edit remains in cumulative comparisons; two saves of the same page landing at once can no longer leave the record describing the older version
- AI plans generated before the freshness upgrade are marked expired without deleting their content or starting automatic regeneration
- Status and the next due date now come from the same calendar: a page baselined on March 1 with a six-month cycle is due on September 1, not already due on August 30
- What to do now follows the diagnosis: a recent drop says monitor and recheck, an unconfirmed drop says find the cause first, a zero-click page is about winning back the click, demand decay says check demand before deciding, and a page that changed recently is checked before another rewrite. The same rules reach AI fix plans and the fallback text
- A plain save inside a traffic drop is no longer described as an edit; only a detected content change is. A technical diagnosis still mentions the last save, labeled as a save
- CSV export: eight columns appended (last WordPress edit, last meaningful refresh, refresh evidence, manual confirmation, freshness baseline and its source, next due date, change-detection coverage). Existing columns are unchanged
- For page builders that keep text outside the editor, the panel reports limited coverage instead of claiming a verified refresh; the cpanalyzer_freshness_content and cpanalyzer_freshness_coverage filters let a site supply that text
1.8.4
- Every heading on a page now reaches a connected assistant as the heading itself. They arrived as the word „Array”, so a plan written outside the site was working from a page that appeared to have no headings at all
- A fix plan saved by a connected assistant can now carry the rest of what the site’s own generator stores – the kind of work, the expected click-through and conversion change, how to measure it, a confidence and an estimate in hours – instead of dropping them on every save. The opportunity score stays the plugin’s own arithmetic, whatever a plan sends
- Coverage maps stored before this release are recomputed in the background after updating, ten at a time: branch impressions, the „link to this page instead” suggestions, the covered, buried and missing verdicts, and the action each branch earns all catch up with the current rules, from data already on the site – no AI call and no competitor search
1.8.3
- A fix plan saved without an action title is now filed under an instruction written from the page’s own diagnosis – „Refresh the content to recover rankings for hourly time tracking” – instead of the first sentence of the summary, which was usually the diagnosis restated and read as a quote
- A derived content priority now counts the clicks a page is leaving on the table, not only its decay: a page holding position 5 on 20,000 impressions at a 1% click-through rate comes back high priority even with nothing wrong with it, and the same number is available to a connected assistant as opportunity_clicks
- A Search Console query needs one click, or ten impressions, before it can be picked as a page’s keyword automatically. On a page where every query has zero clicks, a two-impression misspelling used to win the column; now it stays blank until there is something real to put in it
- The „link to this page instead” suggestion on the coverage map now needs genuine overlap: two of the branch’s words in the other page’s headings and at least 60 per cent of them, a heading carrying the search word for word beats a loose match, and words every page shares – software, tool, platform, guide – no longer count as overlap at all
1.8.2
- A fix plan saved by a connected assistant can send its own action title, content priority and primary keyword, and each is stored as sent. Omit one and the site derives it from the page’s own data – the title from the first sentence of the summary, the priority from the stored diagnosis, the keyword from the page’s Search Console queries – instead of leaving the previous plan’s label in place
- Coverage branches saved by a connected assistant now carry the Search Console impressions behind their own queries instead of zero, so the branch table and the action each branch earns read from real demand
- One text cleaner for every stored plan, whoever wrote it: „Oracle Time & Labor” keeps its ampersand instead of showing as „&” on screen, and a stray backslash in front of a quote is dropped
- Suggested keywords and technical issues declare their limits and a plan that goes over is refused with a clear message, instead of being cut at 120 characters with no warning. A keyword can now be up to 240 characters, so a long conversational query is kept whole on both paths
- Search-operator searches, percent-encoded strings and bare URLs in Search Console data are no longer treated as keywords, so none of them can become a page’s primary keyword or fill the Keyword column
1.8.1
- Pro MCP: collect_coverage_inputs reads People Also Ask, related searches and competitor headings from the cache only, and reports serp_source (cache, live, not_cached or none); pass fetch: true to spend one hosted search on a cache miss. save_coverage_map never searches. Previously a cache miss on either call ran a live search and spent one of the site’s hosted searches, contrary to the read-tools promise
- Coverage map: when no SERP data was read, per-branch competitor counts are unknown (null) instead of reading as „0 of 0 competitors cover this”; a failed live search is reported the same way
- External Services: the included Pro AI service description now matches the relay — every request is answered by Kimi K3 on the plugin author’s Modal deployment; the AI gateway path described in 1.8.0 was removed because it rejected server-to-server requests
1.8.0
- New Pro feature — Bring your own assistant (MCP): a Model Context Protocol endpoint at /wp-json/cpanalyzer/v1/mcp that lets Claude Code, Cursor or Claude Desktop work directly against this site’s audit on your own AI subscription. Streamable HTTP with JSON responses, stateless, HTTPS only, and off until you enable it in Settings
- Seventeen tools: nine that read (site summary, page list, everything known about one page, the grounding payload, the coverage map and its inputs, cached competitor context, data health, scan status) and eight that write (fix plan, coverage map, draft assets, refresh draft, apply and undo title/meta, mark fixed, start scan)
- Five prompts — fix_plan, coverage_branches, draft_assets, refresh_brief and weekly_review — each carrying the same rules the plugin’s own generator follows, so a client model is held to the same standard; and one resource, the site summary
- Tokens with scopes: create a token per client, read-only or read and write, shown once and never stored. Application Passwords work too. Rate limited to 120 requests a minute per token, with every call logged by tool name, scope and duration
- Writes are opt-in twice: the site setting „Allow write tools” and the token’s write scope. Read tools never touch your pages, competitor context and coverage inputs read the cache unless you explicitly ask for a live search (fetch: true), saving a coverage map never searches, and no MCP call spends a hosted AI generation
- New Settings card with the endpoint URL, the token table and copy-ready snippets for each client
- On WordPress 6.9 and later the same tools also register as core Abilities under the cpanalyzer/ namespace, so the official WordPress MCP adapter and WP-CLI see them
- Internal refactors with no change in behaviour: the fix-plan rules and the draft-asset rules each moved into a single shared getter, and mark-as-fixed, apply/undo title and meta, and scan start are now callable methods behind their existing AJAX handlers
1.7.3
- GA4 and Search Console rows that normalize to the same page path (trailing slash, query string, letter case, http/https, www) are now summed instead of the last row overwriting the others: views, users, clicks and impressions add up, engagement, duration, CTR and position are recomputed as weighted averages. Affects the current and previous 30-day windows in both collectors and the year-over-year windows. Symptom fixed: a busy page showing 12 views and 4 impressions next to hundreds of AI referrals, then being diagnosed as an unconfirmed drop
- The scheduled weekly scan records previous-period clicks, CTR and position for every page, not only for pages that vanished from search — on that path the decay classifier had no Search Console baseline to compare against
- Keyword cannibalization counts each page once per query: several spellings of one URL no longer read as a page competing with itself, and the presence threshold applies to the page’s summed clicks and impressions
- Single-page Search Console lookups (metric and keyword recovery, the demand check, the coverage map’s query pull) and the GA4 metric recovery match every spelling of the page with an anchored regex filter instead of one exact URL, so a site whose canonical URLs end in a slash no longer gets empty results from them
- Year-over-year and cannibalization caches use new keys, so the first scan after the upgrade works from summed rows
1.7.2
- Page age gate: a page published under 30 days ago is „New page — not enough history”, 30–59 days is „Building baseline”; neither is diagnosed or flagged as decay (a total impression collapse still reads as a technical issue at any age)
- Low-volume gate: a drop on fewer than 100 previous views or 10 previous clicks is „Insufficient traffic for decay analysis” with the raw numbers, not a decay call
- Trend gate: when only the latest 28-day click bucket fell and the five before it were flat or growing, the diagnosis is „Recent drop — monitor” (weak, unflagged) instead of decay; three or more declining buckets now confirm a ranking slide
- Search Console windows end on the last fully reported day (3 days ago by default, filter
cpanalyzer_gsc_lag_days) in every pull — current and previous comparison, keywords, recovery, cannibalization, the coverage map’s 90-day query pull, the demand check and the trend buckets — so both windows hold the same number of complete days - The flag column shows the diagnosis („Non-search drop”, „Possible tracking break”) in place of the generic „Decay” badge, and rows with a monitor state show it even when nothing is flagged
- The AI badge reads „AI referrals: N” with a tooltip that says what it counts and what it does not
- The scheduled daily refresh now runs the same decay classifier as the browser scan, with the page’s publish date, and keeps the trend, year-over-year, cannibalization and SERP data the scan attached to each page, so the two paths agree and a refresh never wipes a diagnosis; an impression collapse or a tracking break is judged before the age and volume gates; a measured noindex or foreign canonical overrides the new states; year-over-year windows follow the same lag-aligned dates as the comparison windows
1.7.1
- Conversions that were not measured now stay unknown through the whole AI pipeline: an explicit null is no longer cast to 0 on its way into the payload, the insights rows or the CSV, and a current unmeasured value overrides an older stored count instead of letting it survive the merge
- Pro draft rules: a measured 0% click-through on a page with impressions now counts as weak CTR, so the title and meta description suggestions fire instead of being skipped
- The automatic off-peak full scan runs weekly instead of daily, on the day you choose in Settings (new Off-Peak Day option, default Sunday); changing the day or hour reschedules it immediately, an existing daily event is moved to the weekly slot on the next page load, and the Settings page shows the next scheduled run
1.7.0
- New Coverage tab in the page details: the likely information branches behind a page’s main search, each marked covered, buried, or missing, with an action per branch. Mapping runs only when you click it; nothing changes on your pages. Pro adds an evidence audit, drafted sections, and a writer brief.
- Diagnosis integrity: pages whose search or GA4 traffic fell to zero now keep their previous-period baseline and get diagnosed instead of disappearing; one flag ruleset replaces four (low engagement no longer counts as decay; a page that could not be read never flags as thin); a demand-decay diagnosis is only confirmed when a query-level check agrees, and the consolidation advice is softened; a seasonal call now requires last year’s window to have dropped too; Core Web Vitals show as unknown when unmeasured and are labeled as lab data, with field data when available; the wording-based freshness score is removed; the opportunity score is computed from real CTR units; AEO checks count lists and headings inside the content only and require the answer paragraph to relate to its heading. AEO scores can shift after this update because navigation menus no longer count as lists.
- Follow-up fixes from a second review: a zero row is synthesized only when the current-period result was complete and successful, never from a failed or truncated request; the demand check looks up queries missing from the top rows one by one and never assumes an unchanged ranking; the AI is told to hold consolidation and redirect advice until the diagnosis is confirmed; batch scans count the same conversions as scheduled scans (custom events, GA4 key events, then form_submit) and leave the count unknown when the request fails; a seasonal call also requires this year’s decline to be comparable to last year’s; a Slow real-visitor Core Web Vitals verdict now flags performance, and Max Potential FID is shown under its own name; the SEO flag and the opportunity score share one position-based CTR benchmark; thin content uses the same 120-word allowance for pages with a form or CTA as the AEO length check; the opportunity score is always the plugin’s own arithmetic.
1.6.6
- Groq free provider: openai/gpt-oss-120b stays the default, qwen/qwen3.8-27b replaces llama-3.3-70b-versatile as the only fallback; a model chosen by hand in Settings still wins
- Qwen reasoning is off by default so the model spends its budget on the answer (filter
cpanalyzer_groq_reasoning_effortto change), and any thinking tags that still appear are stripped before the JSON is read - Groq requests get at least 120 seconds so a slow answer does not time out before the fallback gets its turn; the browser scan loop waits up to 3 minutes per chunk to match
- llama-3.3-70b-versatile removed from the model list (an existing manual selection keeps working)
1.6.5
- Pro: the full draft is now a rewrite of the real WordPress post rather than a fresh 600-900 words written from a summary. Each section is rewritten on its own, and every table, image, embed, shortcode, button and column layout is carried across untouched, in its original position
- Pro: a completeness check runs before anything is saved. A draft that drops a heading, misses a numbered section its title promises, or loses a table is refused and reported instead of stored — the AI gets one repair pass first. Length is reported as a warning, not a refusal
- Pro: the AI notice no longer sits in the draft’s content, so it can never become the page’s meta description. It shows as a notice in the editor instead, and the draft excerpt is never left empty
- Pro: new „Publish as replacement” copies the reviewed draft into the live article in place. The URL, publish date, author, categories, featured image and SEO settings stay exactly as they were, the previous content is kept as a WordPress revision, and one click undoes it
- Pro: the draft status line now tells you to click Open draft, instead of relying on a pop-up window that browsers block
- Pro: the direct-answer question heading now lands after the first paragraph, inside the opening hundred words, where search engines and AI answers actually read it
- Pro: a draft that still holds an [add: …] placeholder cannot be published as a replacement, and the completeness check runs again at that moment in case the draft was edited
- Pro: a suggested title no longer stores the ” | Site Name” suffix your SEO plugin or theme already adds
- Drafts written before this update keep the AI notice as their first paragraph, where it could become the meta description. Updating removes it from those drafts automatically, and any published page still carrying it is listed for review rather than edited for you
1.6.4
- Batch scans no longer stop after 20 pages or wait on WordPress cron to continue. The open browser tab drives the run, so a scan finishes in one sitting on hosts where cron never fires
- Data collection and AI fix plans are now two stages: every page gets its GA4, Search Console and on-page data first, in seconds each, and the AI plans for flagged pages are written afterwards. The Insights table fills within minutes instead of after an hour
- The Batch Processing box shows a live progress bar with the stage, the page count, the URL being scanned, and an estimated time left
- GA4 and Search Console data is pulled once per scan and reused for 15 minutes instead of being re-pulled for every batch
- A site with „Discourage search engines from indexing this site” turned on is now reported once as a site setting, rather than giving every page the same „remove the noindex tag” fix plan
- Closing the tab no longer loses the run: background processing continues, more slowly, and picks up where the scan stopped
- The hourly stuck-process cleanup now reads the value the batch actually writes, so an abandoned run clears itself
1.6.3
- When a page’s HTML cannot be downloaded (self-signed certificate, firewall), the plugin now records the failure and its reason instead of storing an empty result that read as 0 words, 0 links, no H1, and no CTAs — the AEO score shows a dash, the AI is told the on-page checks are unavailable, and the row says „Page content not read — rescan”. Rows from earlier scans in that state are marked the same way on update
- On local and development hosts the scraper no longer verifies TLS certificates by default; a saved Verify SSL setting still wins
- Batch scans process several pages per run: the time guard measures the whole run instead of one page, cron runs may use most of PHP’s own limit, rows stuck in progress for ten minutes are released automatically, and the next run is scheduled five seconds later instead of thirty
- Pro: status messages say „Contacting Content Performance AI” instead of the pre-upgrade provider, and the provider option self-heals on the next admin visit
- Pro: writing drafts for a page whose content was never read explains that instead of „The AI returned no usable drafts”; a page that already passes every draft check says so too
1.6.2
- Pro: an active license now routes AI recommendations to the hosted engine as soon as it is activated. Previously the plugin kept calling the provider and key chosen before the upgrade until Settings was saved once, and an expired personal key produced „Invalid API Key” errors on a paid plan
- Pro: when the plan lapses, the provider returns to the key you used before, rather than staying on a hosted engine the site can no longer use
- Pro: hosted AI failures now report one clear reason instead of a per-model list
1.6.1
- The Freshness cell is now a status badge (Fresh, Refresh due soon, Refresh due, Refresh overdue) with one fact line and a View details button. The panel shows when the page was published, its last content update, its last save, how many content updates it has had, the refresh cycle and why it applies, and a single What to do action chosen from the decay type — so a page losing non-search traffic no longer reads as „refresh now, refreshing is pointless”
- The legend explains the four freshness states and the 6/9/12-month cycles
- The AI Action column now says „AI plan expired” when a recommendation is older than its data; the previous „Expired – needs refresh” read as if the page needed refreshing
1.6.0
- Added AI crawler rules: a per-bot allow or block checklist that writes User-agent rules into the WordPress robots.txt, with a recommended preset that allows AI search engines and blocks training-only crawlers, a preview of the exact block, and a warning when a physical robots.txt file means WordPress is not serving it
- Added /llms-full.txt alongside /llms.txt, carrying the same page index plus each page’s text with shortcodes and markup stripped, capped at 60 pages and 3,000 words per page, cached for six hours
- Added IndexNow: publishing, updating, or unpublishing a page notifies api.indexnow.org, which relays to Bing, Yandex, Seznam, Naver, and Yep. Includes a served key file, a test ping, a 10-minute debounce per URL, a skip on non-production sites, and a log of the last 20 pings. Google …
