@wapitee/typhoonx-hydrogen 0.7.0 → 0.8.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 CHANGED
@@ -42,15 +42,12 @@ const {nonce, header, NonceProvider} = createContentSecurityPolicy({
42
42
 
43
43
  ### Props
44
44
 
45
- | Prop | Type | Required | Description |
46
- | -------------- | -------- | -------- | ----------------------------------------------------------------------------------------------------------------- |
47
- | `merchantId` | `string` | yes | TyphoonX merchant ID (`TPX-…`) |
48
- | `shopId` | `string` | yes | Shopify store ID |
49
- | `cookieDomain` | `string` | no | Cookie `Domain` for a first-party client id. Defaults to the current hostname's apex domain (e.g. `.example.com`) |
50
-
51
- ### Meta Pixel
52
-
53
- If the storefront runs Meta Pixel, every event also carries its `_fbp` cookie as `fbp` and its `_fbc` cookie as `fbc`. When `_fbc` is not set yet but the page URL has `fbclid`, `fbc` is built as `fb.1.<timestamp>.<fbclid>`. Missing values are omitted.
45
+ | Prop | Type | Required | Description |
46
+ | --------------- | -------- | -------- | ----------------------------------------------------------------------------------------------------------------- |
47
+ | `merchantId` | `string` | yes | TyphoonX merchant ID (`TPX-…`) |
48
+ | `shopId` | `string` | yes | Shopify store ID |
49
+ | `cookieDomain` | `string` | no | Cookie `Domain` for a first-party client id. Defaults to the current hostname's apex domain (e.g. `.example.com`) |
50
+ | `measurementId` | `string` | no | GA4 measurement ID (`G-…`). Enables `ga_session_id` |
54
51
 
55
52
  ## License
56
53
 
@@ -2,6 +2,8 @@ export interface TyphoonXProps {
2
2
  merchantId: string;
3
3
  shopId: string;
4
4
  cookieDomain?: string;
5
+ /** GA4 measurement ID (`G-…`) whose `_ga_<ID>` cookie supplies `ga_session_id`. */
6
+ measurementId?: string;
5
7
  }
6
8
  export default function TyphoonX(props: TyphoonXProps): import("react").JSX.Element | null;
7
9
  //# sourceMappingURL=TyphoonX.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"TyphoonX.d.ts","sourceRoot":"","sources":["../src/TyphoonX.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAqCD,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,KAAK,EAAE,aAAa,sCAuBpD"}
1
+ {"version":3,"file":"TyphoonX.d.ts","sourceRoot":"","sources":["../src/TyphoonX.tsx"],"names":[],"mappings":"AASA,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAmCD,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,KAAK,EAAE,aAAa,sCAuBpD"}
package/dist/TyphoonX.js CHANGED
@@ -2,6 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { flattenConnection, parseGid, useAnalytics } from '@shopify/hydrogen';
3
3
  import { useEffect, useRef, useState } from 'react';
4
4
  import { getOrCreateClientId, hasClientId } from './client-id.js';
5
+ import { getGoogleIds } from './google-ids.js';
5
6
  import { getMetaPixelIds } from './meta-pixel.js';
6
7
  const COLLECT_ENDPOINT = 'https://spell.typhoonx.io/api/v1/receive';
7
8
  export default function TyphoonX(props) {
@@ -21,7 +22,7 @@ export default function TyphoonX(props) {
21
22
  }
22
23
  return _jsx(TyphoonXClient, { ...props });
23
24
  }
24
- function TyphoonXClient({ cookieDomain, merchantId, shopId }) {
25
+ function TyphoonXClient({ cookieDomain, measurementId, merchantId, shopId, }) {
25
26
  const { canTrack, register, subscribe } = useAnalytics();
26
27
  const { ready } = register('TyphoonX');
27
28
  const currentUrlRef = useRef(null);
@@ -61,6 +62,7 @@ function TyphoonXClient({ cookieDomain, merchantId, shopId }) {
61
62
  user_agent: window.navigator.userAgent,
62
63
  ...(currency === undefined ? {} : { currency }),
63
64
  ...getMetaPixelIds(url),
65
+ ...getGoogleIds(url, measurementId),
64
66
  });
65
67
  subscribe('cart_viewed', (data) => {
66
68
  const { cart } = data;
@@ -185,6 +187,14 @@ function TyphoonXClient({ cookieDomain, merchantId, shopId }) {
185
187
  });
186
188
  });
187
189
  ready();
188
- }, [cookieDomain, merchantId, shopId, canTrack, ready, subscribe]);
190
+ }, [
191
+ cookieDomain,
192
+ measurementId,
193
+ merchantId,
194
+ shopId,
195
+ canTrack,
196
+ ready,
197
+ subscribe,
198
+ ]);
189
199
  return null;
190
200
  }
@@ -0,0 +1,13 @@
1
+ export interface GoogleIds {
2
+ ga_client_id?: string | undefined;
3
+ ga_session_id?: string | undefined;
4
+ gbraid?: string | undefined;
5
+ gclid?: string | undefined;
6
+ wbraid?: string | undefined;
7
+ }
8
+ /**
9
+ * GA4 client and session IDs from `_ga` / `_ga_<ID>`, and Google Ads click IDs
10
+ * from `_gcl_aw` falling back to `url`'s `gclid`, `gbraid` and `wbraid`.
11
+ */
12
+ export declare function getGoogleIds(url: string, measurementId?: string): GoogleIds;
13
+ //# sourceMappingURL=google-ids.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google-ids.d.ts","sourceRoot":"","sources":["../src/google-ids.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,SAAS;IACxB,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAgB3E"}
@@ -0,0 +1,29 @@
1
+ import CookieLib from 'universal-cookie';
2
+ // Runtime default export is the class.
3
+ const cookies = new CookieLib();
4
+ /**
5
+ * GA4 client and session IDs from `_ga` / `_ga_<ID>`, and Google Ads click IDs
6
+ * from `_gcl_aw` falling back to `url`'s `gclid`, `gbraid` and `wbraid`.
7
+ */
8
+ export function getGoogleIds(url, measurementId) {
9
+ const params = searchParams(url);
10
+ const cookie = (name) => cookies.get(name, { doNotParse: true });
11
+ const param = (name) => params?.get(name)?.match(/^.+$/)?.[0];
12
+ return {
13
+ ga_client_id: cookie('_ga')?.match(/^GA\d\.\d+\.(.+)$/)?.[1],
14
+ ga_session_id: measurementId
15
+ ? cookie(`_ga_${measurementId.replace(/^G-/, '')}`)?.match(/^GS\d\.\d+\.s?(\d+)/)?.[1]
16
+ : undefined,
17
+ gbraid: param('gbraid'),
18
+ gclid: cookie('_gcl_aw')?.match(/^GCL\.\d+\.(.+)$/)?.[1] ?? param('gclid'),
19
+ wbraid: param('wbraid'),
20
+ };
21
+ }
22
+ function searchParams(url) {
23
+ try {
24
+ return new URL(url).searchParams;
25
+ }
26
+ catch {
27
+ return undefined;
28
+ }
29
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wapitee/typhoonx-hydrogen",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "TyphoonX Hydrogen Analytics subscriber",
5
5
  "keywords": [
6
6
  "typhoonx",
@@ -10,14 +10,14 @@
10
10
  "react",
11
11
  "storefront"
12
12
  ],
13
- "homepage": "https://github.com/Wapitee-Interactive-Marketing-Limited/typhoonx-js/tree/main/packages/typhoonx-hydrogen",
13
+ "homepage": "https://github.com/Wapitee-Interactive-Marketing-Limited/typhoonx-js/tree/main/packages/hydrogen",
14
14
  "bugs": {
15
15
  "url": "https://github.com/Wapitee-Interactive-Marketing-Limited/typhoonx-js/issues"
16
16
  },
17
17
  "repository": {
18
18
  "type": "git",
19
19
  "url": "git+https://github.com/Wapitee-Interactive-Marketing-Limited/typhoonx-js.git",
20
- "directory": "packages/typhoonx-hydrogen"
20
+ "directory": "packages/hydrogen"
21
21
  },
22
22
  "license": "MIT",
23
23
  "author": "jay@wapitee.io",