=== Hack The SEO – AI SEO for Google and AI Search ===
Contributors: hacktheseo
Tags: seo, geo, ai seo, schema, xml sitemap
Requires at least: 5.9
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.0.25
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

See if ChatGPT and Claude really read your pages, and fix what stops them. Complete technical SEO too: schema, sitemaps, redirects. Free.

== Description ==

**Hack The SEO handles the whole technical SEO job: schema, XML sitemap, redirects, canonicals and meta. It also records which AI crawlers fetch your pages, so you can tell whether ChatGPT, Claude, Perplexity and Google's AI are reading you. All of it is free, and it works without an account and without sending anything off your server.**

Half of what a page is worth now depends on whether a generative engine can read it and is willing to quote it. That is measured, fixed and proven differently from a blue link. Most plugins bolted an "AI" tab onto a product designed in 2010.

**Why your analytics tool never shows you an AI crawler**

* **AI crawlers do not run JavaScript.** A JavaScript analytics tool is structurally incapable of seeing them, so whatever it tells you about GPTBot, it is guessing.
* Hack The SEO reads the User-Agent on `template_redirect`, server-side. There is no beacon, no tracking script and no external service involved.
* GPTBot, ChatGPT-User, OAI-SearchBot, ClaudeBot, Claude-User, Claude-SearchBot, PerplexityBot, Perplexity-User, Applebot, CCBot and eight more: **18 user agents in total**, from OpenAI, Anthropic, Perplexity, Apple, Google, Meta, Cohere and Common Crawl.
* Every passage is logged into a table in your own database, with the URL and the timestamp.
* Human visits arriving from an AI chat are counted too, through the referrer, so you see the crawler and the click it eventually sent.
* **Only agents these companies really send.** `Google-Extended` is a robots.txt token, not a crawler, so counting it would count nothing.
* **Verify the method in one line:** `curl -A GPTBot https://your-site.tld/your-article/` produces a row in the table.

Other plugins give you a switch to block AI crawlers. This one tells you whether they came.

= Then make the page worth quoting =

**A GEO score, per page, computed on your own server.** GEO, generative engine optimization (sometimes called AEO), covers the work of making a page that a generative engine can read, understand and quote. Scored out of 100 on six criteria, with the failing ones named. Among the questions it asks:

* Does the page answer its question explicitly and early?
* Is that answer above the fold, or buried under four paragraphs of preamble?
* Are there stable facts that can be quoted and attributed?
* Is there a definition block a model can lift as it stands?
* Is the structure parseable by a machine?

**The rules are plain PHP in the plugin.** Open the file and read them. No model decides your score. No API key, no account.

**Then serve the formats a language model actually parses.**

* **A Markdown version of every page, at `/your-page.md`**: no theme, no navigation, no scripts. Almost no other SEO plugin serves this.
* **A virtual `/llms.txt`**, generated from what you really publish, never written to disk.
* **Valid JSON-LD schema**, which a generative engine reads the same way Google does.

Without the crawler log, the rest of this is guesswork.

= Keyword cannibalization, free and actually computed =

Two of your own pages targeting the same keyword compete with each other in the results, and that is very hard to notice by reading your own site.

* Finds the pages competing against each other, by focus keyword and title similarity, then measures how much their content genuinely diverges.
* **Recommends an action for each pair**: merge, differentiate, redirect, or leave alone because the intents really differ.
* Runs in PHP on your server. **It uses no embeddings and no external API, and none of your content leaves the site.**
* Most plugins either do not detect it at all, or put it behind a paid plan.

= The complete technical layer, in the free version =

This is the part most people end up assembling from three or four separate plugins.

An answer engine reads the same schema and the same clean HTML that Google does, so the fundamentals are all here, and none of them is a trial, a teaser or a greyed-out button.

* **Meta titles and descriptions**, Open Graph and Twitter Cards on every post, page and custom post type, with a live Google result preview in the editor.
* Alt text fallback for images that have none, dynamic variables for archives, and category and tag meta edited on the term screen.
* **JSON-LD schema, 60+ types**: Article, Product, Offer, FAQPage, HowTo, QAPage, Recipe, Event, VideoObject, LocalBusiness, JobPosting and more.
* **Generated from what is actually on the page**, not from what you typed in a box. What cannot be detected reliably is yours to enable per page rather than guessed.
* **XML sitemap**: an index plus one sitemap per content type, with image, video and news extensions, and an XSL stylesheet so a human can read it.
* Cached on disk so a cold request does not rebuild it in PHP. Respects noindex, and handles large sites without exhausting memory.
* **301, 302, 307 and 410 redirects**, with a full admin table, regex rules for migrations, CSV import and export, and an automatic 301 when a post slug changes.
* **Incoming 404s logged with hit counts**, so you see what is really broken. Turn any 404 into a redirect in one click. The log is capped and self-cleaning.
* **Redirects are served in PHP, never written into your `.htaccess`.** One malformed line there takes a whole site down with a 500. Identical behaviour on Apache, Nginx and LiteSpeed.
* **Breadcrumbs** built from your real category hierarchy, with matching BreadcrumbList JSON-LD so the trail can appear in Google's results. Shortcode, Gutenberg block and PHP function.
* **Per-post noindex and nofollow**, custom canonicals, and conflict detection so you never emit two canonical tags on one page.
* **A virtual `robots.txt`**, served through WordPress core's own filter. Nothing written to disk.
* **Permalink cleanup**: drop the `/category/`, `/tag/` and `/product-category/` bases, with an automatic 301 from the old URL so you keep what you already ranked.
* **A 21-check on-page score** covering basic SEO, content, meta and result preview, citability and readability, plus a global score and a freshness column in the posts list.
* Table of contents from your H2 and H3 headings, with anchors. **IndexNow** to notify Bing, Yandex, Naver, Seznam and Yep the moment you publish, off until you switch it on.
* **9 modules** you switch on or off one by one, across **12 admin screens**.
* A **"First steps" checklist** that adapts to what your site still needs, and disappears once you are done.

= Moving in without losing what you already rank for =

Switching SEO plugins is where people lose rankings, so the migration wizard reads the other plugin's actual data.

* Imports meta titles and descriptions, robots directives, canonicals, focus keywords, cornerstone flags, redirects and Open Graph fields from **Yoast SEO, Rank Math, All in One SEO and SEOPress**.
* When the previous plugin injected its schema through the theme or a page builder instead of storing it, the wizard **parses your rendered homepage** to recover Organization and LocalBusiness data.
* **It never deletes the original data**, so the move is always reversible.
* **Import first, deactivate second**, in that order. Coexistence detection warns you while a competing SEO plugin is still active, so you never emit duplicate titles and duplicate schema.

= Nothing leaves your site =

**The plugin makes no outbound requests at all.** There is no anonymised telemetry, and nothing to opt out of. If you install the same plugin across client sites, this is the section you will be asked to justify.

* Everything is computed **in PHP, on your server, in your own database**.
* **Exactly one feature can ever contact anything outside your site: IndexNow, and it ships off.** While it is off, no hook is even registered, and it never turns itself on.
* **There is nothing to opt out of, because nothing is sent.** The plugin sets no cookie, loads no third-party script and collects no personal data.
* Visitor IPs are never stored, only hashed into a short-lived rate-limit key, and that module can be switched off entirely.
* Some features do load pages of **your own site** over HTTP: the health check, the sitemap self-test, the schema verification. Loopback requests to your own domain, not a third party.
* **Check it yourself:** grep the plugin for `wp_remote_` and read the nine call sites. Two are IndexNow. The seven others load a page of your own site.

**You never create an account or paste an API key, and no feature stops working because a server somewhere is down.**

= Built for the hosting your clients are actually on =

Older sites are often the ones that need this work most, so the requirements are kept deliberately low.

* Hack The SEO requires **WordPress 5.9 and PHP 7.4**. As of August 2026, Yoast SEO requires WordPress 6.9 and Rank Math requires 6.7. Their own directory pages say so, in the sidebar.
* The site that pays you the most is rarely the site on the newest stack. **A plugin you cannot install on a client's shared host is not a plugin you can standardise on.**
* Thirty client sites, one plugin, and no licences to count.
* Detects **Elementor, Divi, Bricks, Beaver Builder, Oxygen and WPBakery**, and reads the **rendered** content rather than the raw `post_content`.
* So the score, the schema and the Markdown all see the same text your visitors see.
* **WooCommerce**: product schema built from the real product data, and an exempt state for product rows instead of an editorial score that would mean nothing.
* **A health check** that verifies your sitemap answers, your schema is really in the rendered HTML, and your canonicals are valid.
* It tells you when **your host** blocks internal requests, instead of blaming your configuration.
* **It writes one file of its own**: the cached XML sitemap, under `wp-content/uploads/`.
* Front-end output is built during the normal page render, so it caches like the rest of your site. **Nothing in that path calls a remote API**, so no third-party latency lands in your render.
* Works on multisite, each site with its own settings, redirects, sitemap and data.
* **Uninstalling deletes nothing by default.** Someone who reinstalls should not lose the 301s holding their site together.
* **Five languages included**: French, Spanish, German, Italian and Brazilian Portuguese, with translate.wordpress.org open for the rest.

= What this plugin does not do =

* **It does not promise, imply or guarantee any ranking, position or traffic result.** No plugin can, and you should be suspicious of any that says otherwise.
* It gives you correct technical output and honest measurement. The rest is your content.
* It does not include AI content generation, automated internal linking, or a rank tracker.

== External services ==

This plugin connects to exactly one external service, and it is disabled by default: IndexNow.

= IndexNow =

**What it is.** IndexNow is an open protocol that lets a site notify participating search engines (Bing, Yandex, Naver, Seznam, Yep) that a URL has changed, instead of waiting to be crawled. The endpoint `https://api.indexnow.org/indexnow` is operated by the IndexNow sponsors: Microsoft Corporation, Yandex N.V. and Seznam.cz, a.s.

**When it is used.** Only when the IndexNow module is enabled. The option `htsfree_indexnow_enabled` defaults to `0`. While it is `0`, no hook is registered and no request is ever made. The plugin never enables it for you, including on activation. Once you enable it, a request is sent when you publish or update a post or page, or when you click the manual ping button in the admin.

**What is sent.** Only:

* the public URL(s) of the content you just published or updated on your own site;
* the host name of your site;
* an IndexNow key, randomly generated locally and published by design at `https://your-site.tld/{key}.txt`, which is how the protocol proves you own the domain.

No post content, no personal data, no visitor data, no site credentials and no administrator information are transmitted. Requests are rate-limited to one ping per URL per ten minutes.

**Where to read their terms.** Terms of use, which also contain the privacy statement for the service: [https://www.indexnow.org/terms](https://www.indexnow.org/terms). Protocol documentation: [https://www.indexnow.org/documentation](https://www.indexnow.org/documentation). Microsoft's privacy statement, as one of the sponsors processing submissions: [https://privacy.microsoft.com/privacystatement](https://privacy.microsoft.com/privacystatement).

= On-site visitor measurement (no third party) =

The content performance module counts views, reading time and scroll depth for your published posts. This is stored **in your own database only**. Visitor IP addresses are never stored: they are hashed and used solely as a short-lived rate-limit key so the same visitor is not counted twice within thirty minutes. Nothing is sent anywhere. The module can be turned off with the option `htsfree_visits_tracking`.

= For clarity: requests to your own site =

Some features (the health check, the sitemap self-test, the schema verification, the redirect probe, page-builder content extraction) load a URL of **your own site** over HTTP, because that is the only reliable way to see what a visitor or a crawler actually receives. These are loopback requests to your own domain. They are not a third-party service, and nothing leaves your server.

== Installation ==

= From your WordPress admin =

1. Go to **Plugins > Add New**.
2. Search for **Hack The SEO**.
3. Click **Install Now**, then **Activate**.

= Manual installation =

1. Download the ZIP file.
2. Go to **Plugins > Add New > Upload Plugin** and select the ZIP.
3. Click **Install Now**, then **Activate**.
4. Or, over FTP, upload the `hack-the-seo` folder to `/wp-content/plugins/` and activate it from the **Plugins** screen.

= After activation =

1. Open the **Hack The SEO** menu. The "First steps" checklist adapts to what your site still needs and disappears once you are done.
2. If you are coming from another SEO plugin, run the **Migration** screen **before** deactivating it. Import first, deactivate second.
3. Check **Health** to confirm your sitemap and schema are being served correctly.
4. Submit `/sitemap.xml` to Google Search Console.

= Requirements =

* WordPress 5.9 or later
* PHP 7.4 or later
* No account, no API key, no subscription.

== Frequently Asked Questions ==

= What is the best free SEO plugin for WordPress? =

That depends on what you need, and anyone giving you a single answer is selling something. Yoast SEO and Rank Math are the two largest and have the biggest ecosystems. All in One SEO is the oldest. SEOPress is the leanest of the big four. Slim SEO is the right answer if you want zero configuration.

Hack The SEO is built for a specific case: you want the whole technical layer (schema, sitemap, redirects, canonical, robots, breadcrumbs) plus keyword cannibalization detection and real AI-crawler measurement, computed locally, with no account and nothing sent to a third party. If cannibalization or GEO measurement is what you are missing, this is the free plugin that has it. If you mostly want AI-generated content, it is not.

= How do I add schema (JSON-LD) to WordPress? =

Install Hack The SEO and it generates JSON-LD automatically from what is already on each page: Article, BreadcrumbList, Organization, Person, Product, FAQPage, HowTo, QAPage, VideoObject and 60+ types in total. Types that cannot be detected reliably, such as LocalBusiness opening hours, are yours to enable per page in the Schema settings, so nothing is invented. Confirm the result in Google's Rich Results Test or the Schema Markup Validator.

= How do I create a 301 redirect in WordPress? =

Open the Redirects screen, enter the old URL and the destination, and choose 301 (permanent). You can also use 302, 307 and 410, add regex rules for bulk migrations, and import or export everything as CSV. When you rename a post, a 301 from the old slug is created for you. Incoming 404s are logged, and any 404 can be turned into a redirect in one click. Redirects are served in PHP, so your `.htaccess` is never touched and it works identically on Apache, Nginx and LiteSpeed.

= How do I generate an XML sitemap for WordPress? =

It is served automatically at `/sitemap.xml`: a sitemap index plus one sitemap per content type, with image, video and news extensions and an XSL stylesheet so it is readable by a human. It respects noindex and is cached on disk so it does not rebuild in PHP on every request. Submit `/sitemap.xml` to Google Search Console. The "First steps" checklist reminds you to.

= What is llms.txt, and how do I add it to WordPress? =

`llms.txt` is a plain-text file listing your key content for AI crawlers, in the same spirit as `robots.txt` for search crawlers. Hack The SEO serves it virtually at `/llms.txt`, generated from your real content, with no file written to disk. It also serves a Markdown version of every page at `/your-page.md`, which is the format LLMs parse most reliably and most cheaply. Both are on your own server, both are free, and neither requires an account.

= What is GEO (generative engine optimization) and AEO? =

GEO, sometimes called AEO (answer engine optimization), means making your content easy for generative engines (ChatGPT, Claude, Perplexity, Gemini, Google AI Overviews) to read, understand and cite. Classic SEO optimises for a ranked list of links; GEO optimises for being the source quoted inside an answer.

In practice it comes down to: answer the question explicitly and early, keep facts stable and attributable, structure the page so a machine can parse it, expose clean formats (schema, Markdown, llms.txt), and then measure whether the AI crawlers actually come. Hack The SEO does all five, locally, in the free version.

= How do I see which AI crawlers visit my site? =

The AI visibility screen records visits from GPTBot, ChatGPT-User, OAI-SearchBot, ClaudeBot, Claude-User, Claude-SearchBot, PerplexityBot, Perplexity-User, Applebot, CCBot, Bytespider and others, read directly from the server request, with no JavaScript and no external service. This is not a detail: AI crawlers do not run JavaScript, so ordinary analytics tools cannot see them at all. Test it in one line:

`curl -A GPTBot https://your-site.tld/your-article/`

That request will appear in your dashboard.

= What is keyword cannibalization, and how do I fix it? =

Keyword cannibalization is when two or more of your own pages target the same query, so search engines have to pick between them and both underperform. It is one of the most common causes of a site that has plenty of content and no rankings.

Hack The SEO detects it for free: it compares focus keywords and title similarity to find competing pairs, measures how much their content actually diverges, and recommends what to do with each pair: merge them, differentiate them, redirect one into the other, or leave them alone because they genuinely serve different intents. All computed in PHP on your server, with no embeddings and no external API.

= How do I get my content cited by ChatGPT, Perplexity or Google AI Overviews? =

Nobody controls that, and any tool claiming otherwise is guessing. What you can control is whether your content is *citable*, and whether the engines are even reading it.

Being citable means: answering the question explicitly and early on the page rather than after four paragraphs of preamble; stating facts that can be quoted and attributed; keeping a clean, parseable structure; and exposing formats a model reads cheaply: valid JSON-LD schema, a Markdown version of the page, an `llms.txt` index. Hack The SEO's GEO score checks the first three and generates the last two.

Then you measure. The AI visibility screen tells you whether GPTBot, ClaudeBot, PerplexityBot and the rest actually came, on which URLs, and how often. Very few free plugins give you that, and without it you have no way of knowing whether any of the rest is working.

= How do I find and fix 404 errors in WordPress? =

Every 404 hit on your site is logged automatically, with the requested URL, the referrer and a hit count, so you can tell a real broken link from a bot probing for `/wp-admin/setup.php`. Sort by hits, and the URLs actually costing you traffic come straight to the top. Each row has a one-click "redirect this" action that turns the 404 into a 301 to wherever you choose. The log is capped and self-cleaning, so it cannot grow until it hurts your database.

= Does it work with Google Search Console and IndexNow? =

The XML sitemap at `/sitemap.xml` is what you submit to Google Search Console, and the "First steps" checklist walks you through it. IndexNow is built in and optional: turn it on, and Bing, Yandex, Naver, Seznam and Yep are notified the moment you publish or update a URL, rather than waiting for a crawl. It is off by default and sends nothing but the URL, your host name and your IndexNow key. See "External services".

= How do I switch from Yoast SEO, Rank Math, All in One SEO or SEOPress? =

Install Hack The SEO **while the other plugin is still active**, open the Migration screen, and run the import. It reads meta titles and descriptions, meta robots, canonical URLs, focus keywords, cornerstone/pillar flags, redirects and Open Graph fields. If the previous plugin emitted its schema through the theme or a page builder rather than storing it, the wizard parses your rendered homepage to recover Organization and LocalBusiness data.

Then verify a few pages, then deactivate the other plugin. Import first, deactivate second, in that order. The wizard never deletes the source data, so the move is reversible.

= Can I run it alongside Yoast, Rank Math, All in One SEO or SEOPress? =

Not permanently. Two SEO plugins active at once means duplicate title tags, duplicate canonicals and duplicate schema, which is worse than either one alone. Hack The SEO detects a competing SEO plugin and warns you. The intended path is: install, migrate, verify, deactivate the other one.

= Will it slow down my site? =

Front-end output is meta tags, JSON-LD and, if you enable them, breadcrumbs, all built during the normal page render. The XML sitemap is cached on disk rather than rebuilt in PHP. Scores, cannibalization and health checks run in the admin or on cron, never on a visitor's request. AI crawler detection is a User-Agent read on a hook that already runs. There is no external HTTP call in the front-end path, which is worth stating explicitly: a plugin that calls a remote API while rendering your page is at the mercy of that API's latency. This one has nothing to call.

= Does this plugin send my data anywhere? =

No. Out of the box it makes **zero outbound requests**.

There is exactly one feature that can ever contact a third party, and you have to switch it on yourself: **IndexNow**. When enabled, it sends the URL you just published, your host name and your IndexNow key to `api.indexnow.org`. Nothing else, ever. While it is off, which is how it ships, no hook is even registered.

Some features do load pages of *your own site* over HTTP, to verify that your sitemap answers and your schema is really in the rendered HTML. Those requests go to your domain, not to us.

That is the whole story, and you can verify it: grep the plugin for `wp_remote_` and read the nine call sites yourself: two are IndexNow, the seven others load a page of your own site.

= Is it GDPR compliant? =

The plugin sets no cookie, loads no third-party script and sends no personal data anywhere. The on-site content performance module counts views, reading time and scroll depth in your own database; visitor IP addresses are never stored, only hashed as a short-lived rate-limit key, and the module can be switched off. As always, GDPR compliance is a property of your whole site, not of one plugin, but this one gives you nothing to declare.

= Do I need an account to use it? =

No. Every feature described on this page runs locally. There is no sign-up, no key to paste, and no feature that stops working because a server somewhere is down.

= Does it guarantee I will rank better on Google? =

No, and be suspicious of any plugin that says otherwise. Ranking depends on your content, your market and factors nobody controls. What this plugin does is make sure the technical layer is correct and give you honest measurements. That is a prerequisite, not a promise.

= Does it work with WooCommerce? =

Yes. Product pages get Product, Offer and AggregateRating schema where the data genuinely exists, product categories are handled by the sitemap and the permalink options, and product rows in the posts list show an exempt state rather than an editorial score that would mean nothing for a product.

= Does it work with Elementor, Divi, Bricks, Oxygen or WPBakery? =

Yes. The plugin detects the builder and reads the rendered content rather than the raw `post_content`, so the scoring, the schema and the Markdown output all see the same text your visitors see.

= Does it work with caching plugins and CDNs? =

Yes. Everything on the front end is standard WordPress output, so it caches like the rest of your page. Redirects are evaluated early, on `template_redirect`. A full-page cache drop-in can still answer before WordPress loads any plugin, so clear your cache after adding a rule. The sitemap has its own disk cache. Nothing depends on a request reaching PHP uncached.

= Does it work on multisite? =

Yes. Each site keeps its own settings, redirects, sitemap and data.

= How do I noindex a page or post in WordPress? =

Open the Hack The SEO panel on any post, page or custom post type and switch on "noindex", and "nofollow" if you need it. The plugin outputs a single, correct robots meta tag and keeps that URL out of your XML sitemap. Whole archives (author, date, internal search) can be set to noindex from the settings.

= How do I add breadcrumbs to WordPress? =

Switch the Breadcrumbs module on first, then use the `[htsfree_breadcrumbs]` shortcode, the "Breadcrumbs" Gutenberg block, or the `htsfree_breadcrumbs()` PHP function in your theme. Hack The SEO builds the trail from your category hierarchy and outputs matching BreadcrumbList schema, so your breadcrumbs can appear directly in Google's results.

= How do I set a canonical URL? =

Every post and page has a canonical field in the SEO panel. Leave it blank for the automatic self-referencing canonical, or enter a custom URL to consolidate duplicate content. The plugin detects conflicts and never outputs two canonical tags on the same page.

= Does the plugin write files on my server? =

Almost nothing. There is exactly one thing written to disk: the generated XML sitemap, cached under `wp-content/uploads/hts-cache/sitemaps/` so a cold request does not have to rebuild it in PHP. That is the complete list. In particular:

* **No redirect is ever written to your `.htaccess`.** Redirects are served in PHP, on Apache, Nginx and LiteSpeed alike. The only time the file changes at all is when WordPress refreshes its own `# BEGIN WordPress` block: the plugin asks core for a rewrite refresh on activation, on update, and when you change a permalink option, exactly as Settings > Permalinks does. Nothing of ours is added to the file, and it is left alone entirely when it is not writable.
* `robots.txt` is **not** written to disk. It is served virtually, through WordPress core's own `robots_txt` filter.
* `llms.txt` is **not** written to disk either.
* Nothing is ever written outside `wp-content`.

= What happens to my data if I uninstall? =

By default, nothing is deleted. Your redirects, your 404 log, your metadata and your settings stay in the database; only transients and scheduled tasks are cleaned. This is deliberate: someone who uninstalls and reinstalls should not lose the 301s holding their site together. If you genuinely want everything gone, enable the "delete my data on uninstall" option first.

= Why is part of the interface in French? =

The plugin is developed in France and is fully internationalised; the interface follows your site language automatically. French, Spanish, German, Italian and Brazilian Portuguese are included with the plugin. Further translations are handled through translate.wordpress.org. Help with any other language is very welcome.

= Is there a paid version? =

Yes, and it is a separate product. Everything on this page works in the free version, permanently, without an account. See the section below.

== A paid version exists ==

Hack The SEO also has a commercial version, which adds automated internal linking and semantic cocoons, AI-assisted content workflows, and a hosted dashboard. It is a separate product and is not required for anything described here.

The free version is not a trial and does not expire. It stores its data under the same keys as the commercial version, so if you ever move up, your metadata, redirects and scores are picked up exactly as they are. Details at [hacktheseo.com](https://hacktheseo.com/).

== Screenshots ==

1. SEO dashboard: module status, site health, SEO score, GEO score and AI crawler activity at a glance.
2. On-page SEO panel in the editor: a Google score and an AI citability score, meta title and description, and 21 checks.
3. Schema JSON-LD settings: 60+ schema types generated automatically, configurable per page.
4. Keyword cannibalization report: pages competing on the same keyword, with a recommended action for every pair.
5. AI visibility and GEO: visits from GPTBot, ClaudeBot, PerplexityBot and other AI crawlers, measured server-side.
6. Redirects and 404 log: 301 redirects, regex rules, CSV import and export, one-click 404-to-redirect.
7. Migration wizard: import meta, redirects and schema from Yoast SEO, Rank Math, All in One SEO or SEOPress.
8. XML sitemap: sitemap index, per-type sitemaps and a human-readable XSL stylesheet.
9. Health check: sitemap, schema and canonical verified against your rendered HTML.
10. Every issue on your site, ranked: pages under 50, 404s, competing groups, images without alt, each with its fix.

== Changelog ==

= 1.0.25 =
* Fix: `Google-Extended` and `Applebot-Extended` have been removed from the AI crawler list. Neither is a crawler: Google documents that Google-Extended has no separate user agent string, and Apple documents that Applebot-Extended does not crawl web pages. Both were robots.txt tokens, so neither could ever have been detected. Apple is now tracked through its real crawler, `Applebot`.
* Added: `Claude-User` and `Claude-SearchBot`, Anthropic's current on-demand and search agents; `Perplexity-User`, Perplexity's on-demand fetcher; and `Google-CloudVertexBot`. Eighteen user agents are now matched, up from thirteen.
* Removed: `Gemini-Bot` and `CopilotBot`, which neither company publishes. Human visits arriving from Gemini and Copilot chats are still measured, through the referrer.

= 1.0.24 =
* Fix: updating from 1.0.22 or earlier no longer resets your settings. The rename migration ran after the modules had already written their defaults, so a module you had switched on could come back off.
* Fix: the migration now keeps each setting's autoload state instead of turning it off. WordPress 6.6 changed the wording stored in that column, and the check missed it, which added one database query per setting on every page.
* Fix: `[hts_breadcrumbs]` and `[hts_sitemap]` written in older posts render again. They were renamed in 1.0.21 without rewriting existing content, so visitors saw the raw shortcode text.
* Fix: the rename migration no longer runs when the commercial version is installed alongside. It shares the same setting names, and moving them emptied its data.
* Changed: the breadcrumbs block is now registered as `htsfree/breadcrumbs`, and the remaining French labels and untranslatable strings are translated: "Table of contents", "Breadcrumb", "Home", "Other AI", and the sitemap screen messages.

= 1.0.23 =
* Changed: every option and transient the plugin owns now carries the `htsfree_` prefix, as the directory requires. Your settings are migrated automatically on update; per-post SEO data is untouched.
* Fix: the Author URI now points to the wordpress.org profile, which answers in a second. The previous address took eleven, over the review tool's timeout.

= 1.0.21 =
* Changed: the two shortcodes are now `[htsfree_breadcrumbs]` and `[htsfree_sitemap]`, so every registered name carries a prefix longer than three characters.

= 1.0.20 =
* Fix: FAQ schema answers are no longer cut in the middle of a word. AI answer engines read this markup directly, so a truncated answer stayed truncated in their index.
* Fix: llms.txt descriptions no longer show leftover escape characters when page builders store their content as JSON.
* Improved: the AI visibility card now says "Visits from AI chats", so it is no longer mistaken for the crawler passage counter next to it.
* Changed: activating the plugin no longer redirects you. A dismissible welcome notice offers the setup instead, on the plugins list and on Hack The SEO screens only.
* Fix: with the Breadcrumbs module enabled, the breadcrumbs Gutenberg block is now offered in the block inserter. It was registered server-side only, so it rendered existing markup but could not be added to a page.
* Changed: the XML sitemap stylesheet, which is served publicly, no longer carries links to our own site and is now written in English. It previously showed French text and a "powered by" badge on every site.

= 1.0.18 =
* Fix: "Analyze my pages" no longer reports success when the requests were rejected; it now says so and gives the button back.
* Fix: redirecting or approving a 404 no longer claims success when the rule was refused; the entry stays in the list.
* Fix: the "Choose" button of the social share image is visible again and opens the media library.
* Fix: turning the XML sitemap off now flushes the rewrite rules, so /sitemap.xml stops answering with the home page.
* Fix: the "Who handles what?" step of the migration wizard now really changes what the site outputs, both ways.
* Fix: uninstalling removes the plugin transients again, and two "Repair" buttons of the Health screen do what they announce.

= 1.0.17 =
* Fix: the design system stylesheet is loaded again. In 1.0.16 the prefix rename also renamed the file path, so every admin screen rendered unstyled.

= 1.0.16 =
* Changed: every function, class, constant, hook, AJAX action, transient, nonce, admin page slug and script handle now uses the `htsfree_` prefix. Stored data keys are unchanged, so nothing is lost on update.
* Improved: inline styles and scripts no longer go through an output buffer; 33 of them are now plain strings handed to WordPress.
* Fix: `set_time_limit()` no longer shortens the execution window on hosts that allow more than 120 seconds, and never imposes one on hosts that allow unlimited.
* Fix: the breadcrumb separator saved from the settings screen is applied again.
* Fix: redirect and score queries build their `IN ()` lists from bound placeholders.
* Fix: removed an unused AJAX endpoint that could overwrite the breadcrumb settings without validation.

= 1.0.15 =
* Fix: the page title is now escaped once on output, so a meta title can never inject markup into the `<title>` tag.
* Fix: saving Schema Pro fields no longer fails with a server error when a field holds a list of values.
* Fix: the sitemap and migration notices only appear on Hack The SEO screens, and every notice can be dismissed with the standard WordPress control.
* Fix: on multisite, uninstalling now removes the cached sitemap of every subsite instead of the main site only.
* Fix: the canonical URL box in the editor is translatable, and no longer shows an icon in place of its title.
* Improved: all stylesheets are handed to WordPress instead of being written into the page.
* Improved: readme wording corrected on disk writes, translations and the paid version.

= 1.0.14 =
* New: a "First steps" checklist on the dashboard that adapts to what still needs setting up (indexing, permalinks, importing from another SEO plugin, company details, author profile, sitemap) and disappears once you are done.
* New: a guided tour of the dashboard (native highlight, no external library) that walks through your SEO score, AI visibility and the main screens. Starts from the "First steps" card and can be restarted anytime.
* New: edit the SEO meta title and description of your categories and tags directly on the term edit screen.
* Improved: the "Go Pro" and semantic-cocoon screens were redesigned to be clearer and more useful.
* Improved: the plugin is now fully internationalised, ready for translation through translate.wordpress.org.
* Fix: WooCommerce product rows in the posts list now always show an exempt state instead of an old editorial score left over from a previous version.
* Hardening: reinforced unslashing and sanitization of every admin form and request input, and reviewed all database access.
* Fix: redirects imported from another SEO plugin, and redirects whose URL contains accents or encoded characters, are now matched correctly instead of silently never firing.
* Fix: sending a post to the trash no longer replaces its redirect with a broken one.
* Fix: redirects now keep the incoming query string (utm_source, filters, sorting) when the destination has none.
* Fix: on sites using a static front page plus a posts page, the posts page now outputs its own title, description and canonical instead of the home page's.
* Fix: meta descriptions and titles are no longer corrupted on non-Latin content (Japanese, Chinese, Korean, Arabic, Cyrillic) or after an accented capital.
* Fix: category and tag archives are no longer set to noindex behind your back; only internal search and paginated pages get safe defaults.
* Fix: the meta description, schema and scores now refresh as soon as you edit a post, instead of describing the previous version for up to a week.
* Fix: the sitemap cron no longer loads the whole site in one pass (memory exhaustion on large sites), and deactivating the plugin no longer leaves /sitemap.xml answering incorrectly.
* Fix: the 404 log no longer freezes once full, and bot probes can no longer crowd out real 404s.
* Fix: the Markdown (.md) version of a post now respects membership and paywall plugins, and is no longer empty on shortcode-based page builders.
* Fix: every screen is now translatable; strings that were missing from the catalogue have been added.
* Fix: "Top pages seen by AI" counted SEO crawlers (Moz, Ahrefs, Semrush) as AI reads. Only genuine AI crawlers are counted now.
* Fix: running the analysis from the dashboard left the Actions screen claiming your pages had never been analyzed for up to five minutes. The cached views are now refreshed the moment the analysis finishes.
* Improved: OAI-SearchBot, the crawler behind ChatGPT search, is now recognised and logged.
* Improved: the "Go Pro" screen lost a redundant call-to-action that sat directly above the pricing table.

For the full version history, see changelog.txt.

== Upgrade Notice ==

= 1.0.20 =
Fixes truncated FAQ schema answers and llms.txt descriptions.

= 1.0.18 =
Several buttons announced a success they had not obtained. They now tell the truth.

= 1.0.17 =
Fixes the missing admin stylesheet introduced in 1.0.16.

= 1.0.16 =
Internal renaming to a longer prefix, as requested by the WordPress.org plugin review. Your settings and SEO data are untouched.

= 1.0.15 =
Output escaping and notice fixes following the WordPress.org plugin review, plus a multisite uninstall fix.

= 1.0.14 =
New "First steps" checklist, a guided dashboard tour, category and tag meta editing, redesigned Go Pro and semantic-cocoon screens, and full internationalisation.
