SilverStripe is a PHP CMS with powerful templating. This guide covers GA4 implementation using templates, configuration, and available modules.
Prerequisites
- Google Analytics 4 property created
- GA4 Measurement ID (format:
G-XXXXXXXXXX) - SilverStripe 4.x or 5.x installed
- Access to SilverStripe templates and configuration
Method 1: Template Integration (Recommended)
Step 1: Create GA4 Include Template
File: themes/yourtheme/templates/Includes/GoogleAnalytics.ss
<% if $SiteConfig.GATrackingID %>
<!-- Google Analytics 4 -->
<script async src="https://www.googletagmanager.com/gtag/js?id={$SiteConfig.GATrackingID}"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '{$SiteConfig.GATrackingID}', {
'send_page_view': true,
'cookie_flags': 'SameSite=None;Secure'
});
</script>
<!-- End Google Analytics 4 -->
<% end_if %>
Step 2: Add to Page Template
File: themes/yourtheme/templates/Page.ss
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>$Title</title>
$MetaTags
<% require themedCSS('app') %>
<!-- Include GA4 in head -->
<% include GoogleAnalytics %>
</head>
<body class="$ClassName">
$Layout
<% require themedJavascript('app') %>
</body>
</html>
Step 3: Add Tracking ID to SiteConfig
File: app/src/Extensions/SiteConfigExtension.php
<?php
namespace App\Extensions;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\TextField;
use SilverStripe\ORM\DataExtension;
class SiteConfigExtension extends DataExtension
{
private static $db = [
'GATrackingID' => 'Varchar(20)',
];
public function updateCMSFields(FieldList $fields)
{
$fields->addFieldToTab(
'Root.Analytics',
TextField::create('GATrackingID', 'GA4 Tracking ID')
->setDescription('Format: G-XXXXXXXXXX')
);
}
}
Step 4: Register Extension
File: app/_config/config.yml
SilverStripe\SiteConfig\SiteConfig:
extensions:
- App\Extensions\SiteConfigExtension
Step 5: Run Dev/Build
sake dev/build flush=1
Step 6: Add Tracking ID in CMS
- Log in to SilverStripe CMS
- Go to Settings
- Click Analytics tab
- Enter your GA4 Measurement ID
- Save
Method 2: Using SilverStripe GoogleAnalytics Module
Step 1: Install Module via Composer
composer require silverstripe/googleanalytics
Step 2: Configure Module
File: app/_config/googleanalytics.yml
SilverStripe\GoogleAnalytics\GoogleAnalytics:
tracking_id: 'G-XXXXXXXXXX'
enabled: true
anonymize_ip: false
Step 3: Add to Template
The module automatically adds GA4 when configured. Alternatively, manually include:
<% include GoogleAnalytics %>
Method 3: Environment-Based Configuration
Store tracking ID in environment file for different environments.
Step 1: Add to .env
File: .env
GA_TRACKING_ID="G-XXXXXXXXXX"
Step 2: Update Template
File: themes/yourtheme/templates/Includes/GoogleAnalytics.ss
<script async src="https://www.googletagmanager.com/gtag/js?id=<% with $Env.GA_TRACKING_ID %>{$Value}<% end_with %>"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '<% with $Env.GA_TRACKING_ID %>{$Value}<% end_with %>');
</script>
Step 3: Create Template Helper
File: app/src/PageController.php
<?php
namespace App;
use PageController as BasePageController;
use SilverStripe\Core\Environment;
class PageController extends BasePageController
{
public function GATrackingID()
{
return Environment::getEnv('GA_TRACKING_ID');
}
}
In template:
<% if $GATrackingID %>
<script async src="https://www.googletagmanager.com/gtag/js?id={$GATrackingID}"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '{$GATrackingID}');
</script>
<% end_if %>
Advanced Configuration
Track Member Status
File: themes/yourtheme/templates/Includes/GoogleAnalytics.ss
<script async src="https://www.googletagmanager.com/gtag/js?id={$SiteConfig.GATrackingID}"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '{$SiteConfig.GATrackingID}', {
<% if $CurrentMember %>
'user_id': '{$CurrentMember.ID}',
'user_properties': {
'member_status': 'logged_in',
'member_role': '{$CurrentMember.ClassName}'
},
<% else %>
'user_properties': {
'member_status': 'guest'
},
<% end_if %>
});
</script>
Environment-Specific Tracking
Only load in production:
<% if $IsLive %>
<!-- GA4 code -->
<% end_if %>
File: app/src/PageController.php
public function IsLive()
{
return Director::isLive();
}
Tracking Different Page Types
Custom Page Types
File: app/src/BlogPageController.php
<?php
namespace App;
use PageController;
class BlogPageController extends PageController
{
protected function init()
{
parent::init();
// Add custom GA4 tracking for blog posts
$this->setCustomGATracking();
}
protected function setCustomGATracking()
{
$script = <<<JS
gtag('event', 'page_view', {
'page_type': 'blog_post',
'content_category': '{$this->data()->Category()->Title}',
'author': '{$this->data()->Author()->Name}'
});
JS;
Requirements::customScript($script);
}
}
Verify Installation
Step 1: Check Page Source
- Visit your SilverStripe site
- View page source
- Search for
gtag - Verify script is present with correct Measurement ID
Step 2: Use Google Tag Assistant
- Install Google Tag Assistant Chrome Extension
- Visit your site
- Click extension
- Verify GA4 tag detected
Step 3: Check Real-Time Reports
- In GA4, go to Reports > Realtime
- Visit your SilverStripe site
- Verify page views appear within 30 seconds
Using Requirements API
SilverStripe's Requirements API for better control:
File: app/src/PageController.php
<?php
namespace App;
use PageController as BasePageController;
use SilverStripe\View\Requirements;
use SilverStripe\Core\Environment;
class PageController extends BasePageController
{
protected function init()
{
parent::init();
$trackingId = Environment::getEnv('GA_TRACKING_ID');
if ($trackingId) {
// Load gtag.js
Requirements::javascript(
"https://www.googletagmanager.com/gtag/js?id={$trackingId}",
['async' => true]
);
// Initialize gtag
$script = <<<JS
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '{$trackingId}');
JS;
Requirements::customScript($script, 'ga4-init');
}
}
}
Conditional Loading
Don't Track Admins
protected function init()
{
parent::init();
// Don't track logged-in admin users
if (!Permission::check('ADMIN')) {
$this->loadGoogleAnalytics();
}
}
Multiple Environments
File: app/_config.php
<?php
use SilverStripe\Core\Environment;
use SilverStripe\Control\Director;
// Set GA ID based on environment
if (Director::isLive()) {
Environment::setEnv('GA_TRACKING_ID', 'G-PRODUCTION-ID');
} elseif (Director::isTest()) {
Environment::setEnv('GA_TRACKING_ID', 'G-STAGING-ID');
} else {
// Don't track in dev
Environment::setEnv('GA_TRACKING_ID', '');
}
Form Tracking Integration
Track form submissions:
File: app/src/Forms/ContactForm.php
<?php
namespace App\Forms;
use SilverStripe\Forms\Form;
use SilverStripe\View\Requirements;
class ContactForm extends Form
{
public function doSubmit($data, $form)
{
// Process form...
// Track submission
Requirements::customScript(<<<JS
if (typeof gtag !== 'undefined') {
gtag('event', 'form_submission', {
'form_name': 'contact',
'form_id': '{$this->FormName()}'
});
}
JS
);
return $this->controller->redirectBack();
}
}
Troubleshooting
Issue: GA4 Not Loading
Check:
- Tracking ID is set in SiteConfig
- Template include is in Page.ss
- Run
dev/build flush=1 - Check browser console for errors
Issue: Tracking ID Empty
Solution:
- Verify
GATrackingIDfield exists in database - Run
sake dev/build - Check extension is registered in config.yml