@getcontextual/shopify-sdk 1.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.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,49 @@
1
+ import { trackPageView, trackProductView, trackCollectionView, trackAddToCart, trackCheckoutStarted, trackCheckoutCompleted, trackSearch, identify } from "../vanilla";
2
+ import type { ShopifyProductVariant, ShopifyCartLine, ShopifyCheckout, ShopifyCollection, ShopifySearchResult } from "../types";
3
+ import type { HeadlessShopifyConfig } from "../tracker";
4
+ interface TrackerContextValue {
5
+ trackPageView: typeof trackPageView;
6
+ trackProductView: typeof trackProductView;
7
+ trackCollectionView: typeof trackCollectionView;
8
+ trackAddToCart: typeof trackAddToCart;
9
+ trackCheckoutStarted: typeof trackCheckoutStarted;
10
+ trackCheckoutCompleted: typeof trackCheckoutCompleted;
11
+ trackSearch: typeof trackSearch;
12
+ identify: typeof identify;
13
+ }
14
+ export declare function TrackerProvider({ config, children, }: {
15
+ config: HeadlessShopifyConfig;
16
+ children: React.ReactNode;
17
+ }): import("react/jsx-runtime").JSX.Element;
18
+ export declare function useTracker(): TrackerContextValue;
19
+ export declare function PageViewTracker({ pathname }: {
20
+ pathname: string;
21
+ }): null;
22
+ export declare function ProductTracking({ productVariant, }: {
23
+ productVariant: ShopifyProductVariant;
24
+ }): null;
25
+ export declare function CollectionTracking({ collection, }: {
26
+ collection: ShopifyCollection;
27
+ }): null;
28
+ export declare function AddToCartTracking({ cartLine }: {
29
+ cartLine: ShopifyCartLine;
30
+ }): null;
31
+ export declare function CheckoutStartedTracking({ checkout, }: {
32
+ checkout: ShopifyCheckout;
33
+ }): null;
34
+ export declare function CheckoutCompletedTracking({ checkout, }: {
35
+ checkout: ShopifyCheckout;
36
+ }): null;
37
+ export declare function SearchTracking({ search, searchResult, }: {
38
+ search: string;
39
+ searchResult: ShopifySearchResult;
40
+ }): void;
41
+ export declare function IdentifyTracking({ userProperties, }: {
42
+ userProperties: {
43
+ email?: string;
44
+ phone?: string;
45
+ firstName?: string;
46
+ lastName?: string;
47
+ };
48
+ }): null;
49
+ export {};
@@ -0,0 +1,71 @@
1
+ import type { ShopifyProductVariant, ShopifyCartLine, ShopifyCheckout, ShopifyCollection, ShopifySearchResult } from "./types";
2
+ export interface HeadlessShopifyConfig {
3
+ merchantId: string;
4
+ version?: string;
5
+ autoFlush?: boolean;
6
+ flushInterval?: number;
7
+ gtmContainerId?: string;
8
+ }
9
+ export declare class HeadlessShopifyTracker {
10
+ private tracking;
11
+ private merchantId;
12
+ private gtmManager;
13
+ private gtmContainerId?;
14
+ private autoFlushInterval?;
15
+ constructor(config: HeadlessShopifyConfig);
16
+ /**
17
+ * Track page view
18
+ */
19
+ trackPageView(url?: string): Promise<void>;
20
+ /**
21
+ * Track product view
22
+ */
23
+ trackProductView(productVariant: ShopifyProductVariant): Promise<void>;
24
+ /**
25
+ * Track collection view
26
+ */
27
+ trackCollectionView(collection: ShopifyCollection): Promise<void>;
28
+ /**
29
+ * Track add to cart
30
+ */
31
+ trackAddToCart(cartLine: ShopifyCartLine): Promise<void>;
32
+ /**
33
+ * Track cart view
34
+ */
35
+ trackCartView(cart: {
36
+ lines: ShopifyCartLine[];
37
+ }): Promise<void>;
38
+ /**
39
+ * Track checkout started
40
+ */
41
+ trackCheckoutStarted(checkout: ShopifyCheckout): Promise<void>;
42
+ /**
43
+ * Track checkout completed
44
+ */
45
+ trackCheckoutCompleted(checkout: ShopifyCheckout): Promise<void>;
46
+ /**
47
+ * Track search
48
+ */
49
+ trackSearch(query: string, results: ShopifySearchResult): Promise<void>;
50
+ /**
51
+ * Update user properties (email, phone, etc.)
52
+ */
53
+ identify(userProperties: {
54
+ email?: string;
55
+ phone?: string;
56
+ firstName?: string;
57
+ lastName?: string;
58
+ }): Promise<void>;
59
+ private track;
60
+ /**
61
+ * Manually flush events
62
+ */
63
+ flush(): Promise<void>;
64
+ private startAutoFlush;
65
+ /**
66
+ * Clean up resources (call on component unmount in React)
67
+ *
68
+ * Clears auto-flush interval to prevent memory leaks
69
+ */
70
+ destroy(): void;
71
+ }
@@ -0,0 +1,5 @@
1
+ import { BrowserEvent, Tracking } from "@contextual/browser";
2
+ export interface TrackingWithSource extends Omit<Tracking, "makeEvent"> {
3
+ makeEvent: (source: "sap" | "scp" | "ses", event: Parameters<Tracking["makeEvent"]>[0], options?: Parameters<Tracking["makeEvent"]>[1]) => Promise<BrowserEvent>;
4
+ }
5
+ export declare function createTrackingWithSourceProxy(tracking: Tracking): TrackingWithSource;
@@ -0,0 +1,12 @@
1
+ import type { PixelEventsProductViewedData, PixelEventsProductAddedToCartData, PixelEventsCheckoutCompletedData, PixelEventsCollectionViewedData, PixelEventsSearchSubmittedData } from "@shopify/web-pixels-extension";
2
+ /**
3
+ * Shopify types for headless integration
4
+ *
5
+ * Uses Shopify's web-pixels-extension types directly (same as web-pixel.ts)
6
+ * for consistency and type safety.
7
+ */
8
+ export type ShopifyProductVariant = PixelEventsProductViewedData["productVariant"];
9
+ export type ShopifyCartLine = PixelEventsProductAddedToCartData["cartLine"];
10
+ export type ShopifyCheckout = PixelEventsCheckoutCompletedData["checkout"];
11
+ export type ShopifyCollection = PixelEventsCollectionViewedData["collection"];
12
+ export type ShopifySearchResult = PixelEventsSearchSubmittedData["searchResult"];
@@ -0,0 +1,40 @@
1
+ import { HeadlessShopifyTracker } from "../tracker";
2
+ import type { HeadlessShopifyConfig } from "../tracker";
3
+ import type { ShopifyProductVariant, ShopifyCartLine, ShopifyCheckout, ShopifyCollection, ShopifySearchResult } from "../types";
4
+ interface VanillaShopifyConfig extends HeadlessShopifyConfig {
5
+ autoTrackPageView: boolean;
6
+ }
7
+ /**
8
+ * Initialize tracker (call once on page load)
9
+ *
10
+ * SSR-safe: Returns immediately on server-side
11
+ * Use in useEffect or with browser check for SSR environments
12
+ */
13
+ export declare function init(config: VanillaShopifyConfig): HeadlessShopifyTracker | null;
14
+ /**
15
+ * Get tracker instance
16
+ *
17
+ * SSR-safe: Returns null on server-side
18
+ */
19
+ export declare function getTracker(): HeadlessShopifyTracker | null;
20
+ /**
21
+ * Convenience functions
22
+ * All functions are SSR-safe: No-op on server-side
23
+ */
24
+ export declare const trackProductView: (product: ShopifyProductVariant) => void;
25
+ export declare const trackCollectionView: (collection: ShopifyCollection) => void;
26
+ export declare const trackPageView: () => void;
27
+ export declare const trackAddToCart: (cartLine: ShopifyCartLine) => void;
28
+ export declare const trackCartView: (cart: {
29
+ lines: ShopifyCartLine[];
30
+ }) => void;
31
+ export declare const trackCheckoutStarted: (checkout: ShopifyCheckout) => void;
32
+ export declare const trackCheckoutCompleted: (checkout: ShopifyCheckout) => void;
33
+ export declare const trackSearch: (query: string, results: ShopifySearchResult) => void;
34
+ export declare const identify: (userProperties: {
35
+ email?: string;
36
+ phone?: string;
37
+ firstName?: string;
38
+ lastName?: string;
39
+ }) => void;
40
+ export {};
@@ -0,0 +1,9 @@
1
+ /**
2
+ * End-to-end tests for vanilla/index.ts
3
+ *
4
+ * Tests:
5
+ * - GTM initialization and loading
6
+ * - LiveIntent initialization and loading
7
+ * - Event payloads sent to backend match expected structure
8
+ */
9
+ export {};
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "@getcontextual/shopify-sdk",
3
+ "version": "1.1.0",
4
+ "description": "Easy integration for tracking on headless Shopify sites",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "publishConfig": {
9
+ "access": "public",
10
+ "registry": "https://registry.npmjs.org/"
11
+ },
12
+ "files": [
13
+ "dist",
14
+ "README.md",
15
+ "LICENSE",
16
+ "THIRD_PARTY"
17
+ ],
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js",
22
+ "default": "./dist/index.js"
23
+ },
24
+ "./react": {
25
+ "types": "./dist/react/index.d.ts",
26
+ "import": "./dist/react/index.js",
27
+ "default": "./dist/react/index.js"
28
+ },
29
+ "./vanilla": {
30
+ "types": "./dist/vanilla/index.d.ts",
31
+ "import": "./dist/vanilla/index.js",
32
+ "default": "./dist/vanilla/index.js"
33
+ },
34
+ "./package.json": "./package.json"
35
+ },
36
+ "license": "Apache-2.0",
37
+ "peerDependencies": {
38
+ "react": ">=16.8.0"
39
+ },
40
+ "peerDependenciesMeta": {
41
+ "react": {
42
+ "optional": true
43
+ }
44
+ },
45
+ "devDependencies": {
46
+ "@rollup/plugin-commonjs": "^28.0.6",
47
+ "@rollup/plugin-node-resolve": "^16.0.1",
48
+ "@rollup/plugin-typescript": "^12.1.4",
49
+ "@shopify/web-pixels-extension": "^2.18.0",
50
+ "@testing-library/jest-dom": "^6.8.0",
51
+ "@testing-library/react": "^16.3.0",
52
+ "@types/react": "^18.0.0",
53
+ "eslint": "^9.36.0",
54
+ "nock": "^13.5.5",
55
+ "prettier": "^3.6.2",
56
+ "react": "^18.3.1",
57
+ "react-dom": "^18.3.1",
58
+ "rollup": "^4.52.2",
59
+ "rollup-plugin-filesize": "^10.0.0",
60
+ "typescript": "^5.9.2",
61
+ "vitest": "^3.2.4",
62
+ "@contextual/typescript-config": "0.0.0",
63
+ "@contextual/prettier-config": "1.0.0",
64
+ "@contextual/eslint-config": "1.0.0"
65
+ },
66
+ "scripts": {
67
+ "prettier": "prettier . --write",
68
+ "prettier:ci": "prettier . --check",
69
+ "test:unit": "vitest --run",
70
+ "test:e2e": "vitest --run ./src/**/*.e2e.test.ts",
71
+ "test:integration": "",
72
+ "lint": "eslint .",
73
+ "lint:ci": "eslint .",
74
+ "tsc": "tsc --noEmit",
75
+ "clean": "rm -rf dist",
76
+ "prebuild": "pnpm run --filter=@contextual/browser build && pnpm clean",
77
+ "build": "rollup -c"
78
+ }
79
+ }