@junctionjs/destination-ga4 0.1.0
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.
- package/README.md +42 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +136 -0
- package/dist/index.js.map +1 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# @junctionjs/destination-ga4
|
|
2
|
+
|
|
3
|
+
Google Analytics 4 destination for Junction.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Client-side via gtag.js (loaded lazily if not present)
|
|
8
|
+
- Server-side via GA4 Measurement Protocol
|
|
9
|
+
- Google Consent Mode v2 — automatically maps Junction consent state to Google's consent signals
|
|
10
|
+
- GA4 recommended event mapping (view_item, add_to_cart, purchase, etc.)
|
|
11
|
+
- Custom event name and parameter overrides
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @junctionjs/destination-ga4
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { ga4 } from "@junctionjs/destination-ga4";
|
|
23
|
+
|
|
24
|
+
// In your collector config
|
|
25
|
+
const config = {
|
|
26
|
+
destinations: [
|
|
27
|
+
{
|
|
28
|
+
destination: ga4,
|
|
29
|
+
config: {
|
|
30
|
+
measurementId: "G-XXXXXXXXXX",
|
|
31
|
+
consentMode: true,
|
|
32
|
+
sendPageView: false, // Junction handles page views
|
|
33
|
+
},
|
|
34
|
+
consent: ["analytics"],
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## License
|
|
41
|
+
|
|
42
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Destination } from '@junctionjs/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @junctionjs/destination-ga4
|
|
5
|
+
*
|
|
6
|
+
* Google Analytics 4 destination for Junction.
|
|
7
|
+
*
|
|
8
|
+
* Client-side: uses gtag.js (loaded lazily if not present)
|
|
9
|
+
* Server-side: uses GA4 Measurement Protocol
|
|
10
|
+
*
|
|
11
|
+
* Handles Google's consent mode (v2) natively — when consent state
|
|
12
|
+
* changes, we update gtag's consent settings automatically.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
interface GA4Config {
|
|
16
|
+
/** GA4 Measurement ID (e.g., "G-XXXXXXXXXX") */
|
|
17
|
+
measurementId: string;
|
|
18
|
+
/** Server-side: GA4 Measurement Protocol API secret */
|
|
19
|
+
apiSecret?: string;
|
|
20
|
+
/** Whether to load gtag.js if not already present (default: true) */
|
|
21
|
+
loadScript?: boolean;
|
|
22
|
+
/** Custom gtag.js URL (for self-hosting or proxy) */
|
|
23
|
+
gtagUrl?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Enable Google Consent Mode v2.
|
|
26
|
+
* When true, Junction's consent state maps to Google's consent categories.
|
|
27
|
+
*/
|
|
28
|
+
consentMode?: boolean;
|
|
29
|
+
/** Send page_view events automatically (default: false — Junction handles this) */
|
|
30
|
+
sendPageView?: boolean;
|
|
31
|
+
/** Custom event name mapping */
|
|
32
|
+
eventNameMap?: Record<string, string>;
|
|
33
|
+
/** Custom parameter mapping */
|
|
34
|
+
parameterMap?: Record<string, string>;
|
|
35
|
+
}
|
|
36
|
+
declare const ga4: Destination<GA4Config>;
|
|
37
|
+
|
|
38
|
+
export { type GA4Config, ga4 as default, ga4 };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
function mapConsentToGoogle(state) {
|
|
3
|
+
return {
|
|
4
|
+
ad_storage: state.marketing ? "granted" : "denied",
|
|
5
|
+
analytics_storage: state.analytics ? "granted" : "denied",
|
|
6
|
+
ad_user_data: state.marketing ? "granted" : "denied",
|
|
7
|
+
ad_personalization: state.personalization ? "granted" : "denied",
|
|
8
|
+
personalization_storage: state.personalization ? "granted" : "denied",
|
|
9
|
+
functionality_storage: state.necessary !== false ? "granted" : "denied",
|
|
10
|
+
security_storage: "granted"
|
|
11
|
+
// always granted
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
var GA4_EVENT_MAP = {
|
|
15
|
+
"page:viewed": "page_view",
|
|
16
|
+
"product:viewed": "view_item",
|
|
17
|
+
"product:added": "add_to_cart",
|
|
18
|
+
"product:removed": "remove_from_cart",
|
|
19
|
+
"product:list_viewed": "view_item_list",
|
|
20
|
+
"product:clicked": "select_item",
|
|
21
|
+
"cart:viewed": "view_cart",
|
|
22
|
+
"checkout:started": "begin_checkout",
|
|
23
|
+
"checkout:shipping_added": "add_shipping_info",
|
|
24
|
+
"checkout:payment_added": "add_payment_info",
|
|
25
|
+
"order:completed": "purchase",
|
|
26
|
+
"order:refunded": "refund",
|
|
27
|
+
"promotion:viewed": "view_promotion",
|
|
28
|
+
"promotion:clicked": "select_promotion",
|
|
29
|
+
"search:performed": "search",
|
|
30
|
+
"user:signed_up": "sign_up",
|
|
31
|
+
"user:logged_in": "login",
|
|
32
|
+
"content:shared": "share"
|
|
33
|
+
};
|
|
34
|
+
function getGA4EventName(event, config) {
|
|
35
|
+
const key = `${event.entity}:${event.action}`;
|
|
36
|
+
return config.eventNameMap?.[key] ?? GA4_EVENT_MAP[key] ?? `${event.entity}_${event.action}`;
|
|
37
|
+
}
|
|
38
|
+
var GA4_PARAM_MAP = {
|
|
39
|
+
product_id: "item_id",
|
|
40
|
+
name: "item_name",
|
|
41
|
+
category: "item_category",
|
|
42
|
+
brand: "item_brand",
|
|
43
|
+
variant: "item_variant",
|
|
44
|
+
price: "price",
|
|
45
|
+
quantity: "quantity",
|
|
46
|
+
order_id: "transaction_id",
|
|
47
|
+
total: "value",
|
|
48
|
+
revenue: "value",
|
|
49
|
+
tax: "tax",
|
|
50
|
+
shipping: "shipping",
|
|
51
|
+
currency: "currency",
|
|
52
|
+
coupon: "coupon",
|
|
53
|
+
search_term: "search_term"
|
|
54
|
+
};
|
|
55
|
+
function mapParameters(properties, config) {
|
|
56
|
+
const mapped = {};
|
|
57
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
58
|
+
const mappedKey = config.parameterMap?.[key] ?? GA4_PARAM_MAP[key] ?? key;
|
|
59
|
+
mapped[mappedKey] = value;
|
|
60
|
+
}
|
|
61
|
+
return mapped;
|
|
62
|
+
}
|
|
63
|
+
function transformEvent(event, config) {
|
|
64
|
+
return {
|
|
65
|
+
eventName: getGA4EventName(event, config),
|
|
66
|
+
parameters: mapParameters(event.properties, config)
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function loadGtag(measurementId, gtagUrl) {
|
|
70
|
+
if (typeof window === "undefined") return;
|
|
71
|
+
if (typeof window.gtag === "function") return;
|
|
72
|
+
window.dataLayer = window.dataLayer || [];
|
|
73
|
+
window.gtag = function() {
|
|
74
|
+
window.dataLayer.push(arguments);
|
|
75
|
+
};
|
|
76
|
+
window.gtag("js", /* @__PURE__ */ new Date());
|
|
77
|
+
const script = document.createElement("script");
|
|
78
|
+
script.async = true;
|
|
79
|
+
script.src = gtagUrl ?? `https://www.googletagmanager.com/gtag/js?id=${measurementId}`;
|
|
80
|
+
document.head.appendChild(script);
|
|
81
|
+
}
|
|
82
|
+
var ga4 = {
|
|
83
|
+
name: "ga4",
|
|
84
|
+
description: "Google Analytics 4",
|
|
85
|
+
version: "0.1.0",
|
|
86
|
+
consent: ["analytics"],
|
|
87
|
+
runtime: "both",
|
|
88
|
+
init(config) {
|
|
89
|
+
if (!config.measurementId) {
|
|
90
|
+
throw new Error("[Junction:GA4] measurementId is required");
|
|
91
|
+
}
|
|
92
|
+
if (typeof window !== "undefined" && config.loadScript !== false) {
|
|
93
|
+
loadGtag(config.measurementId, config.gtagUrl);
|
|
94
|
+
const gtagConfig = {
|
|
95
|
+
send_page_view: config.sendPageView ?? false
|
|
96
|
+
};
|
|
97
|
+
window.gtag?.("config", config.measurementId, gtagConfig);
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
transform(event) {
|
|
101
|
+
if (event.entity === "_system") return null;
|
|
102
|
+
return transformEvent(event, {});
|
|
103
|
+
},
|
|
104
|
+
async send(payload, config) {
|
|
105
|
+
const ga4Payload = payload;
|
|
106
|
+
if (typeof window !== "undefined" && typeof window.gtag === "function") {
|
|
107
|
+
window.gtag("event", ga4Payload.eventName, ga4Payload.parameters);
|
|
108
|
+
} else if (config.apiSecret) {
|
|
109
|
+
const url = `https://www.google-analytics.com/mp/collect?measurement_id=${config.measurementId}&api_secret=${config.apiSecret}`;
|
|
110
|
+
await fetch(url, {
|
|
111
|
+
method: "POST",
|
|
112
|
+
body: JSON.stringify({
|
|
113
|
+
client_id: "server",
|
|
114
|
+
// should be passed from client
|
|
115
|
+
events: [
|
|
116
|
+
{
|
|
117
|
+
name: ga4Payload.eventName,
|
|
118
|
+
params: ga4Payload.parameters
|
|
119
|
+
}
|
|
120
|
+
]
|
|
121
|
+
})
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
onConsent(state) {
|
|
126
|
+
if (typeof window !== "undefined" && typeof window.gtag === "function") {
|
|
127
|
+
window.gtag("consent", "update", mapConsentToGoogle(state));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
var index_default = ga4;
|
|
132
|
+
export {
|
|
133
|
+
index_default as default,
|
|
134
|
+
ga4
|
|
135
|
+
};
|
|
136
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @junctionjs/destination-ga4\n *\n * Google Analytics 4 destination for Junction.\n *\n * Client-side: uses gtag.js (loaded lazily if not present)\n * Server-side: uses GA4 Measurement Protocol\n *\n * Handles Google's consent mode (v2) natively — when consent state\n * changes, we update gtag's consent settings automatically.\n */\n\nimport type { Destination, JctEvent, ConsentState } from \"@junctionjs/core\";\n\n// ─── Configuration ───────────────────────────────────────────────\n\nexport interface GA4Config {\n /** GA4 Measurement ID (e.g., \"G-XXXXXXXXXX\") */\n measurementId: string;\n\n /** Server-side: GA4 Measurement Protocol API secret */\n apiSecret?: string;\n\n /** Whether to load gtag.js if not already present (default: true) */\n loadScript?: boolean;\n\n /** Custom gtag.js URL (for self-hosting or proxy) */\n gtagUrl?: string;\n\n /**\n * Enable Google Consent Mode v2.\n * When true, Junction's consent state maps to Google's consent categories.\n */\n consentMode?: boolean;\n\n /** Send page_view events automatically (default: false — Junction handles this) */\n sendPageView?: boolean;\n\n /** Custom event name mapping */\n eventNameMap?: Record<string, string>;\n\n /** Custom parameter mapping */\n parameterMap?: Record<string, string>;\n}\n\n// ─── Consent Mode Mapping ────────────────────────────────────────\n\n/**\n * Maps Junction consent categories to Google's consent mode signals.\n * Google's categories:\n * - ad_storage (marketing)\n * - analytics_storage (analytics)\n * - ad_user_data (marketing)\n * - ad_personalization (personalization)\n * - personalization_storage (personalization)\n * - functionality_storage (necessary)\n * - security_storage (necessary)\n */\nfunction mapConsentToGoogle(state: ConsentState): Record<string, \"granted\" | \"denied\"> {\n return {\n ad_storage: state.marketing ? \"granted\" : \"denied\",\n analytics_storage: state.analytics ? \"granted\" : \"denied\",\n ad_user_data: state.marketing ? \"granted\" : \"denied\",\n ad_personalization: state.personalization ? \"granted\" : \"denied\",\n personalization_storage: state.personalization ? \"granted\" : \"denied\",\n functionality_storage: state.necessary !== false ? \"granted\" : \"denied\",\n security_storage: \"granted\", // always granted\n };\n}\n\n// ─── GA4 Event Mapping ───────────────────────────────────────────\n\n/**\n * Maps Junction entity:action to GA4 recommended events where possible.\n * Falls back to custom event naming for non-standard events.\n *\n * https://developers.google.com/analytics/devguides/collection/ga4/reference/events\n */\nconst GA4_EVENT_MAP: Record<string, string> = {\n \"page:viewed\": \"page_view\",\n \"product:viewed\": \"view_item\",\n \"product:added\": \"add_to_cart\",\n \"product:removed\": \"remove_from_cart\",\n \"product:list_viewed\": \"view_item_list\",\n \"product:clicked\": \"select_item\",\n \"cart:viewed\": \"view_cart\",\n \"checkout:started\": \"begin_checkout\",\n \"checkout:shipping_added\": \"add_shipping_info\",\n \"checkout:payment_added\": \"add_payment_info\",\n \"order:completed\": \"purchase\",\n \"order:refunded\": \"refund\",\n \"promotion:viewed\": \"view_promotion\",\n \"promotion:clicked\": \"select_promotion\",\n \"search:performed\": \"search\",\n \"user:signed_up\": \"sign_up\",\n \"user:logged_in\": \"login\",\n \"content:shared\": \"share\",\n};\n\nfunction getGA4EventName(event: JctEvent, config: GA4Config): string {\n const key = `${event.entity}:${event.action}`;\n\n // Check custom mapping first, then default mapping, then generate\n return (\n config.eventNameMap?.[key] ??\n GA4_EVENT_MAP[key] ??\n `${event.entity}_${event.action}`\n );\n}\n\n// ─── Parameter Mapping ───────────────────────────────────────────\n\n/**\n * Maps Junction properties to GA4 parameters.\n * GA4 has specific parameter names for e-commerce events.\n */\nconst GA4_PARAM_MAP: Record<string, string> = {\n product_id: \"item_id\",\n name: \"item_name\",\n category: \"item_category\",\n brand: \"item_brand\",\n variant: \"item_variant\",\n price: \"price\",\n quantity: \"quantity\",\n order_id: \"transaction_id\",\n total: \"value\",\n revenue: \"value\",\n tax: \"tax\",\n shipping: \"shipping\",\n currency: \"currency\",\n coupon: \"coupon\",\n search_term: \"search_term\",\n};\n\nfunction mapParameters(\n properties: Record<string, unknown>,\n config: GA4Config,\n): Record<string, unknown> {\n const mapped: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(properties)) {\n const mappedKey = config.parameterMap?.[key] ?? GA4_PARAM_MAP[key] ?? key;\n mapped[mappedKey] = value;\n }\n\n return mapped;\n}\n\n// ─── Transform ───────────────────────────────────────────────────\n\ninterface GA4Payload {\n eventName: string;\n parameters: Record<string, unknown>;\n}\n\nfunction transformEvent(event: JctEvent, config: GA4Config): GA4Payload {\n return {\n eventName: getGA4EventName(event, config),\n parameters: mapParameters(event.properties, config),\n };\n}\n\n// ─── gtag.js Loader ──────────────────────────────────────────────\n\nfunction loadGtag(measurementId: string, gtagUrl?: string): void {\n if (typeof window === \"undefined\") return;\n if (typeof (window as any).gtag === \"function\") return;\n\n // Initialize dataLayer\n (window as any).dataLayer = (window as any).dataLayer || [];\n (window as any).gtag = function () {\n (window as any).dataLayer.push(arguments);\n };\n (window as any).gtag(\"js\", new Date());\n\n // Load script\n const script = document.createElement(\"script\");\n script.async = true;\n script.src = gtagUrl ?? `https://www.googletagmanager.com/gtag/js?id=${measurementId}`;\n document.head.appendChild(script);\n}\n\n// ─── Destination Export ──────────────────────────────────────────\n\nexport const ga4: Destination<GA4Config> = {\n name: \"ga4\",\n description: \"Google Analytics 4\",\n version: \"0.1.0\",\n consent: [\"analytics\"],\n runtime: \"both\",\n\n init(config: GA4Config) {\n if (!config.measurementId) {\n throw new Error(\"[Junction:GA4] measurementId is required\");\n }\n\n // Client-side: load gtag.js if needed\n if (typeof window !== \"undefined\" && config.loadScript !== false) {\n loadGtag(config.measurementId, config.gtagUrl);\n\n // Configure GA4\n const gtagConfig: Record<string, unknown> = {\n send_page_view: config.sendPageView ?? false,\n };\n\n (window as any).gtag?.(\"config\", config.measurementId, gtagConfig);\n }\n },\n\n transform(event: JctEvent) {\n if (event.entity === \"_system\") return null;\n return transformEvent(event, {} as GA4Config);\n },\n\n async send(payload: unknown, config: GA4Config) {\n const ga4Payload = payload as GA4Payload;\n\n if (typeof window !== \"undefined\" && typeof (window as any).gtag === \"function\") {\n // Client-side: use gtag\n (window as any).gtag(\"event\", ga4Payload.eventName, ga4Payload.parameters);\n } else if (config.apiSecret) {\n // Server-side: Measurement Protocol\n const url = `https://www.google-analytics.com/mp/collect?measurement_id=${config.measurementId}&api_secret=${config.apiSecret}`;\n\n await fetch(url, {\n method: \"POST\",\n body: JSON.stringify({\n client_id: \"server\", // should be passed from client\n events: [\n {\n name: ga4Payload.eventName,\n params: ga4Payload.parameters,\n },\n ],\n }),\n });\n }\n },\n\n onConsent(state: ConsentState) {\n // Update Google Consent Mode\n if (typeof window !== \"undefined\" && typeof (window as any).gtag === \"function\") {\n (window as any).gtag(\"consent\", \"update\", mapConsentToGoogle(state));\n }\n },\n};\n\nexport default ga4;\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@junctionjs/destination-ga4",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Google Analytics 4 destination for Junction — gtag.js, Measurement Protocol, Consent Mode v2",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": ["dist", "README.md"],
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsup src/index.ts --format esm --dts --sourcemap --target es2022 --no-config --external @junctionjs/core",
|
|
17
|
+
"dev": "tsup src/index.ts --format esm --dts --watch --no-config --external @junctionjs/core",
|
|
18
|
+
"clean": "rm -rf dist",
|
|
19
|
+
"typecheck": "tsc --noEmit"
|
|
20
|
+
},
|
|
21
|
+
"peerDependencies": {
|
|
22
|
+
"@junctionjs/core": "*"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@junctionjs/core": "*",
|
|
26
|
+
"tsup": "^8.0.0",
|
|
27
|
+
"typescript": "^5.5.0"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=18.0.0"
|
|
31
|
+
},
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://github.com/tyssejc/junction.git",
|
|
36
|
+
"directory": "packages/destination-ga4"
|
|
37
|
+
},
|
|
38
|
+
"keywords": ["analytics", "google-analytics", "ga4", "junction-destination"]
|
|
39
|
+
}
|