=== DevDome Analytics – Real Traffic Without Bot Noise ===
Contributors: devdome
Tags: analytics, traffic analytics, bot traffic, ai referrals, click tracking
Requires at least: 6.0
Tested up to: 7.0
Requires PHP: 7.4
Stable tag: 1.0.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

See real visitors, not bot-inflated traffic. Track pageviews, AI referrals, outbound clicks, live visitors, and crawlers separately.

== Description ==

DevDome Analytics gives you a clearer view of real website traffic by detecting known bots and AI crawlers and reporting them separately from human visitors.

A lightweight Google Analytics alternative for WordPress: track visitors, pageviews, sessions, live traffic, top pages, referrers, countries, devices, and outbound-link clicks without filling your WordPress database with analytics data, and with cookieless general traffic tracking on new installs.

A free DevDome account is required because collection, processing, and full reports are provided by the hosted DevDome Analytics service. Nothing is tracked or sent until you connect the site.

**Real traffic without bot noise**

Known crawlers and AI bots are identified and shown in separate reports instead of being mixed into your visitor numbers. This helps you understand how much of your traffic comes from people and how much comes from crawlers.

Bot detection covers known search crawlers, SEO crawlers, and AI crawlers. Unknown or disguised bots may not always be identifiable.

**Website traffic analytics**

* Visitors, pageviews, sessions, live visitors, and top pages.
* Referrers, countries, browsers, operating systems, and device types.
* Pages per visit, average session duration, bounce rate, and click-through rates.
* Reports for the last 24 hours, 7 days, 30 days, 3 months, or 12 months.

**AI referrals and crawler reports**

See visits referred by AI assistants such as ChatGPT and Perplexity. Known AI crawlers, search-engine bots, and SEO crawlers are reported separately so you can compare human traffic with crawler activity.

**Outbound-link click tracking**

Track which external links visitors click. Outbound clicks are relayed through your own domain, helping preserve click events that may otherwise be missed when a third-party analytics script is blocked.

**Privacy controls**

* New installs use cookieless general traffic tracking by default.
* Returning-visitor tracking is optional and disabled on new installs.
* Outbound-link tracking uses localStorage and sessionStorage only after a visitor clicks an external link; it can be disabled.
* Logged-in administrators are excluded by default, and any WordPress role can be excluded.
* Browser Do Not Track signals are respected by default.
* No form values, post content, user accounts, customer details, order data, or payment data are collected.
* Each tracking feature has its own switch, plus a master switch to stop all tracking.

**No analytics database bloat**

The plugin creates no analytics tables and stores no pageviews, visits, clicks, or sessions in your WordPress database. Only plugin settings, connection details, and short-lived operational transients are stored locally.

**Reports in WordPress and DevDome**

The WordPress Overview tab shows key numbers including visitors, live visitors, bots, clicks, pageviews, click-through rates, pages per visit, session duration, and bounce rate.

Detailed traffic analytics, AI referral reports, outbound-click reports, and crawler activity are available in your DevDome account.

**Connect in minutes**

Open **DevDome > Analytics**, connect your DevDome account, review the tracking settings, and enable only the features you want.

== External services ==

DevDome Analytics is a connector for the DevDome Analytics service. It talks to two hosts, both operated by DevDome.

Terms of service: https://devdome.com/terms-of-service
Privacy policy: https://devdome.com/privacy-policy

= analytics.devdome.com - the analytics service =

**The tracking script, https://analytics.devdome.com/track.js**
Loaded in your visitors' browsers on public pages, once the site is connected and Enable Tracking is on. It is not added to your pages before you connect.

**The event ingest, https://analytics.devdome.com/api/event**
This is where analytics events are recorded, and there are three ways it is reached.

1. From the visitor's browser, by the tracking script above. Each event carries: your Site ID (this site's domain), your DevDome Account ID, the page URL and path, the page title, the referring URL, browser, operating system, device type, user agent, browser language, country, the target URL of a click, and a visitor ID and session ID only when the browser is storing them (see Privacy). Because the browser contacts the service directly, the visitor's IP address is visible to it, as it is to any server a browser connects to.
2. From your server, when it forwards an outbound-link click. The visitor's browser sends the click to the `/dd-e` path on your own domain and your server relays it. Your server adds two fields to that relayed event: the visitor's country code and **the visitor's IP address**, so location and per-visitor counts stay correct when the event arrives from your server instead of from the browser.
3. From your server, when a known crawler requests a page and Track Bot Visits is on. That event carries the crawler's user agent, the bot name and type, the requested URL and path, your Site ID and a timestamp. No human visitor data is in it.

**The connection handshake, https://analytics.devdome.com/api/plugin/status**
Sent when you connect the site and when the connection is re-verified. Contains your Site ID, this site's secret token, your Account ID, the site URL, the site name, **the site administrator's email address**, the WordPress version, the PHP version, the plugin version, the active theme name, the timezone, the site language and whether this is a multisite install. No visitor data.

**The one-click connect handshake, https://analytics.devdome.com/api/plugin/connect/start and /api/plugin/connect/claim**
`connect/start` runs only when you press the "Connect Via DevDome Account" button, never on its own — opening the plugin's screen makes no request. It sends this site's domain, its secret token and the wp-admin address to return to, and receives a short-lived connect link. `connect/claim` runs when your browser returns from devdome.com and exchanges that link for your Account ID.

**The stats read, https://analytics.devdome.com/api/plugin/stats**
Sends your Site ID, this site's secret token (so only your own site can read its numbers) and the selected day range. Used to fill the Overview tiles in wp-admin, and the bot-visit figure shared with DevDome Bot Protection when that plugin is installed.

**Deleting your data, https://analytics.devdome.com/api/plugin/purge**
Sends your Site ID and this site's secret token, and only when you press Reset Analytics, or tick "Also delete my data on DevDome" while disconnecting.

= api.devdome.com - DevDome account services =

These two are made by the shared DevDome library bundled with every plugin in the suite.

**The account check, https://api.devdome.com/plugin/account**
A GET carrying this site's domain and its secret token, answered with the Account ID and account email address that the token belongs to, so the DevDome screen can show which account this site is linked to. It runs when the DevDome screen is displayed, at most once every twelve hours — and never before you have acted: until you press a Connect button, save an Account ID or complete a connection, this check is not made at all.

**Disconnecting, https://api.devdome.com/plugin/disconnect**
A POST carrying this site's domain and its secret token, sent only when you press Disconnect, to unlink the site from the account.

= Not contacted on this WordPress.org build =

The bundled shared library also references endpoints that this build never calls:

* `https://api.devdome.com/bot-protection/list`, `/asns` and `/drop`: shared bot-signature feeds used by other plugins in the DevDome suite. This build never fetches them and no cron is scheduled for them.
* `https://api.devdome.com/plugin-updates/`: self-hosted updates and the suite hub's one-click installer for DevDome plugins that are not on WordPress.org. Disabled on this build; updates come from WordPress.org.

= devdome.com =

`https://devdome.com/connect/` is a link you click, not a request the plugin makes. Your browser goes there to sign in and approve the connection, and comes back. The plugin makes no server-side call to devdome.com.

= Never sent, in any request =

* Passwords and password hashes.
* Form field values submitted by visitors.
* Post, page, comment or any other WordPress content.
* User accounts, user lists, or the email addresses of your registered users. The one exception is the site's administration email address, which is sent once during the connection handshake described above.
* Customer, order or payment data.
* Anything at all about what happens inside wp-admin.

== Privacy ==

**What is stored on your site.** Roughly twenty-five option rows: the tracking switches, the service addresses, this site's ID and secret token, your Account ID and account email, and the timestamp of the connection. Nothing else. No custom tables, no post meta, no user meta, and not one analytics event. Three short-lived transients are used: a connect handle (10 minutes), the cached bot-visit figure (1 hour), and a flood counter for the `/dd-e` endpoint that lives for 2 minutes and is keyed by an MD5 hash of the visitor's IP address.

**Public paths the plugin adds.** Two, and both only while the site is connected. `/dd-e` accepts the outbound-click beacon described in External services; it answers empty to everything else, ignores requests from excluded roles, is rate limited per IP address and stores nothing. `/.well-known/devdome-analytics.txt` returns one short line of fixed text and nothing else, so DevDome can confirm the plugin really is installed on the domain you connected.

**What is stored on a visitor's device.** Two settings decide this, and they are independent of each other.

* **Track Returning Visitors, off on new installs.** While it is off, the DevDome tracking script writes nothing at all: no cookie, no localStorage, no sessionStorage. Unique visitors are still counted, using an identifier DevDome derives on its own server from the request (site, date, IP address and user agent, combined with a secret key). It changes every day, is different on every site, and cannot be reversed to identify a person. The honest trade-off is that a visitor who returns tomorrow is counted as a new visitor. Turning the setting on stores a randomly generated visitor ID in a first-party cookie and in localStorage, plus a session ID in sessionStorage, so the same person is recognised across days and a click can be tied back to the visit it came from. Those are random values, not derived from anything personal, but they are storage on a visitor's device, so **you may need visitor consent for it**. The setting says so where you switch it on.
* **Track Outbound Links, on by default.** This is the exception to "nothing is stored". The built-in click detector stores two randomly generated IDs the first time a visitor clicks a link that leaves your site: `td_vid` in localStorage and `td_sid` in sessionStorage. It does this **even when Track Returning Visitors is off**, because a click has to be tied to the visit it came from to be worth anything. Visitors who never click an outbound link are unaffected. If you do not want it, switch Track Outbound Links off; a visitor whose browser sends the Do Not Track header never gets it either.

**Sites upgrading from an earlier version** keep returning-visitor tracking on, exactly as they behaved before, so nothing changes on a live site until you decide otherwise.

**IP addresses.** The plugin never stores a visitor's IP address on your site in readable form. It reaches DevDome in two ways: the tracking script connects to the service from the visitor's browser, so the service sees the connecting address the way any web server does; and when your server relays an outbound-link click it deliberately adds the visitor's real IP address to that event, because otherwise every relayed click would be attributed to your server. DevDome uses it for geolocation and per-visitor counts.

**How to turn things off.** Enable Tracking is the master switch, and turning it off stops all collection. Track Clicks, Track Outbound Links, Track AI Referrals and Track Bot Visits each switch off on their own. Do Not Track Admins is on by default. Excluded roles lets you name any role that must never be tracked; new installs start with Administrator and Editor. Respect Do Not Track is on by default and honours the browser signal.

**How to remove your data.** Disconnect stops everything immediately: the tracking script is no longer added to your pages, the `/dd-e` endpoint stops relaying, and the domain-verification file is no longer served. To delete what DevDome has already collected, either press Reset Analytics, or tick "Also delete my data on DevDome" while disconnecting. If you do neither, DevDome deletes it automatically after 90 days of inactivity. On your own site there is nothing to clean up beyond the option rows listed above: the plugin creates no tables and stores no analytics data locally.

== Installation ==

1. Install and activate the plugin from **Plugins > Add New**.
2. Open **DevDome > Analytics**.
3. Select **Connect Via DevDome Account**, or enter your DevDome Account ID manually.
4. Review the Settings tab and enable only the tracking features you want.

== Frequently Asked Questions ==

= Do I need a DevDome account? =

Yes. DevDome Analytics is a connector for the hosted DevDome Analytics service, where analytics events are processed and full reports are displayed. A free plan is available. No visitor data is collected until you connect the site.

= Does it remove all bot traffic from visitor reports? =

It detects known bots and AI crawlers and reports them separately from human visitors. Unknown, new, or deliberately disguised bots may not always be identifiable.

= Is anything sent before I connect? =

No. Before you connect, the tracking script is not added, analytics events are not sent, and no account or connection request is made.

= Does it set cookies? =

General traffic tracking is cookieless on new installs. Returning-visitor tracking is optional and disabled by default.

Outbound-link tracking stores random IDs in localStorage and sessionStorage after a visitor clicks an external link. Disable Track Outbound Links if you do not want that storage. See the Privacy section for full details.

= Can I exclude myself and my team? =

Yes. Logged-in administrators are excluded by default. You can exclude any additional WordPress role.

= Will it slow down my site? =

The tracking script loads asynchronously and does not block page rendering. The plugin does not write analytics events to your WordPress database.

= Does it work with caching plugins? =

Yes. The tracking snippet is the same for every visitor, so it works with full-page caching. Connecting or disconnecting also clears common page caches so the change is applied.

= Which crawlers can it report? =

The current detection list includes GPTBot, ChatGPT-User, ClaudeBot, PerplexityBot, Google-Extended, Bytespider, CCBot, Googlebot, bingbot, Slurp, DuckDuckBot, Baiduspider, YandexBot, AhrefsBot, SemrushBot, MJ12bot, DotBot, and Screaming Frog.

The plugin reports detected crawlers; it does not block them.

= What happens when I disconnect? =

Tracking stops immediately. You can also delete the site's hosted analytics data when disconnecting or by selecting Reset Analytics. Data that remains inactive is deleted automatically after 90 days.

= Does it support WordPress multisite? =

Yes. Each site connects separately and has its own settings, Site ID, and reports.

= Where do I see the reports? =

The WordPress Overview tab shows key metrics. Full traffic, referral, click, location, device, and crawler reports are available in your DevDome account.

== Source code ==

All of this plugin's PHP and JavaScript ships unminified and human-readable.

One file is generated: `assets/devdome-tools-tw.css`, the admin screen's stylesheet. It is a Tailwind CSS v3 utility bundle built from `src/tw.css` and `tailwind.config.cjs` with:

`npx tailwindcss -c tailwind.config.cjs -i src/tw.css -o assets/devdome-tools-tw.css --minify`

Those two build inputs are not included in the distributed package. Ask for them at https://devdome.com/contact and we will send them.

== Changelog ==

= 1.0.1 =
* No request is made to DevDome before you act: the one-click connect link is now requested only when you press "Connect Via DevDome Account", and the account check no longer runs until a connection has been started or completed. Off by default, opt-in by a button press.
* The connect screen now says exactly what connecting sends before you press the button.
* Every field of the relayed outbound-click event is individually validated and sanitized before it is forwarded, and the site and account identifiers in it now always come from the plugin's own settings, never from the request body.
* Request paths and IP addresses read from server variables are sanitized where they are read.

= 1.0.0 =
* First release on WordPress.org.
* The admin screen's styles and behaviour now load as enqueued files instead of inline blocks.
* The tracking snippet is enqueued too: the plugin no longer writes script tags into the page markup. Outbound-click counting is unchanged, including on sites where a blocker stops the tracker file from loading.
* Internal rename: every function, class, constant, option and transient the plugin owns now carries its own identifier prefix. Existing settings and your DevDome connection are carried across automatically.
* Fixed a fatal error that could break wp-admin on sites running several DevDome plugins when this one loaded first.
