Google Analytics 4 and Search Console, right inside your WHMCS admin.
Stop tab-hopping between WHMCS, Google Analytics, and Search Console. WHMCS Analytics puts your website's traffic and SEO data where you actually work - the WHMCS admin dashboard. It installs like any addon module and runs on a stock WHMCS install with no template edits.
Only aggregate metrics (top queries, pages, countries, and KPIs) are ever sent - never visitor personal data - and nothing leaves your server until you ask for advice.
Store Search Console history in the backend you choose:
8.0+ or MariaDB 10.2+
Be the first to review WHMCS Analytics.
The best place to start if you need help with a specific product is to contact the developer. All WHMCS Marketplace developers have both a website and support URL listed.
All notable changes to this project are documented here. The format is based on Keep a Changelog, and this project follows Semantic Versioning.
Changes for the next release go here. Suggested headings: Added, Changed, Fixed, Removed, Security.
alert_traffic_pct, default 20%).getBasePixel and flooded the
console with "skip" errors (and broke the native System Overview graph). The
module now loads its own Chart.js v4 in isolation and restores the host's
global, so both charts work.ResizeObserver) when tall content such as Search Console loads, so neighbouring
widgets no longer overlap.maxOutputTokens 1300 → 8192, and OpenAI/Anthropic/DeepSeek
max_tokens 1300 → 2500.whmcs.json + logo.png).AdminHomeWidgets hook and is
self-contained under modules/addons/whmcs_analytics/ (no modules/widgets/
file), resolving the widget not appearing and a class-redeclaration crash when
a stale copy was left behind. Widget uses the full-width embed styling and a
masonry re-layout nudge so neighbouring widgets no longer overlap.Repackaged as a generic, public WHMCS addon. Works on a stock WHMCS install with no theme edits: the dashboard is available both as a WHMCS dashboard widget and on the addon's own Dashboard tab.
lib/Db/*, lib/Storage.php). Choose the backend in the settings:
lib/AiAdvisor.php, dashboard SEO Advisor tab) —
bring-your-own-key LLM (OpenAI default, Anthropic/Claude, DeepSeek) that turns a
GA4 + Search Console snapshot into prioritized recommendations. Consent-gated:
an aggregate snapshot (top queries/pages/countries + KPIs, no visitor PII) is
sent only when an admin clicks Get advice. Provider/model/key configured in
settings; advice rendered from Markdown.FULL OUTER JOIN replaced with a UNION-of-keys +
LEFT JOIN so comparisons run on both MySQL and libSQL; the week bucket and
schema/upsert DDL are dialect-specific per driver.whmcs_analytics, namespace
WhmcsAnalytics, widget WhmcsAnalyticsWidget, settings table
mod_whmcs_analytics, display name WHMCS Analytics. (CSS/JS class prefixes
kept as-is internally.)BUNNY_DB_*, bunny.config.php) and BUNNY_SETUP.md are
removed in favor of in-UI configuration. See STORAGE.md.whmcs_analytics.php) — the full analytics
dashboard is now available directly at Addons → WHMCS Analytics, not
only the admin homepage. A Dashboard / Settings tab bar at the top switches
between the live dashboard and the connection/threshold settings
(?view=settings). Same UI + assets as the homepage embed and the widget.assets/geomap.js) — darker, more saturated ramp and a
square-root colour scale so a single dominant country no longer washes the rest
of the map out to near-white; mid-tier countries now read clearly. The legend
and tooltips still display the real (un-scaled) figures.assets/geomap.js, bundled
assets/echarts.min.js v5.5.1 + assets/world.geo.json) — a heat-shaded,
zoomable/pannable ECharts choropleth now sits above the country tables in both
the GA4 Countries tab (shaded by users) and the Search Console Countries
view (shaded by impressions). ECharts and the GeoJSON load lazily and only once.
CpgaGeoMap.render() resolves country keys from ISO alpha-2 (GA4 countryId),
ISO alpha-3 (Search Console), or English name to the map's ISO-3 keys, and
adapts its palette to light/dark admin themes. The existing tables are kept
intact beneath each map.ajax.php) now returns a geo payload carrying
both the map dataset (with ISO country codes via the countryId dimension) and
the original table rows.assets/ga.js) — GA time-series line charts get point-style
legends/tooltips, thousands-separated values, and cleaner axes.assets/gsc.js) showed undefined in their
tooltips because the datasets had no label. Each chart (Position / Clicks /
Impressions / CTR) now carries its metric name and a formatted tooltip.lib/Bunny.php) — dependency-free
libSQL HTTP pipeline client over cURL. Credentials read from server env vars
(BUNNY_DB_URL / BUNNY_DB_TOKEN / BUNNY_DB_READONLY_TOKEN) with a protected
config/bunny.config.php fallback. Read path uses the read-only token.lib/GscStore.php) — per-dimension daily tables (query,
page, country, device, search appearance) + daily totals + per-query meta
(first/last seen, best/worst position) + per-site sync state. Impression-
weighted average position; week-over-week and period-over-period comparisons
computed at read time.lib/GscSync.php, hooks.php DailyCronJob,
cron/gsc_sync.php) — incremental trailing-window refresh + resumable monthly
backfill (default 12 months), time-boxed. Manual Sync button on the
dashboard loops until backfill completes.lib/GscApi.php) — Bunny-backed endpoints: view, summary,
movers, opportunities, detail, sync, status. Full sorting (incl.
position/click/impression/CTR change), filtering (text, min impressions/clicks,
position range, movement), and comparison handling. Keyword-detail breakdowns
(pages/countries/devices for one query) fetched live from Google.assets/gsc.js, assets/gsc.css) — replaces the
simple keywords table with a view switcher, filter + comparison bar, sortable
movement table with accessible badges (↑/↓/–/New/Lost), summary cards, Top
Movers, Opportunities, and a keyword detail drawer with four separate charts
(Position over time uses a reversed axis so position 1 is at the top).searchAnalyticsAll() paging helper (startRow paging) for
full-range ingestion.BUNNY_SETUP.md, SEARCH_CONSOLE.md.
All notable changes to this project are documented here. The format is based on Keep a Changelog, and this project follows Semantic Versioning.
Changes for the next release go here. Suggested headings: Added, Changed, Fixed, Removed, Security.
maxOutputTokens 1300 → 8192, and OpenAI/Anthropic/DeepSeek
max_tokens 1300 → 2500.whmcs.json + logo.png).AdminHomeWidgets hook and is
self-contained under modules/addons/whmcs_analytics/ (no modules/widgets/
file), resolving the widget not appearing and a class-redeclaration crash when
a stale copy was left behind. Widget uses the full-width embed styling and a
masonry re-layout nudge so neighbouring widgets no longer overlap.Repackaged as a generic, public WHMCS addon. Works on a stock WHMCS install with no theme edits: the dashboard is available both as a WHMCS dashboard widget and on the addon's own Dashboard tab.
lib/Db/*, lib/Storage.php). Choose the backend in the settings:
lib/AiAdvisor.php, dashboard SEO Advisor tab) —
bring-your-own-key LLM (OpenAI default, Anthropic/Claude, DeepSeek) that turns a
GA4 + Search Console snapshot into prioritized recommendations. Consent-gated:
an aggregate snapshot (top queries/pages/countries + KPIs, no visitor PII) is
sent only when an admin clicks Get advice. Provider/model/key configured in
settings; advice rendered from Markdown.FULL OUTER JOIN replaced with a UNION-of-keys +
LEFT JOIN so comparisons run on both MySQL and libSQL; the week bucket and
schema/upsert DDL are dialect-specific per driver.whmcs_analytics, namespace
WhmcsAnalytics, widget WhmcsAnalyticsWidget, settings table
mod_whmcs_analytics, display name WHMCS Analytics. (CSS/JS class prefixes
kept as-is internally.)BUNNY_DB_*, bunny.config.php) and BUNNY_SETUP.md are
removed in favor of in-UI configuration. See STORAGE.md.whmcs_analytics.php) — the full analytics
dashboard is now available directly at Addons → WHMCS Analytics, not
only the admin homepage. A Dashboard / Settings tab bar at the top switches
between the live dashboard and the connection/threshold settings
(?view=settings). Same UI + assets as the homepage embed and the widget.assets/geomap.js) — darker, more saturated ramp and a
square-root colour scale so a single dominant country no longer washes the rest
of the map out to near-white; mid-tier countries now read clearly. The legend
and tooltips still display the real (un-scaled) figures.assets/geomap.js, bundled
assets/echarts.min.js v5.5.1 + assets/world.geo.json) — a heat-shaded,
zoomable/pannable ECharts choropleth now sits above the country tables in both
the GA4 Countries tab (shaded by users) and the Search Console Countries
view (shaded by impressions). ECharts and the GeoJSON load lazily and only once.
CpgaGeoMap.render() resolves country keys from ISO alpha-2 (GA4 countryId),
ISO alpha-3 (Search Console), or English name to the map's ISO-3 keys, and
adapts its palette to light/dark admin themes. The existing tables are kept
intact beneath each map.ajax.php) now returns a geo payload carrying
both the map dataset (with ISO country codes via the countryId dimension) and
the original table rows.assets/ga.js) — GA time-series line charts get point-style
legends/tooltips, thousands-separated values, and cleaner axes.assets/gsc.js) showed undefined in their
tooltips because the datasets had no label. Each chart (Position / Clicks /
Impressions / CTR) now carries its metric name and a formatted tooltip.lib/Bunny.php) — dependency-free
libSQL HTTP pipeline client over cURL. Credentials read from server env vars
(BUNNY_DB_URL / BUNNY_DB_TOKEN / BUNNY_DB_READONLY_TOKEN) with a protected
config/bunny.config.php fallback. Read path uses the read-only token.lib/GscStore.php) — per-dimension daily tables (query,
page, country, device, search appearance) + daily totals + per-query meta
(first/last seen, best/worst position) + per-site sync state. Impression-
weighted average position; week-over-week and period-over-period comparisons
computed at read time.lib/GscSync.php, hooks.php DailyCronJob,
cron/gsc_sync.php) — incremental trailing-window refresh + resumable monthly
backfill (default 12 months), time-boxed. Manual Sync button on the
dashboard loops until backfill completes.lib/GscApi.php) — Bunny-backed endpoints: view, summary,
movers, opportunities, detail, sync, status. Full sorting (incl.
position/click/impression/CTR change), filtering (text, min impressions/clicks,
position range, movement), and comparison handling. Keyword-detail breakdowns
(pages/countries/devices for one query) fetched live from Google.assets/gsc.js, assets/gsc.css) — replaces the
simple keywords table with a view switcher, filter + comparison bar, sortable
movement table with accessible badges (↑/↓/–/New/Lost), summary cards, Top
Movers, Opportunities, and a keyword detail drawer with four separate charts
(Position over time uses a reversed axis so position 1 is at the top).searchAnalyticsAll() paging helper (startRow paging) for
full-range ingestion.BUNNY_SETUP.md, SEARCH_CONSOLE.md.
All notable changes to this project are documented here. The format is based on Keep a Changelog, and this project follows Semantic Versioning.
Changes for the next release go here. Suggested headings: Added, Changed, Fixed, Removed, Security.
whmcs.json + logo.png).AdminHomeWidgets hook and is
self-contained under modules/addons/whmcs_analytics/ (no modules/widgets/
file), resolving the widget not appearing and a class-redeclaration crash when
a stale copy was left behind. Widget uses the full-width embed styling and a
masonry re-layout nudge so neighbouring widgets no longer overlap.Repackaged as a generic, public WHMCS addon. Works on a stock WHMCS install with no theme edits: the dashboard is available both as a WHMCS dashboard widget and on the addon's own Dashboard tab.
lib/Db/*, lib/Storage.php). Choose the backend in the settings:
lib/AiAdvisor.php, dashboard SEO Advisor tab) —
bring-your-own-key LLM (OpenAI default, Anthropic/Claude, DeepSeek) that turns a
GA4 + Search Console snapshot into prioritized recommendations. Consent-gated:
an aggregate snapshot (top queries/pages/countries + KPIs, no visitor PII) is
sent only when an admin clicks Get advice. Provider/model/key configured in
settings; advice rendered from Markdown.FULL OUTER JOIN replaced with a UNION-of-keys +
LEFT JOIN so comparisons run on both MySQL and libSQL; the week bucket and
schema/upsert DDL are dialect-specific per driver.whmcs_analytics, namespace
WhmcsAnalytics, widget WhmcsAnalyticsWidget, settings table
mod_whmcs_analytics, display name WHMCS Analytics. (CSS/JS class prefixes
kept as-is internally.)BUNNY_DB_*, bunny.config.php) and BUNNY_SETUP.md are
removed in favor of in-UI configuration. See STORAGE.md.whmcs_analytics.php) — the full analytics
dashboard is now available directly at Addons → WHMCS Analytics, not
only the admin homepage. A Dashboard / Settings tab bar at the top switches
between the live dashboard and the connection/threshold settings
(?view=settings). Same UI + assets as the homepage embed and the widget.assets/geomap.js) — darker, more saturated ramp and a
square-root colour scale so a single dominant country no longer washes the rest
of the map out to near-white; mid-tier countries now read clearly. The legend
and tooltips still display the real (un-scaled) figures.assets/geomap.js, bundled
assets/echarts.min.js v5.5.1 + assets/world.geo.json) — a heat-shaded,
zoomable/pannable ECharts choropleth now sits above the country tables in both
the GA4 Countries tab (shaded by users) and the Search Console Countries
view (shaded by impressions). ECharts and the GeoJSON load lazily and only once.
CpgaGeoMap.render() resolves country keys from ISO alpha-2 (GA4 countryId),
ISO alpha-3 (Search Console), or English name to the map's ISO-3 keys, and
adapts its palette to light/dark admin themes. The existing tables are kept
intact beneath each map.ajax.php) now returns a geo payload carrying
both the map dataset (with ISO country codes via the countryId dimension) and
the original table rows.assets/ga.js) — GA time-series line charts get point-style
legends/tooltips, thousands-separated values, and cleaner axes.assets/gsc.js) showed undefined in their
tooltips because the datasets had no label. Each chart (Position / Clicks /
Impressions / CTR) now carries its metric name and a formatted tooltip.lib/Bunny.php) — dependency-free
libSQL HTTP pipeline client over cURL. Credentials read from server env vars
(BUNNY_DB_URL / BUNNY_DB_TOKEN / BUNNY_DB_READONLY_TOKEN) with a protected
config/bunny.config.php fallback. Read path uses the read-only token.lib/GscStore.php) — per-dimension daily tables (query,
page, country, device, search appearance) + daily totals + per-query meta
(first/last seen, best/worst position) + per-site sync state. Impression-
weighted average position; week-over-week and period-over-period comparisons
computed at read time.lib/GscSync.php, hooks.php DailyCronJob,
cron/gsc_sync.php) — incremental trailing-window refresh + resumable monthly
backfill (default 12 months), time-boxed. Manual Sync button on the
dashboard loops until backfill completes.lib/GscApi.php) — Bunny-backed endpoints: view, summary,
movers, opportunities, detail, sync, status. Full sorting (incl.
position/click/impression/CTR change), filtering (text, min impressions/clicks,
position range, movement), and comparison handling. Keyword-detail breakdowns
(pages/countries/devices for one query) fetched live from Google.assets/gsc.js, assets/gsc.css) — replaces the
simple keywords table with a view switcher, filter + comparison bar, sortable
movement table with accessible badges (↑/↓/–/New/Lost), summary cards, Top
Movers, Opportunities, and a keyword detail drawer with four separate charts
(Position over time uses a reversed axis so position 1 is at the top).searchAnalyticsAll() paging helper (startRow paging) for
full-range ingestion.BUNNY_SETUP.md, SEARCH_CONSOLE.md.
Send WHMCS GA 4 Enhanced Ecommerce Data Layer to any tag with GTM WHMCS
Build dynamic reports, schedule their creation and email the results to your staff members.
Intercom Addon Module integrates Intercom.io customer platform into WHMCS.
Access MetricsCube business reports with user tracking and data comparison features.