Title: BinaryPH AI SEO
Author: BinaryPH
Published: <strong>ژون 25, 2025</strong>
Last modified: سپتامبر 30, 2026

---

Search plugins

![](https://ps.w.org/binaryph-ai-seo/assets/banner-772x250.jpg?rev=3317339)

![](https://ps.w.org/binaryph-ai-seo/assets/icon-128x128.png?rev=3317339)

# BinaryPH AI SEO

 By [BinaryPH](https://profiles.wordpress.org/binaryph/)

[Download](https://downloads.wordpress.org/plugin/binaryph-ai-seo.3.0.0.zip)

 * [Details](https://azb.wordpress.org/plugins/binaryph-ai-seo/#description)
 * [Reviews](https://azb.wordpress.org/plugins/binaryph-ai-seo/#reviews)
 *  [Installation](https://azb.wordpress.org/plugins/binaryph-ai-seo/#installation)
 * [Development](https://azb.wordpress.org/plugins/binaryph-ai-seo/#developers)

 [Support](https://wordpress.org/support/plugin/binaryph-ai-seo/)

## Description

BinaryPH AI SEO is a complete, standalone SEO plugin built for non-technical site
owners. Click one button and we set up your site. Click another and we fix every
page that needs attention.

#### What it does

 * **1-Click Optimize.** Fixes missing focus keywords, meta descriptions, SEO titles,
   image alt text, schema, and canonicals across your whole site in one go. Live
   progress, pause/cancel, retry on failure.
 * **Quick Setup with best-default config.** Pick a profile (Blog / WooCommerce /
   News) or hit “Apply best defaults” — sitemap, schema, social tags, daily automation,
   robots.txt all configured for you.
 * **AI focus keywords + search snippets** for posts, pages, and WooCommerce products.
 * **AI-powered image alt text** using vision-capable providers (Gemini, OpenRouter
   vision, Pollinations, Ollama llava).
 * **XML sitemap.** A real sitemap index that scales to large sites — posts, pages,
   products and every public post type, category/tag archives, and featured images
   as image-sitemap entries. Hidden and password-protected content is left out automatically.
 * **Connected schema graph.** Organization (with your social profiles), WebSite,
   WebPage, Article, author Person (job title + profiles), BreadcrumbList, and ProfilePage
   on author archives — plus FAQ, Product, Recipe, Event, JobPosting and LocalBusiness.
 * **Open Graph and Twitter Card** tags on every page type, with a default share
   image fallback.
 * **Robots meta done right.** One merged robots tag through the WordPress API, 
   with full-length snippet permissions (max-snippet:-1) for featured snippets and
   AI Overviews.

#### Built for AI answer engines (AEO / GEO)

 * **llms.txt** — a Markdown guide to your site for ChatGPT, Claude, Perplexity 
   and other AI agents.
 * **Markdown copies** — add .md to any post URL for a clean, noindexed Markdown
   version that AI agents read cheaply and accurately.
 * **AI crawler control** — allow all AI bots, keep AI search but block model training(
   GPTBot, ClaudeBot, Google-Extended, CCBot…), or block them all. Written to robots.
   txt with a Content-Signal line.
 * **IndexNow** — instantly notify Bing (which powers ChatGPT search and Copilot),
   Yandex, Seznam, Naver and Yep when you publish, update or delete.
 * **Answer-first FAQ** — show the FAQ from the SEO box on the page ([bps_faq] or
   automatically), so FAQ schema always matches visible content.
 * **Author expertise** — job title and social profiles on each user profile feed
   the author schema (E-E-A-T).
 * **Per-post meta box** with focus keyword, SEO title, search snippet, canonical,“
   Hide from Google” toggle, and a live SERP preview.
 * **301 redirects + 404 logger.** When pages move, redirect them. We log 404s so
   you can fix them with one click.
 * **robots.txt editor.** No file editing required.
 * **SEO Health Score (0-100)** on the dashboard so you always know where you stand.
 * **Audit log.** Every change tracked, with old  new diffs.
 * **Import from Rank Math, Yoast, AIOSEO.** One-click migration of focus keywords,
   snippets, SEO titles, canonicals, noindex flags, redirects, and 404 logs. Tools
   Import.
 * **Cost tracker + monthly budget cap** for paid AI providers.
 * **AI load balancer + failover.** Enable several providers and calls are spread
   across them (prefer-free-first, round-robin, or fixed priority), failing over
   automatically when one errors or rate-limits.
 * **Web-search context.** Providers with native search (Gemini grounding, Groq 
   compound, OpenRouter web plugin) can ground generations in live results; everyone
   else can use your Brave / Google PSE / custom Mistral-agent search pool.

#### AI providers supported

 * Groq — free tier, key from https://console.groq.com/keys (native web search via
   groq/compound)
 * Google Gemini — free tier, key from https://aistudio.google.com/app/apikey (native
   Google Search grounding)
 * Cerebras — free tier, key from https://cloud.cerebras.ai/
 * Mistral AI — free tier, key from https://console.mistral.ai/api-keys
 * OpenRouter — free models available, key from https://openrouter.ai/keys (native
   web plugin)
 * Pollinations — free tier, key from https://enter.pollinations.ai
 * xAI Grok — paid, key from https://console.x.ai/
 * Ollama — local, no API key needed
 * OpenWebUI — self-hosted, your own instance + key

#### Designed for everyone

 * Plain-language labels everywhere (“Search snippet”, “Hide from Google”) with 
   the technical name in tooltips.
 * Beginner mode by default — power-user fields stay hidden until you ask for them.
 * Dark mode supported. Responsive admin pages.
 * Fully translatable.
 * Encrypted API keys at rest (libsodium).
 * Works alongside Yoast, Rank Math, and All in One SEO if you want — or replace
   them.

#### How it pairs with Yoast / Rank Math / AIOSEO

By default, fresh installs run standalone. If we detect Yoast or Rank Math when 
you activate, we switch to “defer” mode and fill in their fields instead of duplicating.
Pick your preferred mode in Settings  Advanced.

### External Services

This plugin connects to third-party AI APIs to generate SEO content based on the
post, page, product, or image you choose. Requests are made only when you trigger
them or when scheduled automation runs. The default provider is Pollinations; a 
free API key from enter.pollinations.ai is required, and the Setup Wizard links 
you to the signup page. Each provider runs on the user’s own account — the plugin
never proxies, stores, or resells AI usage.

 * Google Gemini — https://ai.google.dev/gemini-api/docs/ — Privacy: https://policies.
   google.com/privacy
 * Groq — https://console.groq.com/docs — Privacy: https://groq.com/privacy-policy
 * Cerebras — https://inference-docs.cerebras.ai/ — Privacy: https://www.cerebras.
   ai/privacy-policy
 * Mistral AI — https://docs.mistral.ai/ — Privacy: https://mistral.ai/terms#privacy-
   policy
 * OpenRouter — https://openrouter.ai/docs — Privacy: https://openrouter.ai/privacy
 * xAI Grok — https://docs.x.ai/ — Privacy: https://x.ai/legal/privacy-policy
 * Pollinations — https://gen.pollinations.ai/ — Get a free key at https://enter.
   pollinations.ai — Privacy: https://pollinations.ai/privacy
 * Ollama (local) — https://ollama.com/ — Runs on your own server.
 * OpenWebUI (self-hosted) — https://openwebui.com/ — Runs on your own server.

IndexNow (opt-in, Settings  AI Visibility): when enabled, the URLs of posts you 
publish, update or delete — and nothing else — are sent to https://api.indexnow.
org/indexnow, which shares them with participating search engines (Bing, Yandex,
Seznam, Naver, Yep). Terms: https://www.indexnow.org/terms — Bing privacy: https://
privacy.microsoft.com/privacystatement

When web-search context is enabled, the plugin can also query these search services
with the post title (never full content): Brave Search API (https://brave.com/search/
api/ — Privacy: https://brave.com/privacy/browser/), Google Custom Search JSON API(
https://developers.google.com/custom-search/v1/overview — Privacy: https://policies.
google.com/privacy), or a Mistral agent you built on your own Mistral account.

## Screenshots

[[

## Installation

 1. Upload the plugin to `/wp-content/plugins/binaryph-ai-seo/`.
 2. Activate. The Setup Wizard opens automatically.
 3. Click **Quick Setup — apply best defaults** for instant configuration.
 4. Click **Optimize my whole site** on the dashboard to fill in everything missing.

## FAQ

### Do I need an API key?

Yes — most providers require one, but several offer free tiers. Pollinations (the
default), Gemini, and OpenRouter all have free tiers; signup takes about 30 seconds.
The Setup Wizard will link you to the right page. Ollama runs locally with no key.

### Does this conflict with Yoast or Rank Math?

No. We detect them on activation and switch to “defer” mode by default — we fill
their fields rather than duplicate. You can change to standalone mode any time.

### Will the optimizer cost money?

If you stay on the free tiers (Groq, Gemini flash, Cerebras, Mistral, OpenRouter“:
free” models, Pollinations) or use Ollama locally, no. The default “prefer free 
first” routing keeps calls on free providers whenever one is available. If you pick
paid providers, set a monthly budget cap (in cents) in Settings  AI & Search (Advanced)
and we will stop before exceeding it.

### Where are my API keys stored?

Encrypted at rest using libsodium (sodium_crypto_secretbox). If your PHP build is
missing libsodium we fall back to plaintext and show an admin notice.

### Google Search Console shows my sitemap as “Success” but 0 discovered pages

That is normal for a few hours after submitting a sitemap index: Google reads the
index first and the child sitemaps it lists afterwards. Versions before 3.0.0 could
also answer child sitemaps with a redirect on sites whose permalinks end in “/”,
which slowed discovery down — update, purge any page cache (LiteSpeed, Cloudflare…),
and resubmit.

### Will blocking AI training bots hide me from ChatGPT or Google?

No. “AI search & assistants only” blocks crawlers that collect training data (GPTBot,
ClaudeBot, Google-Extended, CCBot…) but keeps the ones that power AI search answers(
OAI-SearchBot, Claude-SearchBot, PerplexityBot). Google Search and Bing are never
affected.

### Can I undo a change?

Yes. Every change is recorded in the Audit Log with old and new values.

## Reviews

![](https://secure.gravatar.com/avatar/634c0dd2ccaf72bf5d9c28b9c1d3b6cc56bc6cafe56b627a79ec18f1c63c022e?
s=60&d=retro&r=g)

### 󠀁[I’m the developer](https://wordpress.org/support/topic/im-the-developer/)󠁿

 [BinaryPH](https://profiles.wordpress.org/binaryph/) ژون 28, 2025

It works on my machine

 [ Read all 1 review ](https://wordpress.org/support/plugin/binaryph-ai-seo/reviews/)

## Contributors & Developers

“BinaryPH AI SEO” is open source software. The following people have contributed
to this plugin.

Contributors

 *   [ BinaryPH ](https://profiles.wordpress.org/binaryph/)

[Translate “BinaryPH AI SEO” into your language.](https://translate.wordpress.org/projects/wp-plugins/binaryph-ai-seo)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/binaryph-ai-seo/), 
check out the [SVN repository](https://plugins.svn.wordpress.org/binaryph-ai-seo/),
or subscribe to the [development log](https://plugins.trac.wordpress.org/log/binaryph-ai-seo/)
by [RSS](https://plugins.trac.wordpress.org/log/binaryph-ai-seo/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 3.0.0

SEO for the AI era — sitemap fix, answer-engine features, and a full correctness
audit.

 * Fix: every sitemap URL (/sitemap.xml and each child sitemap) was 301-redirected
   to a trailing-slash variant on sites whose permalinks end in “/” — Search Console
   could report “Success” with 0 discovered pages. Sitemaps now answer 200 directly(
   the slash form is accepted too) and send X-Robots-Tag: noindex.
 * New: taxonomy sitemaps (categories, tags, product categories — empty and hidden
   terms skipped), featured images as image-sitemap entries, the homepage entry 
   for blog-front sites, every public post type included, and a readable browser
   view (/sitemap.xsl).
 * New: AI Visibility settings tab — AI crawler policy for robots.txt (allow all/
   block training only / block all, with a Content-Signal line), IndexNow instant
   indexing (opt-in), and Markdown copies of every post (append .md) for AI agents.
 * New: llms.txt rebuilt to the current llmstxt.org shape — sections per post type,
   topic map, Optional section, SEO descriptions, links to Markdown copies; noindexed
   and password-protected content excluded; HTML entities decoded.
 * New: connected schema graph — WebSite, WebPage, primary ImageObject, author Person(
   with job title and social profiles from the user profile), ProfilePage on author
   archives, Organization sameAs from a new Social profiles setting.
 * New: robots meta through the WordPress wp_robots API — one merged tag (previously
   noindexed pages printed two conflicting robots tags) with max-snippet:-1 / max-
   video-preview:-1 on indexable pages.
 * New: Open Graph/Twitter on author, post-type and term archives; og:locale, article
   times and section, image dimensions, twitter:site from your X profile, and a 
   default share image fallback. Self-referencing canonicals on paginated archives
   and the paged homepage.
 * New: [bps_faq] shortcode and an option to show the SEO-box FAQ on the page. FAQ
   and HowTo schema are now only emitted when that content is visible (markup for
   invisible content violates Google’s structured-data policy). HowTo and Course
   default to off on new installs (Google retired those rich results).
 * Fix: SEO titles and descriptions imported from Yoast (%%title%%), Rank Math (%
   title%) and AIOSEO (#post_title) printed their template variables literally —
   they are now resolved, including on already-imported data.
 * Fix: a static front page’s own SEO title and snippet are now used on the homepage.
 * Fix: “Strip category base” could turn every page, post, robots.txt and sitemap
   URL into a 404 after a rewrite flush (catch-all category rule). It now registers
   explicit per-category rules and 301-redirects old /category/ links.
 * Fix: robots.txt no longer advertises the sitemap of a site set to “Discourage
   search engines”, and the sitemap line now follows site-URL changes ({sitemap}
   placeholder).
 * Fix: cross-domain redirects (same path on a new domain) were blocked by the self-
   loop guard; percent-encoded redirect URLs (non-ASCII slugs) were corrupted on
   save; mixed-case target hosts were rejected.
 * Fix: importers — Rank Math redirections with several sources imported only the
   first, 410/451 rules were dropped, CSV files with a UTF-8 BOM imported their 
   header row as a redirect.
 * Fix: automation candidate queries counted disabled fields, so posts missing only
   a disabled field could block the queue; titles with HTML entities leaked into
   generated keywords and titles.
 * Fix: the monthly budget cap undercounted Gemini spend (outdated prices, thinking
   tokens and search grounding ignored). Default Gemini model is now gemini-flash-
   latest and Ollama’s is gemma3; reasoning models’ think blocks are stripped from
   replies.
 * Fix: dry-run mode no longer swallows manual edits in the SEO box; editors without
   the SEO capability no longer see AI buttons that could only fail; plugin error
   notices are shown only to SEO managers.
 * Improved: block editor — SEO fields registered in the REST API, the snippet preview
   reads the block editor’s title, and suggested slugs apply through the editor.
   The SEO box now appears on every public post type.
 * Improved: PHP 8.4/8.5 compatibility (explicit CSV escape arguments), an upgrade
   lock against concurrent upgrade runs, and many smaller fixes (verification-tag
   paste, JSON-LD field sanitizing, title capitalization, WooCommerce list columns,
   Rank Math/AIOSEO secondary keyphrases preserved, localized image alt text).

#### 2.9.0

Convergence release: scheduled automation now actually finishes the backlog, the
audit log becomes a real tool, and a broad production-hardening pass.

 * New: catch-up mode (on by default) — when a run finishes with work left over,
   the plugin schedules another run ~20 minutes later until the backlog is gone,
   bounded by a new “Daily AI-call limit” (default 50, Settings  Automation). Previously
   one capped daily run could be permanently outpaced by a site that publishes ~
   2 posts/day, so the “items need attention” count only ever grew.
 * New: catch-up runs process oldest content first, so the old backlog can no longer
   be starved forever by a steady stream of new posts.
 * New: the dashboard tells the truth about throughput — a forecast line (“clears
   in ~X days” / “will never clear at this budget”), a Missing SEO title card (it
   was always counted in the headline but had no card, so the cards never summed
   to the total), and a catch-up progress line under Last automation run.
 * New: audit log overhaul — server-side pagination with per-page picker, filters
   by field and source, search by post title, relative timestamps, a per-provider
   AI usage breakdown, and a Clear log button (everything / older than 30 / 90 days;
   admins only). Retention is now configurable (Settings  Advanced) and old entries
   prune automatically.
 * Fix: log pruning (audit, AI calls, 404s) ran only when scheduled automation was
   enabled — with the schedule off, all three tables grew forever. Pruning now runs
   on its own daily maintenance event, always.
 * Fix: the 404 “Clean noise” sweep classified stored rows against the CURRENT request’s
   query string — a request carrying e.g. ?author=1 could mark every logged 404 
   as bot noise and delete the whole log. Stored rows are now judged only on their
   own URL.
 * Fix: redirect lookups no longer cost every front-end pageview 1–2 uncached queries
   on sites with no redirects (cached rule counts short-circuit), and the exact-
   match lookup now uses the source index instead of a full-table BINARY scan.
 * Fix: the Redirects page now follows POST-redirect-GET — refreshing after adding
   or dismissing no longer re-submits the form.
 * Fix: paginated sitemaps advertised the site-wide last-modified date on every 
   page; now only page 1 carries lastmod, and the sitemap index and /llms.txt are
   cached instead of rebuilt on every crawler hit.
 * Fix: editor autosaves no longer wipe the score/orphan/content caches on every
   keystroke (autosave/revision guards on all save_post handlers).
 * Improved: “Optimize my whole site” with AI mode now reports an honest plan (“
   ~N calls needed at up to M/day — done in ~X days”) instead of a vague toast; 
   wording around AI calls vs items corrected throughout.
 * Improved: i18n pass — the redirects page script moved from inline PHP to a proper
   translatable asset, REST error messages are translatable, and the plugin now 
   ships license/domain-path headers per directory guidelines. Removed six dead 
   legacy admin stubs.

#### 2.8.2

Reliability release: fixes the Groq “messages[0].content must be a string” error,
opaque OpenRouter failures, and the ways scheduled automation could silently stop
making progress.

 * Fix: image alt calls no longer send image payloads to text-only models — the 
   vision check now fails closed on unknown models (fetching the provider’s model
   list on demand) instead of assuming capability, and Groq’s qwen3 models are no
   longer mistaken for vision models. This is what produced “groq error: messages[
   0].content must be a string” on every scheduled run.
 * Fix: posts flagged “needs manual attention” during provider outages were permanently
   excluded from automation while still counted as missing on the dashboard. Strikes
   now only count when a provider actually answered, the flag self-expires after
   30 days, filling a field through the plugin clears it, and the upgrade wipes 
   all previously mis-flagged posts so the next run retries them.
 * Fix: orphan pages whose auto-link attempt found or wired nothing were parked 
   as “done” for a week; unproductive attempts now retry daily. The dashboard also
   warns when orphan fixing is on but auto-link is off (or paused by dry-run) — 
   the state where runs cache suggestions forever without ever dropping the count.
 * Fix: AI features that expect JSON (FAQ extraction, AI readability, AI orphan 
   suggestions) were broken on most models — the response cleaner reduced multi-
   line JSON replies to a single brace, which was then cached as a success.
 * Fix: provider error notices no longer appear when a later provider in the failover
   chain succeeded; genuine whole-chain failures now show one notice with the real
   per-provider reasons (including OpenRouter’s upstream provider name and error
   body, previously discarded as “Provider returned error”).
 * Fix: a provider returning HTTP 200 with an empty completion never entered failover
   cooldown and kept winning the first slot of every call; deterministic client 
   errors (400/401/404) now cool down for 30 minutes instead of retrying every 5.
 * Fix: failed image downloads no longer silently degrade a vision request into 
   a text-only “describe this image” prompt — the invented description used to be
   written as real alt text. Downloads are also capped at 5 MB, verified to be images,
   use the “large” rendition instead of the multi-MB original, and are fetched once
   per failover chain instead of once per provider.
 * Fix: slow provider timeouts inside the post loop could spend the whole run’s 
   wall clock so the media alt sweep and orphan pass never executed; AI calls now
   honor the run deadline and the post loop is capped at ~65% of the time budget
   when later passes have work.
 * Fix: cache hits and skipped calls no longer consume the per-run AI call budget;
   snippet/title/alt failures now count strikes like keywords did, instead of re-
   burning budget on the same unfillable post forever.
 * Improved: a dashboard warning now appears when AI features are enabled but scheduled
   automation is off (the state where the AI toggle said “On — every feature uses
   AI on the daily cron” while the cron never ran), and when no provider is enabled
   and configured the run downgrades to heuristic with a clear notice instead of
   failing silently.

#### 2.8.1

Cerebras vision fix.

 * Fix: image alt-text requests routed to Cerebras failed with “Remote image URLs
   are not supported” — images sent to Cerebras are now downloaded and inlined as
   base64 data URIs.
 * Fix: image Content-Type headers with parameters (e.g. `; charset=...`) are stripped
   before building data URIs and Gemini inline payloads, which would otherwise be
   rejected as invalid.

#### 2.8.0

Multi-provider release: AI load balancer + failover, web-search grounding, and automation
reliability fixes.

 * New: Groq, Cerebras, and Mistral AI providers (OpenAI-compatible chat completions,
   free tiers supported).
 * New: AI load balancer + failover — enable any set of providers on the new Settings
   AI & Search tab, order them, and pick a strategy (prefer free first / round-robin/
   fixed priority). Failing providers go on a short cooldown and are retried last;
   429 responses honor Retry-After.
 * New: per-provider model pickers — fetch each provider’s live model list (free
   models sorted first and labeled “(free)”), or type any model id manually. Per-
   provider models replace the single global model that previously only applied 
   to the primary provider.
 * New: web-search context for text generation (keyword, snippet, SEO title — never
   image alt). Native search where the provider supports it: Gemini Google-Search
   grounding, Groq compound systems, OpenRouter web plugin. External search everywhere
   else via a failover pool of Brave Search, Google PSE (existing customers; Google
   retires the API on 2027-01-01 — the UI says so), or your own Mistral Studio web-
   search agent (fetched from your account; CSE-shaped JSON agents parse natively,
   citation output works as fallback). Per-provider search toggle, per-engine daily
   usage counters.
 * Fix: the daily automation’s last-run stats can no longer go stale — the run records
   progress incrementally, a wall-clock guard stops work before host timeouts kill
   the process, and an interrupted run is labeled on the dashboard instead of silently
   showing four-day-old numbers.
 * Fix: the media-library alt sweep and the orphan pass now get guaranteed slices
   of the per-run AI budget — previously the post loop could consume everything 
   and the sweep was skipped entirely, which is why “missing image alt” counts never
   converged in AI mode.
 * Fix: posts whose titles are empty or all stopwords (nothing can be generated 
   from them) are flagged “needs manual attention” after 3 attempts and skipped,
   instead of silently re-burning AI calls every run forever; the dashboard shows
   the count and editing the post retries it.
 * Improved: dashboard shows next-run time and an overdue warning (WP-Cron on low-
   traffic sites), updated model defaults (Gemini 2.5 Flash; xAI grok-4.3 — grok-
   3 was retired), Settings help text now explains the AI-call budget honestly, 
   and the settings/tools tab bar highlights the active tab again.
 * Improved: admin UI responsive pass — provider/engine cards stack on phones and
   in-app webviews, 44px touch targets on reorder controls, wide tables scroll sideways
   instead of blowing out the page.

#### 2.7.1

Plugin Check compliance fixes for the 2.7.0 release.

 * Fix: dry-run staged-changes queries now pass LIKE wildcards through `$wpdb->esc_like()`
   + prepared placeholders instead of interpolating them into the SQL.
 * Fix: translator comments added to all translatable strings with placeholders,
   and confirmation-dialog strings no longer wrap their text in HTML (the markup
   moved to the JS layer).
 * Fix: normalized mixed line endings in `class-bps-assets.php` introduced by the
   2.7.0 i18n merge.

#### 2.7.0

Install-and-forget release: a full audit of the four dashboard features (missing
keyword / snippet / image alt / orphan pages), the automation pipeline, and the 
admin UI.

 * Fix: every AI generation path now falls back to the built-in heuristic in the
   same run when the provider returns nothing (bad key, network failure, empty response,
   budget cap). An unattended site with a broken provider keeps making progress 
   instead of stalling forever — this covers the daily cron (keyword, snippet, SEO
   title, image alt, orphan suggestions), the inline optimizer, the per-post Generate
   buttons, and the FAQ/slug/internal-link helpers. The dashboard’s “Last automation
   run” card reports how many AI calls fell back.
 * Fix: “Missing image alt” can now actually reach zero unattended — the daily automation
   sweeps the whole media library (previously only featured images), AI mode really
   calls the vision provider on featured images, and stored alt text is injected
   into in-content `<img>` tags at render time.
 * Fix: orphan detection counts navigation-menu links as inbound (menu pages were
   false-positive orphans), no longer counts a post’s link to itself, and caches
   URL lookups so rescans are fast. AI link suggestions validate returned post IDs
   against the real candidate list. Orphan suggestion caching now spans a week so
   daily runs work through the whole backlog instead of re-processing the same head
   of the list.
 * Fix: the Optimize picker no longer saves “Skip” for features that merely had 
   nothing to fix that day — a transient zero-count used to permanently disable 
   that feature’s automation for future content. The lazily-loaded orphan count 
   now reaches the picker, the AI toggle no longer silently reverts or overwrites
   per-feature Skip choices, and a mid-run connection hiccup retries instead of 
   stranding the run.
 * Fix: the daily run fires at the configured site-local time (was 03:00 UTC on 
   every non-UTC site). The cron self-heals if its event vanishes, a warning appears
   when WP-Cron is stalled or overdue, presets and settings-import reschedule the
   cron when they change frequency, and the Quick Setup no longer clobbers a just-
   picked profile.
 * New: dry-run mode is now reviewable — staged values are listed in Settings  Advanced
   with Apply / Discard buttons, count as “done” so the cron stops re-billing the
   same posts daily, and orphan auto-link (the one path that still changed the live
   site) is paused while dry-run is on.
 * New: first heuristic fills happen within ~10 minutes of activation (previously
   waited for the first 03:00 run); Settings  “Run now” executes in the background
   instead of timing out the page.
 * New: the setup wizard asks the two questions only the user can answer — orphan
   auto-link consent (it renders a Related: block on the public site) and the optional
   AI key — everything else runs on safe defaults.
 * Improved: AI output is length-clamped at word boundaries (snippets/titles), heuristic
   snippets decode entities and cut on word boundaries, Regenerate bypasses the 
   response cache so a second click gives a fresh suggestion, and saved API keys
   can be removed from the UI.
 * Improved: Content page gained working pagination, an “All content” type filter
   matching the dashboard card counts, and row Generate now fills the snippet as
   well as the keyword.
 * Improved accessibility: modal focus trap + labelled dialogs, accessible names
   on toggle switches and help tips, correct nav semantics on tab bars, and ~120
   admin JS strings are now translatable.
 * Improved security: per-post capability checks on media alt fill and orphan auto-
   link writes, sanitized redirect updates, budget-gated + rate-limited provider
   test calls.
 * Performance: bounded candidate queries, cached 404-rate and readability score
   components (readability is now a real Flesch sample instead of a hard-coded 100%),
   scan cache survives editor autosaves, and plugin CSS no longer bleeds into other
   admin screens.

#### 2.6.8

 * Fix: redirects to external domains actually arrive now. `wp_safe_redirect()` 
   silently rewrote any cross-domain target to wp-admin (sending visitors to the
   login screen, and letting browsers cache that as the 301). The rule’s saved target
   host is whitelisted at redirect time while keeping scheme validation.
 * Fix: Find & Replace regex mode matched nothing. The SQL pre-filter searched for
   the literal pattern text (`colou?r`, `\d{4}`), so no candidate rows ever reached
   the regex engine. Regex mode now scans rows in batches and lets the regex decide;
   an invalid pattern also reports its error in the result panel instead of a silent“
   0 rows touched”.
 * Fix: the dashboard SEO Health Score ring never rendered — the inline boot script
   ran before footer-enqueued core.js defined `window.BPS`. It now defers to DOMContentLoaded.
 * Fix: save/error notices (“Saved.”, “Redirect added.”, “Could not add redirect…”,“
   404 log cleared.”) were queued but never displayed — custom admin pages don’t
   auto-print settings errors. They now render above every plugin page header, so
   a failed redirect add is no longer silent.
 * Fix: pausing 1-Click Optimize was a dead end — nothing ever called the resume
   endpoint. The Pause button now toggles to Resume and restarts the run; both labels
   are translatable.
 * Fix: regex redirect rows imported via CSV using the documented `~...~` shorthand(
   including the placeholder example) were stored as exact matches that could never
   fire. The wrapper is now auto-detected when no match_type column is present.
 * Fix: heuristic internal-link suggestions returned wp-admin _edit_ URLs; the metabox“
   Copy link” button pasted those into post content (broken, login-walled links 
   for visitors). Suggestions now carry the public permalink, matching AI mode.
 * Fix: the auto-redirect created on slug rename assumed a flat `/%postname%/` permalink
   structure — dead redirects for child pages and date/category permalinks. Both
   sides are now derived from the real permalinks.
 * Fix: sitemap `<lastmod>` and Article `datePublished`/`dateModified` carried the
   site’s UTC offset applied to an already-UTC timestamp (wrong by up to ±14 hours).
   Now emitted as true UTC.
 * Fix: Media  bulk alt text now honors Dry-run mode (stages to shadow meta like
   the optimizer/cron instead of writing live), and the completion toast no longer
   claims success when items could not be processed.
 * Fix: Event schema could emit `"image": false` when the post had no featured image(
   Google rejects it) — false values are now dropped, matching the Recipe emitter.
 * Fix: duplicate Product JSON-LD on WooCommerce product pages — WooCommerce core
   already emits one; ours now stands down (filter `bps_schema_product_skip_when_wc`
   to override).
 * Fix: an API key that can no longer be decrypted (salt rotation, migrated DB) 
   was sent to the provider as a literal `bps_enc_v1:` ciphertext Bearer token, 
   producing a misleading “provider rejected your key” error. It’s now treated as
   missing and the existing “re-enter your keys” notice is raised.
 * Fix: uninstall now removes `_bps_*` term meta (term-level SEO fields previously
   survived uninstall) and clears the pending one-shot optimizer cron event on deactivate/
   uninstall.
 * Fix: AIOSEO migration preview counted redirect rows with NULL `enabled` but the
   import skipped them — both paths now agree.
 * Fix: the “Could not add redirect” error message now correctly describes the actual
   constraints (unique source across all match types; homepage/system paths blocked).
 * Tools: tabs whose endpoints require administrator rights (Import, Redirects CSV,
   Find & Replace, Settings export/import) are hidden from users who only hold the`
   bps_manage_seo` capability — their buttons could only ever return 403.
 * Accessibility/contrast: post-list SEO score pills (white on amber was 2.2:1) 
   and the dashboard-widget score (CSS `orange` on white was 2:1) now use darker
   token-aligned colors; form placeholders darkened from 2.6:1 to 4.8:1; success-
   state text nudged to green-800 (the soft-background pairing was a hair under 
   4.5:1); explicit `::selection` colors added so highlighted text stays readable—
   including the llms.txt code preview, where selected text was effectively invisible(
   1.2:1).
 * Fix: a stylesheet that doesn’t ship with the plugin was enqueued on every post-
   edit screen, producing a 404 request per page load — now existence-guarded like
   the other page assets.
 * Fix: importing redirects from Rank Math/AIOSEO could write a homepage (`/`) redirect
   rule directly into the table, bypassing the homepage-lockout guard every other
   entry point honors. Such rows (and rows with no target) are now skipped and counted.
 * Fix: the “has provider” check (dashboard AI toggles) no longer counts an API 
   key that can’t be decrypted as a configured provider.
 * Hardening: optimizer preview modal now HTML-escapes post titles; decrypt failures
   consistently flag the undecryptable-keys admin notice; the external-redirect 
   host whitelist is derived from the rule as stored, so a regex target built from
   back-references can’t be steered to a visitor-controlled domain.

#### 2.6.7

 * Compatibility: tested up to WordPress 7.0. Replaced the deprecated `add_submenu_page(
   null, …)` pattern (hidden Setup wizard + legacy redirect routes) with an empty-
   string parent, eliminating the PHP 8.1+ “passing null to non-nullable” notices
   WordPress core emits for a null parent slug. Hidden-page routing is unchanged.
 * Fix: duplicate `<link rel="canonical">` on every post/page in Standalone mode.
   WordPress core’s own `rel_canonical` was left registered alongside ours, so each
   singular page emitted two canonicals (which disagreed whenever a custom canonical
   was set). Core’s is now removed whenever BinaryPH is the active SEO source — 
   exactly one canonical is output.
 * Fix: term-archive SEO (description, canonical, robots, title) is now gated by
   the same coexistence check as the rest of our front-end output. After migrating
   Yoast/Rank Math term SEO into BinaryPH term meta while still in Defer/Supplement
   mode, category/tag/custom-taxonomy archives no longer emitted a second set of
   tags on top of the third-party plugin’s.
 * Fix: Recipe schema emitted `"image": false` (and empty description/author) when
   a recipe post had no featured image — Google rejects that. Empty/false values
   are now dropped, matching the Event/Course/Product/JobPosting emitters.
 * Fix: Article schema referenced an Organization node (`publisher`) that wasn’t
   output when “organization info for Google” was disabled, leaving a dangling reference
   Google flags. The Organization node is now always present when an Article is 
   emitted.
 * Fix: a regex redirect whose target re-matches its own pattern (e.g. source `~
   ^/p/(.*)$~`, target `/p/$1-x`) caused an infinite redirect loop. Same-site regex
   targets that still match the rule are now refused instead of looping.
 * Fix: the 404 noise filter missed backup/secret-file probes such as `/backup.zip`,`/
   db.sql`, and `/.htaccess` because the logged path carried a trailing slash, defeating
   the `$`-anchored extension patterns. Both the raw and trimmed path are now tested,
   so scanner noise stops polluting the 404 log and SEO score.
 * Fix: custom post type XML sub-sitemaps whose slug contains a hyphen, underscore,
   or digit (e.g. `product_variation`, `my-cpt`) were advertised in the sitemap 
   index but returned an HTML 404 because the rewrite rule only captured `[a-z]+`.
   The capture now allows `[a-z0-9_-]+` (still validated against the registered 
   types).
 * Fix: 1-Click Optimize no longer re-calls the AI provider for orphan-page suggestions
   it already cached when Orphan auto-link is toggled on. The AI’s existing 3–5 
   ranked picks are reused (only the heuristic pool needed the wider re-fetch), 
   avoiding redundant token spend; the reused cache is marked so the orphan stops
   being re-queued.
 * Fix: per-post “Hide from Google” now emits `noindex,follow` instead of `noindex,
   nofollow`, matching the term/archive output and preserving the page’s outbound
   link equity.
 * Fix: `seo_title` is now consistently present in the optimizer feature map across
   settings import, the legacy 2.2.7 upgrade migration, and the cron/asset fallback
   maps (it was silently dropped on those paths, defaulting SEO-title automation
   to off). Settings import also no longer silently re-enables Orphan pages.
 * Content page: the per-row Generate / Apply buttons are hardened against clicks
   landing on inner nodes, and the table/pagination lookups are null-guarded.
 * Sitemap page: the “Open settings” button now scrolls to the XML-sitemap toggle(
   the target anchor previously had no matching element).
 * Coexistence: the duplicate-tag fail-safe now also recognizes SEO plugins BinaryPH
   has no adapter for — SEOPress, The SEO Framework, Slim SEO, SmartCrawl (plus 
   a `bps_detected_foreign_seo_plugin` filter to register others). Running one of
   those in Standalone mode previously slipped past detection and produced duplicate
   canonical/OG/schema tags.
 * Coexistence: BinaryPH no longer serves its own XML sitemap when a third-party
   SEO plugin is active in Standalone/Override mode — it defers to that plugin’s
   sitemap. Fixes a collision with All in One SEO, which also serves /sitemap.xml.
 * Coexistence: the duplicate-tag admin notice is now mode-aware (Override mode 
   shows an informational “this is expected” message instead of an error, names 
   the detected plugin even when it’s one without an adapter, and mentions the sitemap).
   Corrected the misleading `primary()` doc-comment that claimed Override “ignores
   other SEO plugins” — Override in fact writes your values into every active SEO
   plugin’s fields (“write everywhere”) and lets that plugin render them.
 * Housekeeping: full PHP 8.3 lint pass on every touched file.

#### 2.6.6

 * New: Apply button on every orphan-pages suggestion (Tools  Orphans). Click “Find
   similar pages” or “AI suggestions” and each row now has its own **Apply** action
   that wires the source-post  orphan auto-link and (on first use) enables the global
   Orphan auto-link feature. No more guessing whether suggestions were already wired
   or not.
 * New: status banner above each suggestion list — clearly states **✓ Auto-linked
   from N source post(s)** when the server already wired the link during the call,
   or **Auto-link is off — click Apply to enable & wire** when the toggle is disabled.
   The orphan row pill also flips to **✓ wired N** so the table reflects state without
   expanding the row.
 * New: Copy-link button on every AI internal-link suggestion in the post metabox.
   Click it and `<a href="…">anchor</a>` lands on your clipboard, ready to paste
   wherever the anchor text fits naturally in the post body. Editor-agnostic — works
   for Gutenberg, Classic Editor, and page builders.
 * New REST endpoint: `POST /bps/v1/orphans/wire-one` — wires a single source  orphan
   auto-link from the Tools page Apply button. Caps + capability checks honored.

#### 2.6.5

 * Fix: AI suggestions for orphan pages (both the per-row “AI suggestions” button
   and the “AI suggestions for all” bulk action) now actually call the configured
   provider. The helper class was dispatching to a function that never existed (`
   bps_call_ai_provider`), so every AI-driven helper — orphan suggestions, AI FAQ
   extraction, AI slug optimizer, AI readability — silently returned empty. Now 
   routed through the canonical `bps_call_ai()` gateway.
 * Fix: scheduled automation now correctly fills orphan-page AI suggestions when“
   Orphan pages” is set to AI mode (same underlying helper fix — the cron worker
   was hitting the same broken code path).
 * Fix: AI FAQ extraction and AI readability scoring were silently truncating post
   content to 200 characters before sending to the provider (the helper passed a`
   $max = 4000` argument that the underlying `bps_strip_for_prompt()` ignored). `
   bps_strip_for_prompt()` now honors the optional length argument, so AI helpers
   get the intended 4000-character context.
 * Fix: AI slug optimizer was always sending an empty focus-keyword in its prompt
   because it called a non-existent `bps_get_focus_kw()` helper. Now reads the focus
   keyword via the same path the heuristic version uses.
 * Fix: overlapping text/toggle in Settings  Schema, Tracking & Verification, and
   Links. A legacy 36×20px `.bps-switch` rule (used by the per-row Active toggle
   on the Redirects page) was crushing the v2.1 switch component (which carries 
   inline text), causing the label to overlap the track.

#### 2.6.4

 * Performance: Eliminated an N+1 database query storm in the Orphan Detector by
   fetching post content in bulk and caching URL resolutions.
 * Fix: Resolved an infinite retry loop in the 1-Click Optimizer where unfixable
   orphan pages would permanently stall the queue.
 * Fix: Protected core WordPress system paths (e.g. /wp-admin/, /wp-login.php, /
   wp-json/) from being accidentally redirected or logged as 404 noise.
 * Fix: Corrected an undefined variable warning in the background cron worker.
 * Enhancement: Explicit UI toggles added for granular Settings  Automation control.

#### 2.1.1

 * Migration: Rank Math and Yoast term-level SEO (focus keyword, search snippet,
   SEO title, canonical, noindex on every category/tag/custom taxonomy term) is 
   now copied into BinaryPH’s term meta. Previously term archives reverted to defaults
   after switching to Standalone.
 * Migration: per-post primary category is now copied (Rank Math `rank_math_primary_category`,
   Yoast `_yoast_wpseo_primary_category`  `_bps_primary_category`).
 * Schema: breadcrumb category selection now honors the user’s primary category 
   instead of always picking the first attached category. Applies to both posts 
   and WooCommerce products.
 * Migration preview now lists detected per-post schema customizations from Rank
   Math (FAQ, HowTo, Recipe, Event, Course, JobPosting, Product) and Yoast (Article-
   type / Page-type overrides) so users see _before_ importing what will need to
   be re-entered manually after switching to Standalone. We deliberately do not 
   auto-copy these — the source plugins’ serialized schema field shapes vary across
   versions and a bad mapping would corrupt rich snippets.
 * New: when in Standalone mode and we detect leftover SEO data …

## Meta

 *  Version **3.0.0**
 *  Last updated **7 گؤن ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 6.5 or higher **
 *  Tested up to **7.1.3**
 *  PHP version ** 8.0 or higher **
 *  Language
 * [English (US)](https://wordpress.org/plugins/binaryph-ai-seo/)
 * Tags
 * [AI](https://azb.wordpress.org/plugins/tags/ai/)[llms.txt](https://azb.wordpress.org/plugins/tags/llms-txt/)
   [schema](https://azb.wordpress.org/plugins/tags/schema/)[seo](https://azb.wordpress.org/plugins/tags/seo/)
   [sitemap](https://azb.wordpress.org/plugins/tags/sitemap/)
 *  [Advanced View](https://azb.wordpress.org/plugins/binaryph-ai-seo/advanced/)

## Ratings

 5 out of 5 stars.

 *  [  1 5-star review     ](https://wordpress.org/support/plugin/binaryph-ai-seo/reviews/?filter=5)
 *  [  0 4-star reviews     ](https://wordpress.org/support/plugin/binaryph-ai-seo/reviews/?filter=4)
 *  [  0 3-star reviews     ](https://wordpress.org/support/plugin/binaryph-ai-seo/reviews/?filter=3)
 *  [  0 2-star reviews     ](https://wordpress.org/support/plugin/binaryph-ai-seo/reviews/?filter=2)
 *  [  0 1-star reviews     ](https://wordpress.org/support/plugin/binaryph-ai-seo/reviews/?filter=1)

[Your review](https://wordpress.org/support/plugin/binaryph-ai-seo/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/binaryph-ai-seo/reviews/)

## Contributors

 *   [ BinaryPH ](https://profiles.wordpress.org/binaryph/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/binaryph-ai-seo/)