@shopify/hydrogen 0.17.2 → 0.17.3
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/CHANGELOG.md +8 -0
- package/dist/esnext/client.d.ts +2 -0
- package/dist/esnext/client.js +2 -0
- package/dist/esnext/components/ProductProvider/ProductProvider.client.js +1 -1
- package/dist/esnext/foundation/Analytics/ClientAnalytics.d.ts +1 -0
- package/dist/esnext/foundation/Analytics/ClientAnalytics.js +7 -1
- package/dist/esnext/foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetrics.client.d.ts +7 -0
- package/dist/esnext/foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetrics.client.js +64 -0
- package/dist/esnext/foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetrics.server.d.ts +1 -0
- package/dist/esnext/foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetrics.server.js +24 -0
- package/dist/esnext/foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetricsDebug.client.d.ts +1 -0
- package/dist/esnext/foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetricsDebug.client.js +23 -0
- package/dist/esnext/foundation/Analytics/const.d.ts +1 -0
- package/dist/esnext/foundation/Analytics/const.js +1 -0
- package/dist/esnext/foundation/Route/Route.server.js +1 -10
- package/dist/esnext/hooks/useParsedMetafields/useParsedMetafields.js +0 -2
- package/dist/esnext/index.d.ts +1 -0
- package/dist/esnext/index.js +1 -0
- package/dist/esnext/version.d.ts +1 -1
- package/dist/esnext/version.js +1 -1
- package/dist/node/foundation/Analytics/ClientAnalytics.d.ts +1 -0
- package/dist/node/foundation/Analytics/ClientAnalytics.js +7 -1
- package/dist/node/foundation/Analytics/const.d.ts +1 -0
- package/dist/node/foundation/Analytics/const.js +1 -0
- package/dist/node/version.d.ts +1 -1
- package/dist/node/version.js +1 -1
- package/package.json +1 -1
- package/dist/esnext/foundation/Boomerang/Boomerang.client.d.ts +0 -9
- package/dist/esnext/foundation/Boomerang/Boomerang.client.js +0 -66
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.17.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1096](https://github.com/Shopify/hydrogen/pull/1096) [`0a15376e`](https://github.com/Shopify/hydrogen/commit/0a15376ec806054ddd5848d9dbfa6e50a85beb49) Thanks [@wizardlyhel](https://github.com/wizardlyhel)! - Make performance data available with ClientAnalytics and optional for developers to include
|
|
8
|
+
|
|
9
|
+
* [#1209](https://github.com/Shopify/hydrogen/pull/1209) [`d0dada0a`](https://github.com/Shopify/hydrogen/commit/d0dada0a0b3170d2cb885d2f29bbbef0c6d9e9e4) Thanks [@blittle](https://github.com/blittle)! - Make metafields optional within the ProductProvider. Fixes #1127
|
|
10
|
+
|
|
3
11
|
## 0.17.2
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
package/dist/esnext/client.d.ts
CHANGED
|
@@ -11,3 +11,5 @@ export { useRouteParams } from './foundation/useRouteParams/useRouteParams';
|
|
|
11
11
|
export { useNavigate } from './foundation/useNavigate/useNavigate';
|
|
12
12
|
export { fetchSync } from './foundation/fetchSync/client/fetchSync';
|
|
13
13
|
export { suspendFunction, preloadFunction } from './utilities/suspense';
|
|
14
|
+
export { PerformanceMetrics } from './foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetrics.client';
|
|
15
|
+
export { PerformanceMetricsDebug } from './foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetricsDebug.client';
|
package/dist/esnext/client.js
CHANGED
|
@@ -11,3 +11,5 @@ export { useRouteParams } from './foundation/useRouteParams/useRouteParams';
|
|
|
11
11
|
export { useNavigate } from './foundation/useNavigate/useNavigate';
|
|
12
12
|
export { fetchSync } from './foundation/fetchSync/client/fetchSync';
|
|
13
13
|
export { suspendFunction, preloadFunction } from './utilities/suspense';
|
|
14
|
+
export { PerformanceMetrics } from './foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetrics.client';
|
|
15
|
+
export { PerformanceMetricsDebug } from './foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetricsDebug.client';
|
|
@@ -8,7 +8,7 @@ import { ProductOptionsProvider } from './ProductOptionsProvider.client';
|
|
|
8
8
|
* this component can use the `useProduct` hook.
|
|
9
9
|
*/
|
|
10
10
|
export function ProductProvider({ children, data: product, initialVariantId, }) {
|
|
11
|
-
const metafields = useParsedMetafields(product.metafields);
|
|
11
|
+
const metafields = useParsedMetafields(product.metafields || {});
|
|
12
12
|
// @ts-expect-error The types here are broken on main, need to come back and fix them sometime
|
|
13
13
|
const providerValue = useMemo(() => {
|
|
14
14
|
return {
|
|
@@ -78,7 +78,13 @@ function subscribe(eventname, callbackFunction) {
|
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
80
|
function pushToServer(init, searchParam) {
|
|
81
|
-
return fetch(`${EVENT_PATHNAME}${searchParam ? `?${searchParam}` : ''}`,
|
|
81
|
+
return fetch(`${EVENT_PATHNAME}${searchParam ? `?${searchParam}` : ''}`, Object.assign({
|
|
82
|
+
method: 'post',
|
|
83
|
+
headers: {
|
|
84
|
+
'cache-control': 'no-cache',
|
|
85
|
+
'Content-Type': 'application/json',
|
|
86
|
+
},
|
|
87
|
+
}, init));
|
|
82
88
|
}
|
|
83
89
|
export const ClientAnalytics = {
|
|
84
90
|
pushToPageAnalyticsData,
|
package/dist/esnext/foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetrics.client.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { loadScript } from '../../../../utilities';
|
|
3
|
+
import { ClientAnalytics } from '../../index';
|
|
4
|
+
import { useShop } from '../../../useShop';
|
|
5
|
+
const URL = 'https://cdn.shopify.com/shopifycloud/boomerang/shopify-boomerang-hydrogen.min.js';
|
|
6
|
+
export function PerformanceMetrics() {
|
|
7
|
+
const { storeDomain } = useShop();
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
try {
|
|
10
|
+
(function () {
|
|
11
|
+
if (window.BOOMR &&
|
|
12
|
+
(window.BOOMR.version || window.BOOMR.snippetExecuted)) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
// Executes only on first mount
|
|
16
|
+
window.BOOMR = window.BOOMR || {};
|
|
17
|
+
window.BOOMR.hydrogenPerformanceEvent = (data) => {
|
|
18
|
+
ClientAnalytics.publish(ClientAnalytics.eventNames.PERFORMANCE, true, data);
|
|
19
|
+
ClientAnalytics.pushToServer({
|
|
20
|
+
body: JSON.stringify(data),
|
|
21
|
+
}, ClientAnalytics.eventNames.PERFORMANCE);
|
|
22
|
+
};
|
|
23
|
+
window.BOOMR.storeDomain = storeDomain;
|
|
24
|
+
function boomerangSaveLoadTime(e) {
|
|
25
|
+
window.BOOMR_onload = (e && e.timeStamp) || Date.now();
|
|
26
|
+
}
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
function boomerangInit(e) {
|
|
29
|
+
e.detail.BOOMR.init();
|
|
30
|
+
e.detail.BOOMR.t_end = Date.now();
|
|
31
|
+
}
|
|
32
|
+
if (window.addEventListener) {
|
|
33
|
+
window.addEventListener('load', boomerangSaveLoadTime, false);
|
|
34
|
+
// @ts-ignore
|
|
35
|
+
}
|
|
36
|
+
else if (window.attachEvent) {
|
|
37
|
+
// @ts-ignore
|
|
38
|
+
window.attachEvent('onload', boomerangSaveLoadTime);
|
|
39
|
+
}
|
|
40
|
+
if (document.addEventListener) {
|
|
41
|
+
document.addEventListener('onBoomerangLoaded', boomerangInit);
|
|
42
|
+
// @ts-ignore
|
|
43
|
+
}
|
|
44
|
+
else if (document.attachEvent) {
|
|
45
|
+
// @ts-ignore
|
|
46
|
+
document.attachEvent('onpropertychange', function (e) {
|
|
47
|
+
if (!e)
|
|
48
|
+
e = event;
|
|
49
|
+
if (e.propertyName === 'onBoomerangLoaded')
|
|
50
|
+
boomerangInit(e);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
})();
|
|
54
|
+
loadScript(URL).catch(() => {
|
|
55
|
+
// ignore if boomerang doesn't load
|
|
56
|
+
// most likely because of an ad blocker
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
// Do nothing
|
|
61
|
+
}
|
|
62
|
+
}, [storeDomain]);
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function request(request: Request, data?: any, contentType?: string): void;
|
package/dist/esnext/foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetrics.server.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export function request(request, data, contentType) {
|
|
2
|
+
const url = new URL(request.url);
|
|
3
|
+
if (url.search === '?performance' && contentType === 'json') {
|
|
4
|
+
const initTime = new Date().getTime();
|
|
5
|
+
fetch('https://monorail-edge.shopifysvc.com/v1/produce', {
|
|
6
|
+
method: 'post',
|
|
7
|
+
headers: {
|
|
8
|
+
'content-type': 'text/plain',
|
|
9
|
+
'x-forwarded-for': request.headers.get('x-forwarded-for') || '',
|
|
10
|
+
'user-agent': request.headers.get('user-agent') || '',
|
|
11
|
+
},
|
|
12
|
+
body: JSON.stringify({
|
|
13
|
+
schema_id: 'hydrogen_buyer_performance/2.0',
|
|
14
|
+
payload: data,
|
|
15
|
+
metadata: {
|
|
16
|
+
event_created_at_ms: initTime,
|
|
17
|
+
event_sent_at_ms: new Date().getTime(),
|
|
18
|
+
},
|
|
19
|
+
}),
|
|
20
|
+
}).catch((error) => {
|
|
21
|
+
// send to bugsnag? oxygen?
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function PerformanceMetricsDebug(): null;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { ClientAnalytics } from '../../index';
|
|
3
|
+
const PAD = 10;
|
|
4
|
+
let isInit = false;
|
|
5
|
+
export function PerformanceMetricsDebug() {
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
if (!isInit) {
|
|
8
|
+
isInit = true;
|
|
9
|
+
ClientAnalytics.subscribe(ClientAnalytics.eventNames.PERFORMANCE, (data) => {
|
|
10
|
+
console.group(`Performance - ${data.page_load_type} load`);
|
|
11
|
+
logMetricIf('TTFB:', data.response_start - data.navigation_start);
|
|
12
|
+
logMetricIf('FCP:', data.first_contentful_paint);
|
|
13
|
+
logMetricIf('LCP:', data.largest_contentful_paint);
|
|
14
|
+
logMetricIf('Duration:', data.response_end - data.navigation_start);
|
|
15
|
+
console.groupEnd();
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
function logMetricIf(lable, data) {
|
|
22
|
+
data && console.log(`${lable.padEnd(PAD)}${Math.round(data)} ms`);
|
|
23
|
+
}
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import React, { cloneElement } from 'react';
|
|
2
2
|
import { useServerRequest } from '../ServerRequestProvider';
|
|
3
3
|
import { matchPath } from '../../utilities/matchPath';
|
|
4
|
-
import { Boomerang } from '../Boomerang/Boomerang.client';
|
|
5
4
|
import { RouteParamsProvider } from '../useRouteParams/RouteParamsProvider.client';
|
|
6
|
-
import { useServerAnalytics } from '../Analytics';
|
|
7
5
|
/**
|
|
8
6
|
* The `Route` component is used to set up a route in Hydrogen that's independent of the file system. Routes are
|
|
9
7
|
* matched in the order that they're defined.
|
|
10
8
|
*/
|
|
11
9
|
export function Route({ path, page }) {
|
|
12
|
-
var _a;
|
|
13
10
|
const request = useServerRequest();
|
|
14
11
|
const { routeRendered, serverProps } = request.ctx.router;
|
|
15
12
|
if (routeRendered)
|
|
@@ -25,13 +22,7 @@ export function Route({ path, page }) {
|
|
|
25
22
|
if (match) {
|
|
26
23
|
request.ctx.router.routeRendered = true;
|
|
27
24
|
request.ctx.router.routeParams = match.params;
|
|
28
|
-
|
|
29
|
-
useServerAnalytics({
|
|
30
|
-
templateName: name,
|
|
31
|
-
});
|
|
32
|
-
return (React.createElement(RouteParamsProvider, { routeParams: match.params },
|
|
33
|
-
cloneElement(page, { params: match.params || {}, ...serverProps }),
|
|
34
|
-
name ? React.createElement(Boomerang, { pageTemplate: name }) : null));
|
|
25
|
+
return (React.createElement(RouteParamsProvider, { routeParams: match.params }, cloneElement(page, { params: match.params || {}, ...serverProps })));
|
|
35
26
|
}
|
|
36
27
|
return null;
|
|
37
28
|
}
|
|
@@ -7,8 +7,6 @@ import { flattenConnection, parseMetafieldValue } from '../../utilities';
|
|
|
7
7
|
export function useParsedMetafields(
|
|
8
8
|
/** A [MetafieldConnection](https://shopify.dev/api/storefront/reference/common-objects/metafieldconnection). */
|
|
9
9
|
metafields) {
|
|
10
|
-
var _a, _b;
|
|
11
|
-
(_b = (_a = metafields === null || metafields === void 0 ? void 0 : metafields.edges) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.node;
|
|
12
10
|
return useMemo(() => {
|
|
13
11
|
if (!metafields) {
|
|
14
12
|
throw new Error(`'useParsedMetafields' needs metafields`);
|
package/dist/esnext/index.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export { CartQuery } from './components/CartProvider/cart-queries';
|
|
|
15
15
|
export { generateCacheControlHeader, NoStore, CacheSeconds, CacheMinutes, CacheHours, CacheDays, CacheWeeks, CacheMonths, CacheCustom, } from './framework/CachingStrategy';
|
|
16
16
|
export { fetchSync } from './foundation/fetchSync/server/fetchSync';
|
|
17
17
|
export { useServerAnalytics } from './foundation/Analytics';
|
|
18
|
+
export * as PerformanceMetricsServerAnalyticsConnector from './foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetrics.server';
|
|
18
19
|
export { useSession } from './foundation/useSession/useSession';
|
|
19
20
|
export { CookieSessionStorage } from './foundation/CookieSessionStorage/CookieSessionStorage';
|
|
20
21
|
export { MemorySessionStorage } from './foundation/MemorySessionStorage/MemorySessionStorage';
|
package/dist/esnext/index.js
CHANGED
|
@@ -19,6 +19,7 @@ export { CartQuery } from './components/CartProvider/cart-queries';
|
|
|
19
19
|
export { generateCacheControlHeader, NoStore, CacheSeconds, CacheMinutes, CacheHours, CacheDays, CacheWeeks, CacheMonths, CacheCustom, } from './framework/CachingStrategy';
|
|
20
20
|
export { fetchSync } from './foundation/fetchSync/server/fetchSync';
|
|
21
21
|
export { useServerAnalytics } from './foundation/Analytics';
|
|
22
|
+
export * as PerformanceMetricsServerAnalyticsConnector from './foundation/Analytics/connectors/PerformanceMetrics/PerformanceMetrics.server';
|
|
22
23
|
export { useSession } from './foundation/useSession/useSession';
|
|
23
24
|
export { CookieSessionStorage } from './foundation/CookieSessionStorage/CookieSessionStorage';
|
|
24
25
|
export { MemorySessionStorage } from './foundation/MemorySessionStorage/MemorySessionStorage';
|
package/dist/esnext/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const LIB_VERSION = "0.17.
|
|
1
|
+
export declare const LIB_VERSION = "0.17.3";
|
package/dist/esnext/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const LIB_VERSION = '0.17.
|
|
1
|
+
export const LIB_VERSION = '0.17.3';
|
|
@@ -81,7 +81,13 @@ function subscribe(eventname, callbackFunction) {
|
|
|
81
81
|
};
|
|
82
82
|
}
|
|
83
83
|
function pushToServer(init, searchParam) {
|
|
84
|
-
return fetch(`${constants_1.EVENT_PATHNAME}${searchParam ? `?${searchParam}` : ''}`,
|
|
84
|
+
return fetch(`${constants_1.EVENT_PATHNAME}${searchParam ? `?${searchParam}` : ''}`, Object.assign({
|
|
85
|
+
method: 'post',
|
|
86
|
+
headers: {
|
|
87
|
+
'cache-control': 'no-cache',
|
|
88
|
+
'Content-Type': 'application/json',
|
|
89
|
+
},
|
|
90
|
+
}, init));
|
|
85
91
|
}
|
|
86
92
|
exports.ClientAnalytics = {
|
|
87
93
|
pushToPageAnalyticsData,
|
package/dist/node/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const LIB_VERSION = "0.17.
|
|
1
|
+
export declare const LIB_VERSION = "0.17.3";
|
package/dist/node/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { useEffect } from 'react';
|
|
2
|
-
import { loadScript } from '../../utilities';
|
|
3
|
-
import { useShop } from '../useShop';
|
|
4
|
-
const URL = 'https://cdn.shopify.com/shopifycloud/boomerang/shopify-boomerang-hydrogen.min.js';
|
|
5
|
-
export function Boomerang({ pageTemplate }) {
|
|
6
|
-
const { storeDomain } = useShop();
|
|
7
|
-
const templateName = pageTemplate && pageTemplate !== null
|
|
8
|
-
? pageTemplate.toLowerCase()
|
|
9
|
-
: 'not-set';
|
|
10
|
-
useEffect(() => {
|
|
11
|
-
(function () {
|
|
12
|
-
function boomerangAddVar() {
|
|
13
|
-
if (window.BOOMR && window.BOOMR.addVar) {
|
|
14
|
-
window.BOOMR.addVar('page_template', templateName);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
// Executes on every mount
|
|
18
|
-
boomerangAddVar();
|
|
19
|
-
if (window.BOOMR &&
|
|
20
|
-
(window.BOOMR.version || window.BOOMR.snippetExecuted)) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
// Executes only on first mount
|
|
24
|
-
window.BOOMR = window.BOOMR || {};
|
|
25
|
-
window.BOOMR.storeDomain = storeDomain;
|
|
26
|
-
window.BOOMR.pageTemplate = templateName;
|
|
27
|
-
function boomerangSaveLoadTime(e) {
|
|
28
|
-
window.BOOMR_onload = (e && e.timeStamp) || Date.now();
|
|
29
|
-
}
|
|
30
|
-
// @ts-ignore
|
|
31
|
-
function boomerangInit(e) {
|
|
32
|
-
e.detail.BOOMR.init({
|
|
33
|
-
producer_url: 'https://monorail-edge.shopifysvc.com/v1/produce',
|
|
34
|
-
});
|
|
35
|
-
e.detail.BOOMR.t_end = Date.now();
|
|
36
|
-
boomerangAddVar();
|
|
37
|
-
}
|
|
38
|
-
if (window.addEventListener) {
|
|
39
|
-
window.addEventListener('load', boomerangSaveLoadTime, false);
|
|
40
|
-
// @ts-ignore
|
|
41
|
-
}
|
|
42
|
-
else if (window.attachEvent) {
|
|
43
|
-
// @ts-ignore
|
|
44
|
-
window.attachEvent('onload', boomerangSaveLoadTime);
|
|
45
|
-
}
|
|
46
|
-
if (document.addEventListener) {
|
|
47
|
-
document.addEventListener('onBoomerangLoaded', boomerangInit);
|
|
48
|
-
// @ts-ignore
|
|
49
|
-
}
|
|
50
|
-
else if (document.attachEvent) {
|
|
51
|
-
// @ts-ignore
|
|
52
|
-
document.attachEvent('onpropertychange', function (e) {
|
|
53
|
-
if (!e)
|
|
54
|
-
e = event;
|
|
55
|
-
if (e.propertyName === 'onBoomerangLoaded')
|
|
56
|
-
boomerangInit(e);
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
})();
|
|
60
|
-
loadScript(URL).catch(() => {
|
|
61
|
-
// ignore if boomerang doesn't load
|
|
62
|
-
// most likely because of a ad blocker
|
|
63
|
-
});
|
|
64
|
-
}, [storeDomain, pageTemplate]);
|
|
65
|
-
return null;
|
|
66
|
-
}
|