diff --git a/packages/hydrogen/src/analytics-manager/AnalyticsProvider.test.tsx b/packages/hydrogen/src/analytics-manager/AnalyticsProvider.test.tsx
index 2ff514b15..589bedba6 100644
--- a/packages/hydrogen/src/analytics-manager/AnalyticsProvider.test.tsx
+++ b/packages/hydrogen/src/analytics-manager/AnalyticsProvider.test.tsx
@@ -308,9 +308,11 @@ function triggerCartUpdate({
});
}
-function customerPrivacyReady() {
- const event = new CustomEvent('visitorConsentCollected');
- document.dispatchEvent(event);
+function mockPerfKit() {
+ window.PerfKit = {
+ navigate: () => {},
+ setPageType: () => {},
+ };
}
function LoopAnalytics({
@@ -325,8 +327,13 @@ function LoopAnalytics({
}): JSX.Element {
const analytics = useAnalytics();
const {ready} = analytics.register('loopAnalytics');
+ const {ready: customerPrivacyReady} = analytics.register(
+ 'Internal_Shopify_CustomerPrivacy',
+ );
+ const {ready: perfKitReady} = analytics.register('Internal_Shopify_Perf_Kit');
useEffect(() => {
+ mockPerfKit();
if (registerCallback) {
registerCallback(analytics, ready);
} else {
@@ -335,6 +342,7 @@ function LoopAnalytics({
});
customerPrivacyReady();
+ perfKitReady();
return (
{typeof children === 'function' ? children(analytics) : children}
diff --git a/packages/hydrogen/src/analytics-manager/AnalyticsProvider.tsx b/packages/hydrogen/src/analytics-manager/AnalyticsProvider.tsx
index 29e853fa3..bce0684ae 100644
--- a/packages/hydrogen/src/analytics-manager/AnalyticsProvider.tsx
+++ b/packages/hydrogen/src/analytics-manager/AnalyticsProvider.tsx
@@ -37,6 +37,7 @@ import {ShopifyAnalytics} from './ShopifyAnalytics';
import {CartAnalytics} from './CartAnalytics';
import type {CustomerPrivacyApiProps} from '../customer-privacy/ShopifyCustomerPrivacy';
import type {Storefront} from '../storefront';
+import {PerfKit} from './PerfKit';
import {errorOnce, warnOnce} from '../utils/warning';
export type ShopAnalytics = {
@@ -359,6 +360,7 @@ function AnalyticsProvider({
domain={cookieDomain}
/>
)}
+ {!!shop && }
);
}
diff --git a/packages/hydrogen/src/analytics-manager/PerfKit.tsx b/packages/hydrogen/src/analytics-manager/PerfKit.tsx
new file mode 100644
index 000000000..d8767c41a
--- /dev/null
+++ b/packages/hydrogen/src/analytics-manager/PerfKit.tsx
@@ -0,0 +1,60 @@
+import {parseGid, useLoadScript} from '@shopify/hydrogen-react';
+import {ShopAnalytics, useAnalytics} from './AnalyticsProvider';
+import {AnalyticsEvent} from './events';
+import {useEffect, useRef} from 'react';
+
+declare global {
+ interface Window {
+ PerfKit: {
+ navigate: () => void;
+ setPageType: (pageType: string) => void;
+ };
+ }
+}
+
+// Pin to a version that have SPA support.
+// TODO: Update to a stable version when available.
+const PERF_KIT_UNSTABLE =
+ 'https://cdn.shopify.com/shopifycloud/perf-kit/shopify-perf-kit-1bd852a.min.js';
+
+export function PerfKit({shop}: {shop: ShopAnalytics}) {
+ const loadedEvent = useRef(false);
+ const {subscribe, register} = useAnalytics();
+ const {ready} = register('Internal_Shopify_Perf_Kit');
+
+ const scriptStatus = useLoadScript(PERF_KIT_UNSTABLE, {
+ attributes: {
+ id: 'perfkit',
+ 'data-application': 'hydrogen',
+ 'data-shop-id': parseGid(shop.shopId).id.toString(),
+ 'data-storefront-id': shop.hydrogenSubchannelId,
+ 'data-monorail-region': 'global',
+ 'data-spa-mode': 'true',
+ 'data-resource-timing-sampling-rate': '100',
+ },
+ });
+
+ useEffect(() => {
+ if (scriptStatus !== 'done' || loadedEvent.current) return;
+ loadedEvent.current = true;
+
+ subscribe(AnalyticsEvent.PAGE_VIEWED, () => {
+ window.PerfKit?.navigate();
+ });
+ subscribe(AnalyticsEvent.PRODUCT_VIEWED, () => {
+ window.PerfKit?.setPageType('product');
+ });
+ subscribe(AnalyticsEvent.COLLECTION_VIEWED, () => {
+ window.PerfKit?.setPageType('collection');
+ });
+ subscribe(AnalyticsEvent.SEARCH_VIEWED, () => {
+ window.PerfKit?.setPageType('search');
+ });
+ subscribe(AnalyticsEvent.CART_VIEWED, () => {
+ window.PerfKit?.setPageType('cart');
+ });
+
+ ready();
+ }, [subscribe, ready, scriptStatus]);
+ return null;
+}
diff --git a/packages/hydrogen/vitest.setup.ts b/packages/hydrogen/vitest.setup.ts
index e06e48185..86629772d 100644
--- a/packages/hydrogen/vitest.setup.ts
+++ b/packages/hydrogen/vitest.setup.ts
@@ -3,3 +3,8 @@ import matchers from '@testing-library/jest-dom/matchers';
import {expect} from 'vitest';
expect.extend(matchers);
+
+// Defining `document.currentScript` to avoid errors in tests
+Object.defineProperty(document, 'currentScript', {
+ value: document.createElement('script'),
+});