@jitsu/js 1.5.1 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,123 @@
1
+ import { loadScript } from "../script-loader";
2
+ import { AnalyticsClientEvent } from "@jitsu/protocols/analytics";
3
+ import { applyFilters, CommonDestinationCredentials, InternalPlugin } from "./index";
4
+
5
+ const defaultScriptSrc = "https://www.googletagmanager.com/gtag/js";
6
+
7
+ export type Ga4DestinationCredentials = {
8
+ debug?: boolean;
9
+ measurementIds?: string;
10
+ autoPageView?: boolean;
11
+ dataLayerName?: string;
12
+ } & CommonDestinationCredentials;
13
+
14
+ export const ga4Plugin: InternalPlugin<Ga4DestinationCredentials> = {
15
+ id: "ga4-tag",
16
+ async handle(config, payload: AnalyticsClientEvent) {
17
+ if (!applyFilters(payload, config)) {
18
+ return;
19
+ }
20
+ await initGa4IfNeeded(config, payload);
21
+
22
+ const dataLayer = window[config.dataLayerName || "dataLayer"];
23
+ const gtag = function () {
24
+ dataLayer.push(arguments);
25
+ };
26
+ const ids = {
27
+ ...(payload.userId ? { user_id: payload.userId, userId: payload.userId } : {}),
28
+ ...(payload.anonymousId ? { anonymousId: payload.anonymousId } : {}),
29
+ };
30
+ if (payload.userId) {
31
+ // @ts-ignore
32
+ gtag("set", { user_id: payload.userId });
33
+ }
34
+
35
+ switch (payload.type) {
36
+ case "page":
37
+ if (config.autoPageView) {
38
+ console.log("autoPageView");
39
+ break;
40
+ }
41
+ const { properties: pageProperties, context } = payload;
42
+ const pageEvent = {
43
+ page_location: pageProperties.url,
44
+ page_title: pageProperties.title,
45
+ page_path: pageProperties.path,
46
+ page_hash: pageProperties.hash,
47
+ page_search: pageProperties.search,
48
+ page_referrer: context?.page?.referrer ?? "",
49
+ ...ids,
50
+ };
51
+ // @ts-ignore
52
+ gtag("event", "page_view", pageEvent);
53
+ break;
54
+ case "track":
55
+ const { properties: trackProperties } = payload;
56
+ const trackEvent: any = {
57
+ ...trackProperties,
58
+ ...ids,
59
+ };
60
+ // @ts-ignore
61
+ gtag("event", payload.event, trackEvent);
62
+ break;
63
+ case "identify":
64
+ const { traits } = payload;
65
+ const identifyEvent: any = {
66
+ ...traits,
67
+ ...ids,
68
+ };
69
+ // @ts-ignore
70
+ gtag("event", "identify", identifyEvent);
71
+ break;
72
+ }
73
+ },
74
+ };
75
+
76
+ type GtmState = "fresh" | "loading" | "loaded" | "failed";
77
+
78
+ function getGa4State(): GtmState {
79
+ return window["__jitsuGa4State"] || "fresh";
80
+ }
81
+
82
+ function setGa4State(s: GtmState) {
83
+ window["__jitsuGa4State"] = s;
84
+ }
85
+
86
+ async function initGa4IfNeeded(config: Ga4DestinationCredentials, payload: AnalyticsClientEvent) {
87
+ if (getGa4State() !== "fresh") {
88
+ return;
89
+ }
90
+ setGa4State("loading");
91
+
92
+ const dlName = config.dataLayerName || "dataLayer";
93
+ const dlParam = dlName !== "dataLayer" ? "&l=" + dlName : "";
94
+
95
+ // to work with both GA4 and GTM
96
+ const tagId = config.measurementIds;
97
+ const scriptSrc = `${defaultScriptSrc}?id=${tagId}${dlParam}`;
98
+
99
+ window[dlName] = window[dlName] || [];
100
+ const gtag = function () {
101
+ window[dlName].push(arguments);
102
+ };
103
+ // @ts-ignore
104
+ gtag("js", new Date());
105
+ gtag(
106
+ // @ts-ignore
107
+ "config",
108
+ tagId,
109
+ {
110
+ ...(payload.userId ? { user_id: payload.userId } : {}),
111
+ ...(!config.autoPageView ? { send_page_view: false } : {}),
112
+ }
113
+ );
114
+
115
+ loadScript(scriptSrc)
116
+ .then(() => {
117
+ setGa4State("loaded");
118
+ })
119
+ .catch(e => {
120
+ console.warn(`GA4 (containerId=${config.measurementIds}) init failed: ${e.message}`, e);
121
+ setGa4State("failed");
122
+ });
123
+ }
@@ -5,12 +5,12 @@ import { applyFilters, CommonDestinationCredentials, InternalPlugin } from "./in
5
5
  const defaultScriptSrc = "https://www.googletagmanager.com/gtag/js";
6
6
 
7
7
  export type GtmDestinationCredentials = {
8
- debug: boolean;
9
- containerId: string;
10
- dataLayerName: string;
11
- preview: string;
12
- auth: string;
13
- customScriptSrc: string;
8
+ debug?: boolean;
9
+ containerId?: string;
10
+ dataLayerName?: string;
11
+ preview?: string;
12
+ auth?: string;
13
+ customScriptSrc?: string;
14
14
  } & CommonDestinationCredentials;
15
15
 
16
16
  export const gtmPlugin: InternalPlugin<GtmDestinationCredentials> = {
@@ -19,53 +19,50 @@ export const gtmPlugin: InternalPlugin<GtmDestinationCredentials> = {
19
19
  if (!applyFilters(payload, config)) {
20
20
  return;
21
21
  }
22
- await initGtmIfNeeded(config);
22
+ await initGtmIfNeeded(config, payload);
23
23
 
24
24
  const dataLayer = window[config.dataLayerName || "dataLayer"];
25
-
25
+ const ids = {
26
+ ...(payload.userId ? { user_id: payload.userId, userId: payload.userId } : {}),
27
+ ...(payload.anonymousId ? { anonymousId: payload.anonymousId } : {}),
28
+ };
26
29
  switch (payload.type) {
27
30
  case "page":
28
31
  const { properties: pageProperties, context } = payload;
29
32
  const pageEvent = {
30
33
  event: "page_view",
31
- url: pageProperties.url,
32
- title: pageProperties.title,
33
- referer: context?.page?.referrer ?? "",
34
+ page_location: pageProperties.url,
35
+ page_title: pageProperties.title,
36
+ page_path: pageProperties.path,
37
+ page_hash: pageProperties.hash,
38
+ page_search: pageProperties.search,
39
+ page_referrer: context?.page?.referrer ?? "",
40
+ ...ids,
34
41
  };
35
- if (config.debug) {
36
- console.log("gtag push", pageEvent);
37
- }
38
42
  dataLayer.push(pageEvent);
39
43
  break;
40
44
  case "track":
41
45
  const { properties: trackProperties } = payload;
42
- const trackEvent: any = { event: payload.event, ...trackProperties };
43
- if (payload.userId) {
44
- trackEvent.userId = payload.userId;
45
- }
46
- if (payload.anonymousId) {
47
- trackEvent.anonymousId = payload.anonymousId;
48
- }
49
- if (config.debug) {
50
- console.log("gtag push", trackEvent);
51
- }
46
+ const trackEvent: any = {
47
+ event: payload.event,
48
+ ...trackProperties,
49
+ ...ids,
50
+ };
52
51
  dataLayer.push(trackEvent);
53
52
  break;
54
53
  case "identify":
55
54
  const { traits } = payload;
56
- const identifyEvent: any = { event: "identify", ...traits };
57
- if (payload.userId) {
58
- identifyEvent.userId = payload.userId;
59
- }
60
- if (payload.anonymousId) {
61
- identifyEvent.anonymousId = payload.anonymousId;
62
- }
63
- if (config.debug) {
64
- console.log("gtag push", identifyEvent);
65
- }
55
+ const identifyEvent: any = {
56
+ event: "identify",
57
+ ...traits,
58
+ ...ids,
59
+ };
66
60
  dataLayer.push(identifyEvent);
67
61
  break;
68
62
  }
63
+ dataLayer.push(function () {
64
+ this.reset();
65
+ });
69
66
  },
70
67
  };
71
68
 
@@ -79,7 +76,7 @@ function setGtmState(s: GtmState) {
79
76
  window["__jitsuGtmState"] = s;
80
77
  }
81
78
 
82
- async function initGtmIfNeeded(config: GtmDestinationCredentials) {
79
+ async function initGtmIfNeeded(config: GtmDestinationCredentials, payload: AnalyticsClientEvent) {
83
80
  if (getGtmState() !== "fresh") {
84
81
  return;
85
82
  }
@@ -90,23 +87,27 @@ async function initGtmIfNeeded(config: GtmDestinationCredentials) {
90
87
  const previewParams = config.preview
91
88
  ? `&gtm_preview=${config.preview}&gtm_auth=${config.auth}&gtm_cookies_win=x`
92
89
  : "";
93
- const scriptSrc = `${config.customScriptSrc || defaultScriptSrc}?id=${config.containerId}${dlParam}${previewParams}`;
90
+ const tagId = config.containerId;
91
+ const scriptSrc = `${config.customScriptSrc || defaultScriptSrc}?id=${tagId}${dlParam}${previewParams}`;
94
92
 
95
93
  window[dlName] = window[dlName] || [];
96
94
  const gtag = function () {
97
95
  window[dlName].push(arguments);
98
96
  };
97
+ window[dlName].push({
98
+ user_id: payload.userId,
99
+ });
99
100
  // @ts-ignore
100
101
  gtag("js", new Date());
101
102
  // @ts-ignore
102
- gtag("config", config.containerId);
103
+ gtag("config", tagId);
103
104
 
104
105
  loadScript(scriptSrc)
105
106
  .then(() => {
106
107
  setGtmState("loaded");
107
108
  })
108
109
  .catch(e => {
109
- console.warn(`GTM (containerId=${config.containerId}) init failed: ${e.message}`, e);
110
+ console.warn(`GTM (containerId=${tagId}) init failed: ${e.message}`, e);
110
111
  setGtmState("failed");
111
112
  });
112
113
  }
@@ -2,6 +2,7 @@ import { AnalyticsClientEvent } from "@jitsu/protocols/analytics";
2
2
  import { tagPlugin } from "./tag";
3
3
  import { logrocketPlugin } from "./logrocket";
4
4
  import { gtmPlugin } from "./gtm";
5
+ import { ga4Plugin } from "./ga4";
5
6
 
6
7
  export type InternalPlugin<T> = {
7
8
  id: string;
@@ -36,7 +37,7 @@ export function applyFilters(event: AnalyticsClientEvent, creds: CommonDestinati
36
37
  const eventsArray = Array.isArray(events) ? events : events.split("\n");
37
38
  const hostsArray = Array.isArray(hosts) ? hosts : hosts.split("\n");
38
39
  return (
39
- !!hostsArray.find(hostFilter => satisfyDomainFilter(hostFilter, event.context?.host)) &&
40
+ !!hostsArray.find(hostFilter => satisfyDomainFilter(hostFilter, event.context?.page?.host)) &&
40
41
  (!!eventsArray.find(eventFilter => satisfyFilter(eventFilter, event.type)) ||
41
42
  !!eventsArray.find(eventFilter => satisfyFilter(eventFilter, event.event)))
42
43
  );
@@ -55,5 +56,6 @@ export function applyFilters(event: AnalyticsClientEvent, creds: CommonDestinati
55
56
  export const internalDestinationPlugins: Record<string, InternalPlugin<any>> = {
56
57
  [tagPlugin.id]: tagPlugin,
57
58
  [gtmPlugin.id]: gtmPlugin,
59
+ [ga4Plugin.id]: ga4Plugin,
58
60
  [logrocketPlugin.id]: logrocketPlugin,
59
61
  };
package/src/index.ts CHANGED
@@ -98,4 +98,3 @@ export function jitsuAnalytics(opts: JitsuOptions): AnalyticsInterface {
98
98
 
99
99
  export * from "./jitsu";
100
100
  export * from "./analytics-plugin";
101
- export { getTopLevelDomain } from "./tlds";
package/src/jitsu.ts CHANGED
@@ -52,6 +52,9 @@ type RuntimeFacade = {
52
52
  language(): string | undefined;
53
53
  pageUrl(): string | undefined;
54
54
  documentEncoding(): string | undefined;
55
+ getCookie(name: string): string | undefined;
56
+ getCookies(): Record<string, string>;
57
+
55
58
  timezoneOffset(): number | undefined;
56
59
  screen():
57
60
  | {
package/tsconfig.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "moduleResolution": "Node",
8
8
  "resolveJsonModule": true,
9
9
  "target": "ES2015",
10
- "lib": ["es2017", "dom"],
10
+ "lib": ["es2020", "dom"],
11
11
  //this makes typescript igore @types/node during compilation
12
12
  "types": []
13
13
  },