> ## Documentation Index
> Fetch the complete documentation index at: https://snowseo.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# WordPress

> Enable AI crawler tracking on WordPress with the SnowSEO plugin.

The SnowSEO plugin handles this. No code, and if the site is already connected for publishing you will not need to copy a key.

Requires plugin version 1.4.0 or later, WordPress 5.6+, PHP 7.4+.

***

## Setup

<Steps>
  <Step title="Install and connect the plugin">
    Install **SnowSEO** from the WordPress plugin directory, then connect it to your brand under **SnowSEO → Settings**.

    Already publishing to this site from SnowSEO? Then this is done.
  </Step>

  <Step title="Get the site key">
    Open **SnowSEO → AI Crawlers** in wp-admin and click **Get site key**. The plugin exchanges the key it already holds for its tracking key, so nothing is copied by hand.

    No SnowSEO connection on this site? Generate a key under **Settings → Integrations → Beacon** in the SnowSEO dashboard and paste it into the field on that same screen (**Save key**). Tracking works standalone; it does not require the publishing connection.
  </Step>

  <Step title="Switch tracking on">
    Toggle **Tracking** to enabled, on the same screen or under **Settings → Reading**.

    It is off until you do this, on purpose - once on, the plugin sends visitor IP addresses to SnowSEO, and that is your decision to make rather than a side effect of clicking connect.
  </Step>
</Steps>

Hits appear on the Bot Traffic dashboard within a minute or two of the next crawler visit.

***

## Check it is working

**SnowSEO → AI Crawlers** shows four tiles: **Visits sent**, **Waiting to send**, **Last sent** and **Site key**. Buffered visits upload on a one-minute WP-Cron tick, so **Waiting to send** should never hold a value for long. If **Last sent** stays at *Never* while it climbs, something is blocking the outbound request, and the card says so directly - the heading changes to *Nothing has reached SnowSEO yet* and the error line names the cause.

To force a hit, request one of your own pages with a crawler user agent:

```bash theme={null}
curl -A "GPTBot/1.2" https://example.com/
```

***

## Page caching

<Warning>
  This is the single most common reason WordPress numbers look lower than a raw server log.
</Warning>

WP Rocket, LiteSpeed Cache, W3 Total Cache, WP Super Cache and most managed hosts answer many requests from a stored HTML file **without running WordPress at all**.

There is an exact reason for it. WordPress includes the page-cache drop-in at line 100 of `wp-settings.php` and does not register its own shutdown handler until line 166. A cache plugin that serves a stored page and exits from `advanced-cache.php` finishes 66 lines before WordPress has anywhere to hang a plugin, let alone this one.

### Where tracking runs

The **Where tracking runs** card on the AI Crawlers screen offers three positions. Each loads earlier than the last:

| Position            | Loads at                 | Counts                                                         |
| ------------------- | ------------------------ | -------------------------------------------------------------- |
| **This plugin**     | with every other plugin  | every request WordPress serves itself                          |
| **Must-use plugin** | before all other plugins | the above, plus requests another plugin would have ended first |
| **wp-config.php**   | before the page cache    | the above, plus every cached request                           |

The plugin picks the first by default and tells you when the third is worth it - which is whenever a cache drop-in is present. Choosing it writes a one-line `@include_once` into `wp-config.php` directly above the `require_once ABSPATH . 'wp-settings.php';` line. If `wp-config.php` is not writable, or the site sets `DISALLOW_FILE_MODS`, the screen shows the exact line to paste instead.

### Caches in front of WordPress

The **Caches in front of WordPress** card lists every layer it can detect and what to do about each. Where the cache offers a way to skip its stored copy for a user agent, one button sets it:

* **WP Rocket**, **LiteSpeed Cache**, **W3 Total Cache** - handled. (WP Rocket's rules are anchored to the start of the User-Agent, and every AI crawler string begins `Mozilla/5.0`, so the entries have to be written `(.*)GPTBot(.*)`. The plugin does that for you; a bare token entered by hand works on a cache miss and silently fails on a hit.)
* **WP Super Cache** - not possible. Its "Rejected User Agents" setting only applies when *writing* the cache, never when serving it, as its own field text admits. Use the wp-config.php position instead.
* **WP Engine, Kinsta, SiteGround, Cloudways** - no user-agent exclusion exists. The card generates the request to send their support.
* **Cloudflare** - add a Cache Rule matching AI crawler user agents with **Bypass cache** (available on the free plan), or deploy the [Cloudflare Worker](/docs/beacon/install/cloudflare-worker), which runs ahead of the cache and sees everything.

Markdown twins are excluded from the cache automatically, so `.md` fetches are always counted.

Click **Run coverage check** to measure the result. It fires two identical requests at your site and compares a per-request marker, so you get a real number for your setup rather than a warning.

***

## AI assistants getting 403

If ChatGPT or Claude report that they cannot read your pages, nothing on this list will help - the request is being refused before it reaches your site, and no plugin can count a request that never arrives.

Open **Bot Traffic** in the SnowSEO dashboard. The panel at the top fetches your site with every published crawler user agent from outside your network, compares each against a browser, and names what refused it. See [Troubleshooting](/docs/beacon/troubleshooting) for the full list of causes.

***

## Privacy

The plugin adds suggested wording to **Settings → Privacy** describing what tracking sends. Your site is the data controller here, so review it.

If you would rather not send IP addresses, turn off **Send IP addresses** on the AI Crawlers screen. Crawlers can then no longer be verified - every hit will show as **Unverified**, spoof detection stops working, and coding agents cannot be attributed to a provider - but path, User-Agent and volume still report.

***

## Constants and filters

For agencies and config-managed fleets:

```php theme={null}
// wp-config.php
define( 'SNOWSEO_BEACON_KEY', 'sb_live_...' );  // key without touching the database
define( 'SNOWSEO_BEACON_DISABLE', true );       // hard off, nothing registers
```

```php theme={null}
// Widen or narrow what gets recorded.
add_filter( 'snowseo_beacon_should_record', '__return_true' );

// Stop Markdown responses bypassing the page cache.
add_filter( 'snowseo_bypass_page_cache', '__return_false' );
```

Full list in `BEACON.md` in the plugin.
