GA4 Reporting
This module is available exclusively for Premium users.
The GA4 Reporting module builds seven pre-aggregated, dashboard-ready report tables on top of the core GA4Dataform outputs. Instead of writing (and re-writing) the same aggregation SQL in every BI tool, you connect Looker Studio, Power BI or any SQL client straight to small, stable tables with documented grains.
Most dashboard questions are the same five questions: where did my sessions come from, what converts, what did the shop do, which pages work, and what is consent mode hiding. These tables answer them from a few megabytes instead of scanning the raw event table - faster dashboards, lower BigQuery bills, and one shared definition of every metric.
The seven tables​
| Table | One row per | Answers |
|---|---|---|
ga4_reporting_acquisition_report | date x session dimensions | Where do sessions and revenue come from? Three attribution views side by side |
ga4_reporting_conversion_rates_report | date x event (+ drilldowns) | What is the session conversion rate after any event? |
ga4_reporting_ecommerce_report | date x currency | Daily shop totals: transactions, revenue, purchasers, refunds |
ga4_reporting_pages_report | date x page (+ dimensions) | Which pages get views, entrances, exits and engagement? |
ga4_reporting_consent_report | date (+ dimensions) | Consent rates, cookieless traffic and estimated hidden sessions |
ga4_reporting_currency_rates | date x currency | The daily USD conversion rate Google applied to your events |
ga4_reporting_item_sales_report | date x item attributes | Item-level sales and refunds from deduplicated transactions |
Column-level detail for every table: Output Tables.
Configuration​
The module uses a YAML configuration file: includes/custom/modules/ga4_reporting/config.yaml
A report builds when the module-level enabled and the report's own flag are both true:
version: 1
enabled: true
acquisition:
enabled: true
dimensions: []
events_to_exclude: []
conversion_rates:
enabled: true
conversion_events:
- purchase
events_to_exclude:
- user_engagement
- first_visit
- session_start
drilldowns:
default_channel_grouping: true
custom_channel_groupings: true
is_new_session: true
device_category: true
source: false
medium: false
campaign: false
source_medium: false
session_dimensions: []
ecommerce:
enabled: true
events_to_exclude: []
pages:
enabled: true
include_app_screens: false
dimensions: []
consent:
enabled: true
dimensions: []
currency:
enabled: true
events:
- purchase
master_currency: USD
item_sales:
enabled: true
Event metric columns come from CUSTOM_SESSION_TOTALS​
The acquisition and ecommerce reports derive their event columns from the ga4 module's CUSTOM_SESSION_TOTALS.eventsToCount: every configured event becomes an <event> column (total occurrences) plus an <event>_sessions column (sessions containing it). Add an event there and it appears in both reports on the next run.
events_to_exclude removes individual event columns from a report. It is an exact alias match - a typo fails compilation with the list of valid names, so misspellings cannot silently drop a column.
Custom dimensions​
dimensions (acquisition, pages, consent) and session_dimensions (conversion rates) accept three forms:
dimensions:
- device.language # a column path, auto-named
- { name: geo.city, renameTo: city } # a column path, renamed
- { sql: "IF(device.category = 'mobile', 'M', 'Not-M')", renameTo: mobile_split } # any SQL expression
Currency rates​
currency.events lists the events whose (value, value_in_usd) pairs feed the observed daily rate - extend it (e.g. with add_to_cart) to cover days without purchases. master_currency adds a conversion_rate_to_master column via same-day USD cross rates.
A dedicated dataset for BI users​
By default the report tables land in your outputs dataset. Two project variables in workflow_settings.yaml move them to their own dataset instead, so BI users can be granted access to the reports only - never the row-level event data:
REPORTING_DATASET_ENABLED: "true"
REPORTING_DATASET: superform_reporting_123456789
The installer seeds both variables (disabled, with the dataset name prepared) from Installer v2.2.12 on. On older installs, add them manually - when they are absent, the reports simply stay in OUTPUTS_DATASET.
Schema changes and rebuilds​
- Reports pick up added columns automatically (a new
eventsToCountentry, a new dimension, an enabled drilldown). - Removing a column-producing option (adding an
events_to_excludeentry, turning a drilldown orinclude_app_screensoff) requires a full refresh of that report - incremental runs can only add columns. The report tables are small, so this is cheap. - Changing
conversion_eventswarrants a rebuild of the conversion rates report: the counts live in a nestedconversionsstruct.
Migrating from GA4 Event Conversion Rate​
The former GA4 Event Conversion Rate module is retired; ga4_reporting_conversion_rates_report is its successor. What changes:
- Configuration moves from
ga4_event_conversion_rate/config.jsonto theconversion_ratessection ofga4_reporting/config.yaml(conversionEvents→conversion_events,eventsToExclude→events_to_exclude,sessionDimensions→session_dimensions). events_to_excludenow matches exact event names -%wildcards are no longer supported. Excludes are validated at compile time (typos and conversion-event overlaps fail with a clear error), which requires exact names - rewrite pattern entries likewebvitals_%as full event names.- The
is_new_sessiondrilldown was computed inverted in the old module; the new report fixes it. Expect new-vs-returning splits to swap compared to old dashboards. - The old
ga4_event_conversion_rates_reporttable is not deleted by the update - drop it manually once your dashboards point at the new table.