-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Vite migration, Hydrogen package updates, new sitemap generation, Kla…
…viyo analytics, code improvements (#60) Migration: - Migrates Remix's application builder from Remix compiler to Vite. See [Remix Vite documentation](https://remix.run/docs/en/main/guides/vite) Routine: - Updates `hydrogen` packages to `2024.10` and all other packages to latest - Adds additional consent settings required for hydrogen `2024.10` version - Add `"type": "module"` to `package.json` and adjust file exports or file extensions accordingly Improvement: - Utilizes Hydrogen's `sitemap` to paginate sitemaps for product and collection pages. Previously, large stores would generate a singular sitemap that would not be functional due to the large number of server side requests. Also cleans up logic for other sitemaps and product feed. New: - Adds default `KlaviyoEvents` component to `Analytics` Minor improvement: - Updates the cart graphql query to accommodate product bundles - Adds logic to automatically scroll to hash on navigation - Checks for `PACK_SECRET_TOKEN` before the Pack client initializes Minor fix: - Fixes the currency code fallback for the view cart analytics event. Previously an empty cart had a currency code of "XXX" - Corrects hook usage in `usePreviewModeCustomerFetch` from change in release v1.9.3 Minor cleanup: - Graphql cleanup and adds `codegen` dependencies - Minor misc code cleanup
- Loading branch information
1 parent
f1779f0
commit a7e7aff
Showing
72 changed files
with
23,364 additions
and
39,639 deletions.
There are no files selected for viewing
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
node_modules | ||
.vscode | ||
/.cache | ||
/build | ||
/dist | ||
/public/build | ||
/public/build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import {useEffect} from 'react'; | ||
|
||
import {useLoadScript} from '~/hooks'; | ||
|
||
import {AnalyticsEvent} from '../constants'; | ||
|
||
import { | ||
ANALYTICS_NAME, | ||
addToCartEvent, | ||
customerSubscribeEvent, | ||
viewProductEvent, | ||
} from './events'; | ||
|
||
type Data = Record<string, any>; | ||
|
||
export function KlaviyoEvents({ | ||
register, | ||
subscribe, | ||
customer, | ||
debug = false, | ||
klaviyoApiKey, | ||
}: { | ||
register: (key: string) => {ready: () => void}; | ||
subscribe: (arg0: any, arg1: any) => void; | ||
customer?: Record<string, any> | null; | ||
debug?: boolean; | ||
klaviyoApiKey: string; | ||
}) { | ||
let ready: (() => void) | undefined = undefined; | ||
if (register) { | ||
ready = register(ANALYTICS_NAME).ready; | ||
} | ||
|
||
const scriptStatus = useLoadScript( | ||
{ | ||
id: 'klaviyo-script', | ||
src: `https://static.klaviyo.com/onsite/js/klaviyo.js?company_id=${klaviyoApiKey}`, | ||
}, | ||
'body', | ||
!!klaviyoApiKey, | ||
); | ||
|
||
useEffect(() => { | ||
if (!klaviyoApiKey) { | ||
console.error( | ||
`${ANALYTICS_NAME}: ❌ error: \`klaviyoApiKey\` must be passed in.`, | ||
); | ||
} | ||
if (scriptStatus !== 'done') return; | ||
if (!ready || !subscribe) { | ||
console.error( | ||
`${ANALYTICS_NAME}: ❌ error: \`register\` and \`subscribe\` must be passed in from Hydrogen's useAnalytics hook.`, | ||
); | ||
return; | ||
} | ||
/* register analytics events only until script is ready */ | ||
subscribe(AnalyticsEvent.PRODUCT_VIEWED, (data: Data) => { | ||
viewProductEvent({...data, customer, debug}); | ||
}); | ||
subscribe(AnalyticsEvent.PRODUCT_ADD_TO_CART, (data: Data) => { | ||
addToCartEvent({...data, customer, debug}); | ||
}); | ||
subscribe(AnalyticsEvent.CUSTOMER_SUBSCRIBED, (data: Data) => { | ||
customerSubscribeEvent({...data, debug}); | ||
}); | ||
ready(); | ||
if (debug) console.log(`${ANALYTICS_NAME}: 🔄 subscriptions are ready.`); | ||
}, [customer?.id, debug, scriptStatus]); | ||
|
||
return null; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
import {AnalyticsEvent} from '../constants'; | ||
|
||
import { | ||
pathWithoutLocalePrefix, | ||
mapCartLine, | ||
mapProductPageVariant, | ||
} from './utils'; | ||
|
||
export const ANALYTICS_NAME = 'KlaviyoEvents'; | ||
|
||
const logSubscription = ({ | ||
data, | ||
analyticsEvent, | ||
}: { | ||
data: Record<string, any>; | ||
analyticsEvent: string; | ||
}) => { | ||
console.log( | ||
`${ANALYTICS_NAME}: 📥 subscribed to analytics for \`${analyticsEvent}\`:`, | ||
data, | ||
); | ||
}; | ||
|
||
const logError = ({ | ||
analyticsEvent, | ||
message = 'Unknown error', | ||
}: { | ||
analyticsEvent: string; | ||
message?: string | unknown; | ||
}) => { | ||
console.error( | ||
`${ANALYTICS_NAME}: ❌ error from \`${analyticsEvent}\`: ${message}`, | ||
); | ||
}; | ||
|
||
export const identifyCustomer = async ({ | ||
email, | ||
debug, | ||
}: { | ||
email: string; | ||
debug?: boolean; | ||
}) => { | ||
if (!window.klaviyo) return; | ||
await window.klaviyo.identify({email}); | ||
if (debug) | ||
console.log( | ||
`${ANALYTICS_NAME}: 🚀 event emitted for \`identify customer\`:`, | ||
{email}, | ||
); | ||
}; | ||
|
||
export const emitEvent = async ({ | ||
email, | ||
event, | ||
properties, | ||
debug, | ||
}: { | ||
email: string; | ||
event: string; | ||
properties: Record<string, any> | null; | ||
debug?: boolean; | ||
}) => { | ||
if (!window.klaviyo) return; | ||
const klaviyoIdentified = await window.klaviyo.isIdentified(); | ||
if (klaviyoIdentified) { | ||
window.klaviyo.push(['track', event, properties]); | ||
} else if (email) { | ||
await window.klaviyo.identify({email}); | ||
window.klaviyo.push(['track', event, properties]); | ||
} | ||
if (debug) | ||
console.log(`${ANALYTICS_NAME}: 🚀 event emitted for \`${event}\`:`, { | ||
event, | ||
email, | ||
properties, | ||
}); | ||
}; | ||
|
||
const viewProductEvent = ({ | ||
debug, | ||
...data | ||
}: Record<string, any> & {debug?: boolean}) => { | ||
const analyticsEvent = AnalyticsEvent.PRODUCT_VIEWED; | ||
try { | ||
if (debug) logSubscription({data, analyticsEvent}); | ||
|
||
const {customer} = data; | ||
const {selectedVariant} = data.customData; | ||
const previousPath = sessionStorage.getItem('PREVIOUS_PATH'); | ||
const list = previousPath?.startsWith('/collections') ? previousPath : ''; | ||
emitEvent({ | ||
email: customer?.email, | ||
event: 'Viewed Product', | ||
properties: mapProductPageVariant(list)(selectedVariant), | ||
debug, | ||
}); | ||
} catch (error) { | ||
logError({ | ||
analyticsEvent, | ||
message: error instanceof Error ? error.message : error, | ||
}); | ||
} | ||
}; | ||
|
||
const addToCartEvent = ({ | ||
debug, | ||
...data | ||
}: Record<string, any> & {debug?: boolean}) => { | ||
const analyticsEvent = AnalyticsEvent.PRODUCT_ADD_TO_CART; | ||
try { | ||
if (debug) logSubscription({data, analyticsEvent}); | ||
|
||
const {currentLine, customer} = data; | ||
if (!currentLine) | ||
throw new Error('`cart` and/or `currentLine` parameters are missing.'); | ||
|
||
const previousPath = sessionStorage.getItem('PREVIOUS_PATH'); | ||
const windowPathname = pathWithoutLocalePrefix(window.location.pathname); | ||
const list = | ||
(windowPathname.startsWith('/collections') && windowPathname) || | ||
(previousPath?.startsWith('/collections') && previousPath) || | ||
''; | ||
const productProps = mapCartLine(list)(currentLine); | ||
emitEvent({ | ||
email: customer?.email, | ||
event: 'Added to Cart', | ||
properties: productProps, | ||
debug, | ||
}); | ||
} catch (error) { | ||
logError({ | ||
analyticsEvent, | ||
message: error instanceof Error ? error.message : error, | ||
}); | ||
} | ||
}; | ||
|
||
const customerSubscribeEvent = ({ | ||
debug, | ||
...data | ||
}: Record<string, any> & {debug?: boolean}) => { | ||
const analyticsEvent = AnalyticsEvent.CUSTOMER_SUBSCRIBED; | ||
try { | ||
if (debug) logSubscription({data, analyticsEvent}); | ||
|
||
const {email} = data; | ||
if (!email) throw new Error('`email` parameter is missing.'); | ||
|
||
identifyCustomer({email, debug}); | ||
} catch (error) { | ||
logError({ | ||
analyticsEvent, | ||
message: error instanceof Error ? error.message : error, | ||
}); | ||
} | ||
}; | ||
|
||
export {addToCartEvent, customerSubscribeEvent, viewProductEvent}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export {KlaviyoEvents} from './KlaviyoEvents'; |
Oops, something went wrong.