Google Analytics Plugin for dotCMS - Setup Guide
OSGi plugin that integrates Google Analytics Data API (GA4) with dotCMS, allowing you to fetch analytics data programmatically using Velocity viewtools.
What It Does#
This plugin provides a $analytics viewtool in Velocity templates that lets you query Google Analytics 4 (GA4) data directly from your dotCMS pages. You can retrieve metrics like active users, page views, sessions, and more, filtered by dimensions like date, page path, device category, etc.
Note: This plugin is for fetching analytics data from Google Analytics into dotCMS. It does NOT add tracking code to your site. For tracking, use Google Tag Manager or add the GA4 tracking script directly to your templates.
Prerequisites#
Before installing this plugin, you need:
- dotCMS 23.01.10 or higher
- Google Cloud Platform account with billing enabled
- Google Analytics 4 (GA4) property with data to query
- Service account JSON credentials from Google Cloud
Google Cloud Platform Setup#
Step 1: Create or Select a Project#
- Go to Google Cloud Console
- Create a new project or select an existing one that should have access to your GA4 data
- Make sure billing is enabled for the project
Step 2: Enable Google Analytics Data API#
- In Google Cloud Console, go to APIs & Services → Library
- Search for "Google Analytics Data API"
- Click on it and click Enable
- Wait for the API to be enabled (takes a few seconds)
Step 3: Create a Service Account#
- Go to IAM & Admin → Service Accounts
- Click Create Service Account
- Fill in the details:
- Service account name:
dotcms-analytics(or any name you prefer) - Service account description: "Service account for dotCMS to access GA4 data"
- Service account name:
- Click Create and Continue
- Skip the optional "Grant this service account access to project" step (click Continue)
- Skip the "Grant users access to this service account" step (click Done)
Step 4: Create and Download JSON Key File#
- In the Service Accounts list, click on the service account you just created
- Go to the Keys tab
- Click Add Key → Create new key
- Select JSON as the key type
- Click Create
- A JSON file will be downloaded to your computer - save this file securely
- Copy the service account email (looks like
dotcms-analytics@your-project-id.iam.gserviceaccount.com) - you'll need this for the next step
Google Analytics Setup#
Grant Service Account Access to GA4 Property#
- Go to Google Analytics
- Click Admin (gear icon in bottom left)
- In the Property column, click Property Access Management
- Click the + button in the top right
- Click Add users
- Paste the service account email from Step 4 above
- Assign the Viewer role (this gives read-only access to analytics data)
- Uncheck "Notify new users by email" (service accounts don't have email)
- Click Add
Get Your GA4 Property ID#
- Still in Google Analytics Admin, click Property Settings
- Look for Property ID at the top (it's a number like
123456789) - Copy this number - you'll use it in Velocity as
properties/YOUR_PROPERTY_ID
Installation#
Step 1: Build the Plugin (or Download Release)#
Option A: Download pre-built JAR (when available)
- Download
google-analytics-0.4.1.jarfrom GitHub Releases
Option B: Build from source
git clone https://github.com/dotCMS/google-analytics.git cd google-analytics ./gradlew jar
The JAR will be at build/libs/google-analytics-0.4.1.jar
Step 2: Upload to dotCMS#
- Log into your dotCMS instance as an admin
- Go to System → Dynamic Plugins (or Dev Tools → Plugins depending on your version)
- Click Upload Plugin
- Select the
google-analytics-0.4.1.jarfile - Wait for the upload and installation to complete
- Check the dotCMS logs for the message:
Starting Google Analytics OSGI plugin
If successful, the plugin is now installed.
Configuration#
Configure the Google Analytics App in dotCMS#
- Go to System → Apps
- Find Google Analytics in the list of available apps
- Click on it to configure
- Fill in the configuration:
- Application Name: Any descriptive name (e.g., "My GA4 Property")
- Json Key File:
- Open the JSON key file you downloaded from Google Cloud
- Copy the entire contents of the file
- Paste it into this field
- Click Save
The app is now configured and ready to use.
Usage#
Using the $analytics Viewtool#
The plugin provides a $analytics viewtool in Velocity templates with two main methods:
1. Create an Analytics Request#
#set($propertyId = "properties/123456789") ## Replace with your GA4 Property ID #set($request = $analytics.createAnalyticsRequest($propertyId))
2. Configure the Request#
Set date range, metrics, and dimensions:
## Set date range (YYYY-MM-DD format) $gaRequest.setStartDate("2026-02-09") $gaRequest.setEndDate("2026-02-16") ## Set metrics (comma-separated) - REQUIRED for GA4 $gaRequest.setMetrics("activeUsers,sessions") ## Set dimensions (optional, comma-separated) $gaRequest.setDimensions("date,pagePath") ## Set filters (optional) $gaRequest.setFilters("pagePath==/products") ## Set max results (optional, default: 1000, max: 10000) $gaRequest.setMaxResults(100)
3. Execute the Query#
#set($gaResponse = $analytics.query($gaRequest))
4. Process the Response#
The response is a RunReportResponse object from the Google Analytics Data API:
## Get row count <p>Total rows: $gaResponse.getRowCount()</p> ## Iterate through rows #foreach($row in $gaResponse.getRowsList()) <p> Date: $row.getDimensionValues(0).getValue() Active Users: $row.getMetricValues(0).getValue() </p> #end
IMPORTANT: Always use unique variable names like $gaRequest and $gaResponse instead of $request and $response, which are reserved Velocity variables for HTTP request/response objects.
Complete Example#
<h2>Last 7 Days Analytics</h2> ## Your GA4 property ID (just the number, not "properties/123") #set($propertyId = "123456789") ## Create request #set($gaRequest = $analytics.createAnalyticsRequest($propertyId)) ## Configure request $gaRequest.setStartDate("2026-02-09") $gaRequest.setEndDate("2026-02-16") $gaRequest.setMetrics("activeUsers,sessions") $gaRequest.setDimensions("date") ## Execute query #set($gaResponse = $analytics.query($gaRequest)) ## Display results <table> <thead> <tr> <th>Date</th> <th>Active Users</th> <th>Sessions</th> </tr> </thead> <tbody> #foreach($row in $gaResponse.getRowsList()) <tr> <td>$row.getDimensionValues(0).getValue()</td> <td>$row.getMetricValues(0).getValue()</td> <td>$row.getMetricValues(1).getValue()</td> </tr> #end </tbody> </table>
Available Metrics and Dimensions#
Refer to the Google Analytics Data API documentation for the full list of available metrics and dimensions.
Common Metrics#
activeUsers- Number of distinct users who visited your sitesessions- Number of sessionspageviews- Total number of page viewsscreenPageViews- Total page and screen viewsbounceRate- Percentage of single-page sessionsaverageSessionDuration- Average duration of sessions in seconds
Common Dimensions#
date- Date in YYYYMMDD formatpagePath- Page path (e.g., /products/item-1)country- User's countrydeviceCategory- Device type (desktop, mobile, tablet)browser- Browser nameoperatingSystem- Operating system name
Troubleshooting#
OSGi Bundle Resolution Errors#
If you see errors like:
Unable to resolve google-analytics: missing requirement osgi.wiring.package; com.aayushatharva.brotli4j Unable to resolve google-analytics: missing requirement osgi.wiring.package; com.github.luben.zstd Unable to resolve google-analytics: missing requirement osgi.wiring.package; com.jcraft.jzlib
Cause: The Google Analytics Data API library has many transitive dependencies (compression libraries, gRPC, Netty, etc.) that conflict with OSGi bundle wiring.
Solution: This has been fixed in version 0.4.1 by excluding all third-party packages from OSGi imports (they're bundled inside the JAR instead). Make sure you're using the latest build from the repository.
If building from source: The build.gradle has been updated with proper Import-Package exclusions. If you're using an older version of the repo, pull the latest changes.
Activator Start Error: NoClassDefFoundError: org.apache.velocity.tools.view.ToolInfo#
If you see:
Activator start error in bundle google-analytics Caused by: java.lang.NoClassDefFoundError: org/apache/velocity/tools/view/ToolInfo
Cause: The plugin's OSGi Import-Package configuration is missing Velocity tool imports.
Solution: This has been fixed in version 0.4.1. The org.apache.velocity.* packages are now properly imported from dotCMS. Use the latest build.
Plugin won't install#
- Check dotCMS version is 23.01.10 or higher
- Check dotCMS logs at
tomcat/webapps/ROOT/dotsecure/logs/dotcms.logfor detailed error messages - If using Docker/local install, the OSGi framework may be more strict about dependency resolution than cloud/demo instances
$analytics viewtool not available#
- Verify plugin installed successfully (check logs for "Starting Google Analytics OSGI plugin")
- Restart dotCMS after plugin installation
- Check that the viewtool is registered in the Velocity toolbox
- Try accessing through toolbox:
#set($gaTool = $veltools.get("analytics"))
"App not configured" error#
- Make sure you configured the Google Analytics app in System → Apps
- Verify the JSON key file was pasted completely (it should start with
{and end with}) - Check that the Application Name was filled in
"Permission denied" or "403" errors#
- Verify the service account email was added to GA4 Property Access Management
- Verify the service account has "Viewer" role
- Check that the Property ID is correct (format:
properties/123456789)
No data returned#
- Verify your GA4 property has data for the date range you're querying
- Check that the Property ID is correct
- Verify metrics and dimensions are valid (see Google Analytics Data API docs)
- Try querying a broader date range
Error: "Field ga:visits is not a valid metric"#
If you see:
INVALID_ARGUMENT: Field ga:visits is not a valid metric
Cause: The plugin defaults to ga:visits which is a Universal Analytics (GA3) metric. GA4 uses different metric names.
Solution: Always explicitly set metrics using setMetrics() with GA4 metric names:
$gaRequest.setMetrics("activeUsers") ## GA4 metric ## NOT: ga:visits (old GA3 metric)
See the GA4 API Schema for valid GA4 metrics.
Variable name conflicts: $request or $response showing wrong class#
If $request shows VelocityRequestWrapper or $response shows UrlRewriteWrappedResponse:
Cause: $request and $response are reserved Velocity variables for HTTP request/response objects.
Solution: Use unique variable names:
#set($gaRequest = $analytics.createAnalyticsRequest($propertyId)) ## NOT $request #set($gaResponse = $analytics.query($gaRequest)) ## NOT $response
Wrong data or unexpected results#
- Double-check your metric and dimension names match the GA4 Data API schema
- Verify your filters are correctly formatted
- Check the date range is what you expect
- Make sure you're using the property ID as just the number (e.g.,
"123456789"), not"properties/123456789"(the plugin adds the prefix automatically)
Version History#
- 0.4.1 - Current version
- Uses Google Analytics Data API v1beta
- Compatible with dotCMS 23.01.10+
- Supports GA4 properties
Resources#
- GitHub: https://github.com/dotCMS/google-analytics
- dotCMS Documentation: https://www.dotcms.com/docs
- Google Analytics Data API: https://developers.google.com/analytics/devguides/reporting/data/v1
Developer Notes#
OSGi Import-Package Configuration#
The plugin uses a whitelist approach for OSGi Import-Package to avoid dependency conflicts. The build.gradle explicitly imports only what's needed from dotCMS and the JVM:
'Import-Package': ''' !com.google.*, !com.aayushatharva.*, !com.github.luben.*, !com.jcraft.*, !com.ning.*, !io.netty.*, !io.grpc.*, !io.perfmark.*, !io.opencensus.*, !org.conscrypt.*, !org.codehaus.*, !org.checkerframework.*, !org.threeten.*, javax.*, org.osgi.*, org.apache.commons.io.*, org.apache.felix.*, org.apache.logging.log4j.*, org.apache.velocity.*, com.dotcms.*, com.dotmarketing.*, com.liferay.* '''
All Google Analytics Data API dependencies (gRPC, Protobuf, compression libraries, etc.) are bundled inside the plugin JAR via the Bundle-ClassPath mechanism.
Building from Source#
If you need to modify the plugin:
- Clone the repository
- Make your changes
- Build with
./gradlew clean jar - The JAR will be in
build/libs/google-analytics-0.4.1.jar - Test in a local dotCMS instance before releasing
Related Work#
Plugin Enhancements#
- GA4 Compatibility Fix: dotCMS/google-analytics#2 - Fixed default metric compatibility and OSGi dependency resolution
- REST Endpoint: dotCMS/google-analytics#3 - Added REST API endpoint for headless/API-first use cases
Core dotCMS Integration#
- Auto-inject Tracking Code: dotCMS/core#34667 - Automatically inject Google Analytics tracking code into pages
Next Steps#
This guide will be used as the basis for:
- README.md in the google-analytics GitHub repo
- Integration page content on dotcms.com
- Updated documentation on dev.dotcms.com/docs
- GitHub release with pre-built JAR (no more build-from-source requirement)