=== Analytics Head ===

Contributors: lukasznowicki
Donate link: https://paypal.me/lukasznowicki77
Tags: analytics, tracking, gtag, ga4, lightweight
Requires at least: 6.3
Tested up to: 7.0
Requires PHP: 7.4
Stable tag: 1.7.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

A lightweight Google Analytics plugin for WordPress. Paste your Measurement ID, choose head or footer — done.

== Description ==

**Analytics Head** is a deliberately simple WordPress plugin for Google Analytics. No dashboards, no Google account connection, no feature creep — just the tracking code, placed exactly where you want it.

**Why use this plugin?**

* **Lightweight** — a handful of options, minimal overhead, no external dependencies
* **Easy** — paste your GA4 Measurement ID (G-XXXXXXXXXX) and you are done
* **Head placement by default** — required for Google Search Console verification via Analytics
* **Flexible** — footer placement, role-based hiding, Consent Mode v2, optional Google Ads IDs
* **Developer-friendly** — filters and actions to customize output without forking the plugin

Unlike heavyweight analytics suites, this plugin does one job well: inject the standard gtag.js snippet into your site.

= Features =

* Google tag / GA4 Measurement ID support (GT-…, G-XXXXXXXXXX)
* Additional tracking IDs for separate destinations (e.g. Google Ads AW-)
* Legacy UA- ID acceptance (with admin notice to migrate)
* Code in `<head>` by default (optional footer placement)
* Tracking never injected in wp-admin
* Hide tracking for administrators on the front end
* Hide tracking per user role
* Google Consent Mode v2 defaults (for GDPR / cookie plugins)
* Keep settings on uninstall (optional)
* Developer hooks and filters

= External services =

This plugin connects to **Google Analytics** (via Google Tag Manager / gtag.js) to provide website analytics.

* **When:** on public front-end page views only (never in the WordPress admin area), unless tracking is hidden for the current visitor by plugin settings
* **What is sent:** standard Google Analytics measurement data (for example page URL, referrer, browser/device information, and IP-derived location), processed by Google
* **Who receives it:** Google LLC / Google Analytics
* **Terms of Service:** https://marketingplatform.google.com/about/analytics/terms/us/
* **Privacy Policy:** https://policies.google.com/privacy

You are responsible for informing visitors (for example in your privacy policy) and, where required, obtaining consent. Suggested privacy policy text is also offered under Settings → Privacy when the plugin is active.

= Requirements =

* WordPress 6.3 or later (compatible with WordPress 7+)
* PHP 7.4 or later

== Installation ==

1. Upload the `analytics-head` directory to `/wp-content/plugins/`
2. Activate the plugin through the **Plugins** menu in WordPress
3. Go to **Settings → Analytics Head**
4. Enter your GA4 Measurement ID (G-XXXXXXXXXX)
5. Save — tracking starts immediately

== Frequently Asked Questions ==

= How do I get a Measurement ID? =

Sign in to [Google Analytics](https://analytics.google.com/), create a GA4 property for your site, and copy the Measurement ID (format `G-XXXXXXXXXX`) or Google tag ID (`GT-…`) from Admin → Data Streams. Use only one ID per Google tag — do not enter both the GT- and G- IDs that belong to the same tag.

= Why place the code in the head section? =

Google Search Console can verify site ownership via your Analytics tag, but only when the tag is in the `<head>`. You can move it to the footer anytime in plugin settings.

= Do I need to connect my Google account? =

No. This plugin only inserts the tracking snippet — no OAuth, no API keys, no Google login.

= How does Consent Mode work? =

Enable **Consent Mode v2** under Privacy in the plugin settings. Before gtag.js loads, this plugin sets:

* `analytics_storage` → denied
* `ad_storage` → denied
* `ad_user_data` → denied
* `ad_personalization` → denied
* `wait_for_update` → 500 ms

The tracking script still loads (that is how Consent Mode works). Until consent is granted, Google receives only limited, cookieless signals.

When the visitor accepts cookies, your GDPR / cookie banner plugin (or custom JavaScript) should call `gtag('consent', 'update', …)` and grant the same four storage types (see Examples). Granting only `analytics_storage` and `ad_storage` would leave ad user data / personalization permanently denied.

Most modern consent plugins that support **Google Consent Mode** already do this for you. Enable Consent Mode here, then enable Google Consent Mode / Analytics support in your consent plugin.

= Does this block the Analytics script until consent? =

No. Consent Mode is not a hard block. The script is always injected; consent defaults start as denied and are updated later. If you need to delay or remove the script until opt-in, use a consent plugin that hard-blocks tags, or filter `pp_google_analytics_head_tracking_ids` to return an empty list until consent is given.

= Which GDPR plugins work with this? =

Any plugin that can run `gtag('consent', 'update', …)` after the user accepts — for example Complianz, CookieYes, Borlabs Cookie, Cookiebot (when Google Consent Mode is enabled in that plugin). There is no proprietary bridge to a single vendor; we stay lightweight and use the standard Google API.

= What if I know PHP? =

Available hooks and filters (see the Examples section for code):

* `pp_google_analytics_head_before` — action, before scripts are enqueued
* `pp_google_analytics_head_after` — action, after scripts are enqueued
* `pp_google_analytics_head_inline_script` — filter, modify the inline gtag config script (`$script`, `$ids`)
* `pp_google_analytics_head_tracking_ids` — filter, modify the list of Measurement / Ads IDs (`$ids`, `$options`)
* `pp_google_analytics_head_consent_defaults` — filter, modify Consent Mode defaults (`analytics_storage`, `ad_storage`, `ad_user_data`, `ad_personalization`, `wait_for_update`, optional `region` using ISO 3166-2 region codes)
* `pp_google_analytics_head_roles` — filter, modify roles available in visibility settings

**Note:** The old `pp_google_analytics_head_output` HTML filter was removed in 1.7.0 (it was incompatible with `wp_enqueue_script`). Use `pp_google_analytics_head_inline_script` or `pp_google_analytics_head_tracking_ids` instead.

= Is it free? =

Yes, GPLv2 or later. Donations are welcome but never required.

== Screenshots ==

1. Settings page — paste your Measurement ID and choose placement.

== Examples ==

= Filter tracking IDs =

`add_filter( 'pp_google_analytics_head_tracking_ids', function( $ids ) {
	// Add a separate destination only — not a second ID for the same Google tag.
	$ids[] = 'AW-123456789';
	return $ids;
} );`

= Change Consent Mode defaults (PHP) =

`add_filter( 'pp_google_analytics_head_consent_defaults', function( $defaults ) {
	$defaults['wait_for_update'] = 2000;
	$defaults['region'] = [ 'PL', 'DE', 'US-CA' ];
	return $defaults;
} );`

= Grant consent after the user accepts cookies (JavaScript) =

Call this from your consent plugin callback or custom banner “Accept” handler. Update all four types that this plugin sets to denied by default:

`gtag('consent', 'update', {
	analytics_storage: 'granted',
	ad_storage: 'granted',
	ad_user_data: 'granted',
	ad_personalization: 'granted'
});`

If you only want basic analytics (not ads), grant analytics and keep ads denied:

`gtag('consent', 'update', {
	analytics_storage: 'granted',
	ad_storage: 'denied',
	ad_user_data: 'denied',
	ad_personalization: 'denied'
});`

= Modify the inline gtag config =

`add_filter( 'pp_google_analytics_head_inline_script', function( $script, $ids ) {
	$script .= "gtag('event','page_view');";
	return $script;
}, 10, 2 );`

== Changelog ==

= 1.7.0 =
* Release date: 2026-07-28
* Renamed display name to Analytics Head (WordPress.org naming guidelines)
* Google tag / GA4 ID support (GT-, G-) and Google Ads IDs (AW-)
* WordPress 6.3+ and PHP 7.4+ requirement; async script strategy; tested with WordPress 7+
* Translations via WordPress Polyglots (removed bundled language files)
* Output via wp_enqueue_script with real async strategy (inline gtag queued as before)
* Tracking IDs resolved once during wp_enqueue_scripts (late filters / conditional tags work)
* Consent Mode v2 defaults for GDPR / cookie plugin integration (including optional region)
* No wp-admin tracking; role-based front-end visibility via wp_roles()
* Optional keep settings on uninstall (batched multisite cleanup)
* External service documentation and privacy policy helper text
* Invalid IDs no longer wipe previously saved values; filter validation hardened

= 1.6.7 =
* Release date: 2018-11-21
* Set compatibility tag

== Upgrade Notice ==

= 1.7.0 =
Major update: GA4 support, Consent Mode, role-based hiding, lighter codebase. WordPress 6.3+ and PHP 7.4+ required. The legacy pp_google_analytics_head_output filter was removed — use the new filters. Replace UA- IDs with GA4 G- IDs.
