Analytics Module Google Analytics connects your Backstage frontend to Google Analytics 4 through the Backstage Analytics API. It runs behind the scenes to send page views and events as people navigate and use your developer portal. It does not add UI. It focuses on reliable event delivery to GA4.
You get structured telemetry about how Backstage is used. The module can capture contexts like plugin id and chosen event attributes, which makes it easier to slice reports by area of the portal. You can enable content grouping to see usage by plugin or route. You can enrich events with a pseudonymized user id from the Backstage identity system to support metrics like monthly active users. During development you can switch to test mode or turn on debug logs to verify events without polluting production data.
Common use cases include tracking adoption of new plugins, finding underused pages, measuring navigation paths to improve information architecture, and reporting engagement to stakeholders. Because it uses the Backstage Analytics API, your app code stays consistent while the provider handles GA4 specifics. That keeps your analytics wiring simple when requirements change.
If you already rely on GA4 for product or web metrics, this module lets you bring similar insight to your internal portal with minimal friction. It gives engineers the signals they need to guide UX improvements and to prove impact with data.
Installation Instructions
These instructions apply to self-hosted Backstage only.
Install the package
- Run this from the Backstage repo root.
yarn --cwd packages/app add @backstage-community/plugin-analytics-module-ga4
Wire it into the frontend
New frontend system
- Open packages app src App.tsx.
- Import the module and register it with createApp.
// packages/app/src/App.tsx
import ga4Module from '@backstage-community/plugin-analytics-module-ga4/alpha';
// import { createApp } from your app setup
const app = createApp({
features: [ga4Module],
});
// rest of your app
If your app uses feature discovery you can skip the features line. The module will be picked up.
Classic frontend system
- Open packages app src apis.ts.
- Register the GoogleAnalytics4 API factory.
// packages/app/src/apis.ts
import {
AnyApiFactory,
analyticsApiRef,
configApiRef,
identityApiRef,
createApiFactory,
} from '@backstage/core-plugin-api';
import { GoogleAnalytics4 } from '@backstage-community/plugin-analytics-module-ga4';
export const apis: AnyApiFactory[] = [
createApiFactory({
api: analyticsApiRef,
deps: { configApi: configApiRef, identityApi: identityApiRef },
factory: ({ configApi, identityApi }) =>
GoogleAnalytics4.fromConfig(configApi, {
identityApi,
}),
}),
];
There are no UI components to add. The plugin sends events in the background.
Configure analytics in app config
- Add the minimum config. Put this in app-config.yaml.
app:
analytics:
ga4:
measurementId: G-0000000-0
Update backend content security policy
- Add this to app-config.yaml. This applies to both the old and new backend systems.
backend:
csp:
connect-src: ["'self'", 'http:', 'https:']
script-src:
[
"'self'",
"'unsafe-eval'",
'https://www.google-analytics.com',
'https://www.googletagmanager.com',
]
img-src: ["'self'", 'data:', 'https://www.google-analytics.com']
Optional settings
Content grouping by plugin
app:
analytics:
ga4:
contentGrouping: pluginId
Content grouping can take time to appear in the Google Analytics dashboard.
Allow extra context or attributes
- You can allow specific event context fields or attributes.
- Use star to allow all.
app:
analytics:
ga4:
allowedContexts: ['pluginId']
allowedAttributes: ['someEventContextAttr']
Send default page view events
Disabled by default to avoid duplicate events. Turn it on only if you need it.
app:
analytics:
ga4:
enableSendPageView: true
Local debug
app:
analytics:
ga4:
testMode: true
debug: true
User ID support with Identity
- Keep identity accurate for user based metrics.
- Ensure you pass identityApi to GoogleAnalytics4 as shown above.
- Set identity mode in app-config.yaml.
app:
analytics:
ga4:
measurementId: G-0000000-0
identity: optional
Use optional to keep session counts when users do not sign in. Use required if all hits must have a user ID.
- You can customize the user ID value with a transform.
// packages/app/src/apis.ts
import {
AnyApiFactory,
analyticsApiRef,
configApiRef,
identityApiRef,
createApiFactory,
} from '@backstage/core-plugin-api';
import { GoogleAnalytics4 } from '@backstage-community/plugin-analytics-module-ga4';
function customHashingFunction(input: string): string {
// your own hashing or transform
return input;
}
export const apis: AnyApiFactory[] = [
createApiFactory({
api: analyticsApiRef,
deps: { configApi: configApiRef, identityApi: identityApiRef },
factory: ({ configApi, identityApi }) =>
GoogleAnalytics4.fromConfig(configApi, {
identityApi,
userIdTransform: async (userEntityRef: string): Promise<string> => {
return customHashingFunction(userEntityRef);
},
}),
}),
];
Changelog
This changelog is produced from commits made to the Google Analytics plugin since 6 months ago, and based on the code located here. It may not contain information about all commits. Releases and version bumps are intentionally omitted. This changelog is generated by AI.
Set up Backstage in minutes with Roadie
Focus on using Backstage, rather than building and maintaining it.