mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Echo: Add config option to prevent duplicate page views for GA4 (#57619)
This commit is contained in:
parent
463f993186
commit
008c554d7f
@ -230,6 +230,9 @@ google_analytics_ua_id =
|
|||||||
# Google Analytics 4 tracking code, only enabled if you specify an id here
|
# Google Analytics 4 tracking code, only enabled if you specify an id here
|
||||||
google_analytics_4_id =
|
google_analytics_4_id =
|
||||||
|
|
||||||
|
# When Google Analytics 4 Enhanced event measurement is enabled, we will try to avoid sending duplicate events and let Google Analytics 4 detect navigation changes, etc.
|
||||||
|
google_analytics_4_send_manual_page_views = false
|
||||||
|
|
||||||
# Google Tag Manager ID, only enabled if you specify an id here
|
# Google Tag Manager ID, only enabled if you specify an id here
|
||||||
google_tag_manager_id =
|
google_tag_manager_id =
|
||||||
|
|
||||||
|
@ -237,6 +237,9 @@
|
|||||||
# Google Analytics 4 tracking code, only enabled if you specify an id here
|
# Google Analytics 4 tracking code, only enabled if you specify an id here
|
||||||
;google_analytics_4_id =
|
;google_analytics_4_id =
|
||||||
|
|
||||||
|
# When Google Analytics 4 Enhanced event measurement is enabled, we will try to avoid sending duplicate events and let Google Analytics 4 detect navigation changes, etc.
|
||||||
|
;google_analytics_4_send_manual_page_views = false
|
||||||
|
|
||||||
# Google Tag Manager ID, only enabled if you specify an id here
|
# Google Tag Manager ID, only enabled if you specify an id here
|
||||||
;google_tag_manager_id =
|
;google_tag_manager_id =
|
||||||
|
|
||||||
|
@ -211,6 +211,7 @@ export interface GrafanaConfig {
|
|||||||
secretsManagerPluginEnabled: boolean;
|
secretsManagerPluginEnabled: boolean;
|
||||||
googleAnalyticsId: string | undefined;
|
googleAnalyticsId: string | undefined;
|
||||||
googleAnalytics4Id: string | undefined;
|
googleAnalytics4Id: string | undefined;
|
||||||
|
googleAnalytics4SendManualPageViews: boolean;
|
||||||
rudderstackWriteKey: string | undefined;
|
rudderstackWriteKey: string | undefined;
|
||||||
rudderstackDataPlaneUrl: string | undefined;
|
rudderstackDataPlaneUrl: string | undefined;
|
||||||
rudderstackSdkUrl: string | undefined;
|
rudderstackSdkUrl: string | undefined;
|
||||||
|
@ -136,6 +136,7 @@ export class GrafanaBootConfig implements GrafanaConfig {
|
|||||||
};
|
};
|
||||||
googleAnalyticsId: undefined;
|
googleAnalyticsId: undefined;
|
||||||
googleAnalytics4Id: undefined;
|
googleAnalytics4Id: undefined;
|
||||||
|
googleAnalytics4SendManualPageViews = false;
|
||||||
rudderstackWriteKey: undefined;
|
rudderstackWriteKey: undefined;
|
||||||
rudderstackDataPlaneUrl: undefined;
|
rudderstackDataPlaneUrl: undefined;
|
||||||
rudderstackSdkUrl: undefined;
|
rudderstackSdkUrl: undefined;
|
||||||
|
@ -14,6 +14,7 @@ type IndexViewData struct {
|
|||||||
AppSubUrl string
|
AppSubUrl string
|
||||||
GoogleAnalyticsId string
|
GoogleAnalyticsId string
|
||||||
GoogleAnalytics4Id string
|
GoogleAnalytics4Id string
|
||||||
|
GoogleAnalytics4SendManualPageViews bool
|
||||||
GoogleTagManagerId string
|
GoogleTagManagerId string
|
||||||
NavTree *navtree.NavTreeRoot
|
NavTree *navtree.NavTreeRoot
|
||||||
BuildVersion string
|
BuildVersion string
|
||||||
|
@ -124,6 +124,7 @@ func (hs *HTTPServer) getFrontendSettingsMap(c *models.ReqContext) (map[string]i
|
|||||||
"queryHistoryEnabled": hs.Cfg.QueryHistoryEnabled,
|
"queryHistoryEnabled": hs.Cfg.QueryHistoryEnabled,
|
||||||
"googleAnalyticsId": setting.GoogleAnalyticsId,
|
"googleAnalyticsId": setting.GoogleAnalyticsId,
|
||||||
"googleAnalytics4Id": setting.GoogleAnalytics4Id,
|
"googleAnalytics4Id": setting.GoogleAnalytics4Id,
|
||||||
|
"GoogleAnalytics4SendManualPageViews": setting.GoogleAnalytics4SendManualPageViews,
|
||||||
"rudderstackWriteKey": setting.RudderstackWriteKey,
|
"rudderstackWriteKey": setting.RudderstackWriteKey,
|
||||||
"rudderstackDataPlaneUrl": setting.RudderstackDataPlaneUrl,
|
"rudderstackDataPlaneUrl": setting.RudderstackDataPlaneUrl,
|
||||||
"rudderstackSdkUrl": setting.RudderstackSdkUrl,
|
"rudderstackSdkUrl": setting.RudderstackSdkUrl,
|
||||||
|
@ -104,6 +104,7 @@ func (hs *HTTPServer) setIndexViewData(c *models.ReqContext) (*dtos.IndexViewDat
|
|||||||
AppSubUrl: appSubURL,
|
AppSubUrl: appSubURL,
|
||||||
GoogleAnalyticsId: setting.GoogleAnalyticsId,
|
GoogleAnalyticsId: setting.GoogleAnalyticsId,
|
||||||
GoogleAnalytics4Id: setting.GoogleAnalytics4Id,
|
GoogleAnalytics4Id: setting.GoogleAnalytics4Id,
|
||||||
|
GoogleAnalytics4SendManualPageViews: setting.GoogleAnalytics4SendManualPageViews,
|
||||||
GoogleTagManagerId: setting.GoogleTagManagerId,
|
GoogleTagManagerId: setting.GoogleTagManagerId,
|
||||||
BuildVersion: setting.BuildVersion,
|
BuildVersion: setting.BuildVersion,
|
||||||
BuildCommit: setting.BuildCommit,
|
BuildCommit: setting.BuildCommit,
|
||||||
|
@ -139,6 +139,7 @@ var (
|
|||||||
// analytics
|
// analytics
|
||||||
GoogleAnalyticsId string
|
GoogleAnalyticsId string
|
||||||
GoogleAnalytics4Id string
|
GoogleAnalytics4Id string
|
||||||
|
GoogleAnalytics4SendManualPageViews bool
|
||||||
GoogleTagManagerId string
|
GoogleTagManagerId string
|
||||||
RudderstackDataPlaneUrl string
|
RudderstackDataPlaneUrl string
|
||||||
RudderstackWriteKey string
|
RudderstackWriteKey string
|
||||||
@ -995,6 +996,8 @@ func (cfg *Cfg) Load(args CommandLineArgs) error {
|
|||||||
cfg.CheckForPluginUpdates = analytics.Key("check_for_plugin_updates").MustBool(true)
|
cfg.CheckForPluginUpdates = analytics.Key("check_for_plugin_updates").MustBool(true)
|
||||||
GoogleAnalyticsId = analytics.Key("google_analytics_ua_id").String()
|
GoogleAnalyticsId = analytics.Key("google_analytics_ua_id").String()
|
||||||
GoogleAnalytics4Id = analytics.Key("google_analytics_4_id").String()
|
GoogleAnalytics4Id = analytics.Key("google_analytics_4_id").String()
|
||||||
|
GoogleAnalytics4SendManualPageViews = analytics.Key("google_analytics_4_send_manual_page_views").MustBool(false)
|
||||||
|
|
||||||
GoogleTagManagerId = analytics.Key("google_tag_manager_id").String()
|
GoogleTagManagerId = analytics.Key("google_tag_manager_id").String()
|
||||||
RudderstackWriteKey = analytics.Key("rudderstack_write_key").String()
|
RudderstackWriteKey = analytics.Key("rudderstack_write_key").String()
|
||||||
RudderstackDataPlaneUrl = analytics.Key("rudderstack_data_plane_url").String()
|
RudderstackDataPlaneUrl = analytics.Key("rudderstack_data_plane_url").String()
|
||||||
|
@ -268,6 +268,7 @@ function initEchoSrv() {
|
|||||||
registerEchoBackend(
|
registerEchoBackend(
|
||||||
new GA4EchoBackend({
|
new GA4EchoBackend({
|
||||||
googleAnalyticsId: config.googleAnalytics4Id,
|
googleAnalyticsId: config.googleAnalytics4Id,
|
||||||
|
googleAnalytics4SendManualPageViews: config.googleAnalytics4SendManualPageViews,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -11,16 +11,17 @@ declare global {
|
|||||||
|
|
||||||
export interface GA4EchoBackendOptions {
|
export interface GA4EchoBackendOptions {
|
||||||
googleAnalyticsId: string;
|
googleAnalyticsId: string;
|
||||||
|
googleAnalytics4SendManualPageViews: boolean;
|
||||||
user?: CurrentUserDTO;
|
user?: CurrentUserDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GA4EchoBackend implements EchoBackend<PageviewEchoEvent, GA4EchoBackendOptions> {
|
export class GA4EchoBackend implements EchoBackend<PageviewEchoEvent, GA4EchoBackendOptions> {
|
||||||
supportedEvents = [EchoEventType.Pageview];
|
supportedEvents = [EchoEventType.Pageview];
|
||||||
trackedUserId: number | null = null;
|
googleAnalytics4SendManualPageViews = false;
|
||||||
|
|
||||||
constructor(public options: GA4EchoBackendOptions) {
|
constructor(public options: GA4EchoBackendOptions) {
|
||||||
const url = `https://www.googletagmanager.com/gtag/js?id=${options.googleAnalyticsId}`;
|
const url = `https://www.googletagmanager.com/gtag/js?id=${options.googleAnalyticsId}`;
|
||||||
loadScript(url);
|
loadScript(url, true);
|
||||||
|
|
||||||
window.dataLayer = window.dataLayer || [];
|
window.dataLayer = window.dataLayer || [];
|
||||||
window.gtag = function gtag() {
|
window.gtag = function gtag() {
|
||||||
@ -28,12 +29,15 @@ export class GA4EchoBackend implements EchoBackend<PageviewEchoEvent, GA4EchoBac
|
|||||||
};
|
};
|
||||||
window.gtag('js', new Date());
|
window.gtag('js', new Date());
|
||||||
|
|
||||||
const configOptions: Gtag.CustomParams = {};
|
const configOptions: Gtag.CustomParams = {
|
||||||
|
page_path: window.location.pathname,
|
||||||
|
};
|
||||||
|
|
||||||
if (options.user) {
|
if (options.user) {
|
||||||
configOptions.user_id = getUserIdentifier(options.user);
|
configOptions.user_id = getUserIdentifier(options.user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.googleAnalytics4SendManualPageViews = options.googleAnalytics4SendManualPageViews;
|
||||||
window.gtag('config', options.googleAnalyticsId, configOptions);
|
window.gtag('config', options.googleAnalyticsId, configOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,9 +45,10 @@ export class GA4EchoBackend implements EchoBackend<PageviewEchoEvent, GA4EchoBac
|
|||||||
if (!window.gtag) {
|
if (!window.gtag) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// this should prevent duplicate events in case enhanced tracking is enabled
|
||||||
window.gtag('set', 'page_path', e.payload.page);
|
if (this.googleAnalytics4SendManualPageViews) {
|
||||||
window.gtag('event', 'page_view');
|
window.gtag('event', 'page_view', { page_path: e.payload.page });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Not using Echo buffering, addEvent above sends events to GA as soon as they appear
|
// Not using Echo buffering, addEvent above sends events to GA as soon as they appear
|
||||||
|
@ -14,11 +14,12 @@ export function getUserIdentifier(user: CurrentUserDTO) {
|
|||||||
return user.email;
|
return user.email;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loadScript(url: string) {
|
export function loadScript(url: string, async = false) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const script = document.createElement('script');
|
const script = document.createElement('script');
|
||||||
script.onload = resolve;
|
script.onload = resolve;
|
||||||
script.src = url;
|
script.src = url;
|
||||||
|
script.async = async;
|
||||||
document.head.appendChild(script);
|
document.head.appendChild(script);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user