Tracking WIP
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { PropsWithChildren, useEffect } from "react"
|
import { PropsWithChildren } from "react"
|
||||||
|
|
||||||
import { login } from "@/constants/routes/handleAuth"
|
import { login } from "@/constants/routes/handleAuth"
|
||||||
|
|
||||||
@@ -31,17 +31,6 @@ export default function LoginButton({
|
|||||||
? `${login[lang]}?redirectTo=${encodeURIComponent(pathName)}`
|
? `${login[lang]}?redirectTo=${encodeURIComponent(pathName)}`
|
||||||
: login[lang]
|
: login[lang]
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
document
|
|
||||||
.getElementById(trackingId)
|
|
||||||
?.addEventListener("click", () => trackLoginClick(position))
|
|
||||||
return () => {
|
|
||||||
document
|
|
||||||
.getElementById(trackingId)
|
|
||||||
?.removeEventListener("click", () => trackLoginClick(position))
|
|
||||||
}
|
|
||||||
}, [position, trackingId])
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
className={className}
|
className={className}
|
||||||
@@ -49,6 +38,7 @@ export default function LoginButton({
|
|||||||
color={color}
|
color={color}
|
||||||
href={href}
|
href={href}
|
||||||
prefetch={false}
|
prefetch={false}
|
||||||
|
onClick={() => trackLoginClick(position)}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { usePathname, useRouter } from "next/navigation"
|
|||||||
import { startTransition, useCallback } from "react"
|
import { startTransition, useCallback } from "react"
|
||||||
|
|
||||||
import useRouterTransitionStore from "@/stores/router-transition"
|
import useRouterTransitionStore from "@/stores/router-transition"
|
||||||
|
import useTrackingStore from "@/stores/tracking"
|
||||||
|
|
||||||
import { trackClick, trackPageViewStart } from "@/utils/tracking"
|
import { trackClick, trackPageViewStart } from "@/utils/tracking"
|
||||||
|
|
||||||
@@ -27,6 +28,7 @@ export default function Link({
|
|||||||
...props
|
...props
|
||||||
}: LinkProps) {
|
}: LinkProps) {
|
||||||
const currentPageSlug = usePathname()
|
const currentPageSlug = usePathname()
|
||||||
|
const { setInitialPageLoadTime } = useTrackingStore()
|
||||||
let isActive = active || currentPageSlug === href
|
let isActive = active || currentPageSlug === href
|
||||||
|
|
||||||
if (partialMatch && !isActive) {
|
if (partialMatch && !isActive) {
|
||||||
@@ -72,6 +74,7 @@ export default function Link({
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
setInitialPageLoadTime(Date.now())
|
||||||
trackPageViewStart()
|
trackPageViewStart()
|
||||||
startTransition(() => {
|
startTransition(() => {
|
||||||
startRouterTransition()
|
startRouterTransition()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { usePathname } from "next/navigation"
|
import { usePathname } from "next/navigation"
|
||||||
import { useCallback, useEffect } from "react"
|
import { useCallback, useEffect, useRef } from "react"
|
||||||
|
|
||||||
import { webviews } from "@/constants/routes/webviews"
|
import { webviews } from "@/constants/routes/webviews"
|
||||||
import useTrackingStore from "@/stores/tracking"
|
import useTrackingStore from "@/stores/tracking"
|
||||||
@@ -10,11 +10,15 @@ import { createSDKPageObject } from "@/utils/tracking"
|
|||||||
|
|
||||||
import { TrackingSDKProps } from "@/types/components/tracking"
|
import { TrackingSDKProps } from "@/types/components/tracking"
|
||||||
|
|
||||||
export default function TrackingSDK({ pageData, userData }: TrackingSDKProps) {
|
export default function TrackingSDK({
|
||||||
|
pageData,
|
||||||
|
userData,
|
||||||
|
hotelInfo,
|
||||||
|
}: TrackingSDKProps) {
|
||||||
const pathName = usePathname()
|
const pathName = usePathname()
|
||||||
const isWebview = webviews.includes(pathName)
|
const isWebview = webviews.includes(pathName)
|
||||||
const { hasRun, setHasRun } = useTrackingStore()
|
const { hasRun, setHasRun, getPageLoadTime } = useTrackingStore()
|
||||||
|
const hasRunLocal = useRef<boolean>(false)
|
||||||
const CookiebotCallbackOnAccept = useCallback(() => {
|
const CookiebotCallbackOnAccept = useCallback(() => {
|
||||||
const cookie = window._satellite.cookie.get("CookieConsent")
|
const cookie = window._satellite.cookie.get("CookieConsent")
|
||||||
|
|
||||||
@@ -40,31 +44,36 @@ export default function TrackingSDK({ pageData, userData }: TrackingSDKProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!hasRun) {
|
if (!hasRun && !hasRunLocal.current) {
|
||||||
const perfObserver = new PerformanceObserver((observedEntries) => {
|
hasRunLocal.current = true
|
||||||
const entry = observedEntries.getEntriesByType("navigation")[0]
|
|
||||||
|
|
||||||
if (entry && window.adobeDataLayer) {
|
|
||||||
const trackingData = { ...pageData, pathName }
|
|
||||||
const pageObject = createSDKPageObject(trackingData)
|
|
||||||
|
|
||||||
window.adobeDataLayer.push({
|
|
||||||
event: "pageView",
|
|
||||||
pageInfo: pageObject,
|
|
||||||
userInfo: userData,
|
|
||||||
})
|
|
||||||
perfObserver.disconnect()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
perfObserver.observe({
|
|
||||||
type: "navigation",
|
|
||||||
buffered: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
setHasRun()
|
setHasRun()
|
||||||
|
|
||||||
|
if (window.adobeDataLayer) {
|
||||||
|
const trackingData = {
|
||||||
|
...pageData,
|
||||||
|
pathName,
|
||||||
|
pageLoadTime: getPageLoadTime(),
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageObject = createSDKPageObject(trackingData)
|
||||||
|
console.log("TRACKING: Tracking pageView", pageObject, userData)
|
||||||
|
window.adobeDataLayer.push({
|
||||||
|
event: "pageView",
|
||||||
|
pageInfo: pageObject,
|
||||||
|
userInfo: userData,
|
||||||
|
hotelInfo: hotelInfo,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [pathName, pageData, userData, hasRun, setHasRun])
|
}, [
|
||||||
|
pathName,
|
||||||
|
pageData,
|
||||||
|
userData,
|
||||||
|
hasRun,
|
||||||
|
setHasRun,
|
||||||
|
hotelInfo,
|
||||||
|
getPageLoadTime,
|
||||||
|
])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// handle consent
|
// handle consent
|
||||||
|
|||||||
@@ -4,8 +4,9 @@ import { usePathname } from "next/navigation"
|
|||||||
import { startTransition, useEffect, useOptimistic, useState } from "react"
|
import { startTransition, useEffect, useOptimistic, useState } from "react"
|
||||||
|
|
||||||
import useRouterTransitionStore from "@/stores/router-transition"
|
import useRouterTransitionStore from "@/stores/router-transition"
|
||||||
|
import useTrackingStore from "@/stores/tracking"
|
||||||
|
|
||||||
import { createSDKPageObject } from "@/utils/tracking"
|
import { createSDKPageObject, trackPageViewStart } from "@/utils/tracking"
|
||||||
|
|
||||||
import { TrackingSDKProps } from "@/types/components/tracking"
|
import { TrackingSDKProps } from "@/types/components/tracking"
|
||||||
|
|
||||||
@@ -20,15 +21,28 @@ type TransitionStatus = keyof typeof TransitionStatusEnum
|
|||||||
export default function RouterTransition({
|
export default function RouterTransition({
|
||||||
pageData,
|
pageData,
|
||||||
userData,
|
userData,
|
||||||
|
hotelInfo,
|
||||||
}: TrackingSDKProps) {
|
}: TrackingSDKProps) {
|
||||||
const [loading, setLoading] = useOptimistic(false)
|
const [loading, setLoading] = useOptimistic(false)
|
||||||
const [status, setStatus] = useState<TransitionStatus>(
|
const [status, setStatus] = useState<TransitionStatus>(
|
||||||
TransitionStatusEnum.NotRun
|
TransitionStatusEnum.NotRun
|
||||||
)
|
)
|
||||||
|
const { getPageLoadTime } = useTrackingStore()
|
||||||
|
|
||||||
const pathName = usePathname()
|
const pathName = usePathname()
|
||||||
const { isTransitioning, stopRouterTransition } = useRouterTransitionStore()
|
const { isTransitioning, stopRouterTransition } = useRouterTransitionStore()
|
||||||
|
|
||||||
|
// useEffect(() => {
|
||||||
|
// const handleStart = () => {
|
||||||
|
// trackPageViewStart()
|
||||||
|
// setInitialPageLoadTime(Date.now())
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return () => {
|
||||||
|
// handleStart()
|
||||||
|
// }
|
||||||
|
// }, [pathName])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isTransitioning && status === TransitionStatusEnum.NotRun) {
|
if (isTransitioning && status === TransitionStatusEnum.NotRun) {
|
||||||
startTransition(() => {
|
startTransition(() => {
|
||||||
@@ -48,13 +62,21 @@ export default function RouterTransition({
|
|||||||
status === TransitionStatusEnum.Done
|
status === TransitionStatusEnum.Done
|
||||||
) {
|
) {
|
||||||
if (window.adobeDataLayer) {
|
if (window.adobeDataLayer) {
|
||||||
const trackingData = { ...pageData, pathName }
|
const trackingData = {
|
||||||
|
...pageData,
|
||||||
|
pathName,
|
||||||
|
pageLoadTime: getPageLoadTime(),
|
||||||
|
}
|
||||||
const pageObject = createSDKPageObject(trackingData)
|
const pageObject = createSDKPageObject(trackingData)
|
||||||
|
console.log(
|
||||||
|
"TRACKING: Tracking RouterTransition pageViewEnd",
|
||||||
|
pageObject
|
||||||
|
)
|
||||||
window.adobeDataLayer.push({
|
window.adobeDataLayer.push({
|
||||||
event: "pageViewEnd",
|
event: "pageViewEnd",
|
||||||
pageInfo: pageObject,
|
pageInfo: pageObject,
|
||||||
userInfo: userData,
|
userInfo: userData,
|
||||||
|
hotelInfo: hotelInfo,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,6 +89,8 @@ export default function RouterTransition({
|
|||||||
pageData,
|
pageData,
|
||||||
pathName,
|
pathName,
|
||||||
userData,
|
userData,
|
||||||
|
hotelInfo,
|
||||||
|
getPageLoadTime,
|
||||||
])
|
])
|
||||||
|
|
||||||
return null
|
return null
|
||||||
|
|||||||
@@ -4,7 +4,10 @@ import RouterTransition from "@/components/TrackingSDK/RouterTransition"
|
|||||||
|
|
||||||
import TrackingSDKClient from "./Client"
|
import TrackingSDKClient from "./Client"
|
||||||
|
|
||||||
import { TrackingSDKPageData } from "@/types/components/tracking"
|
import {
|
||||||
|
TrackingSDKHotelInfo,
|
||||||
|
TrackingSDKPageData,
|
||||||
|
} from "@/types/components/tracking"
|
||||||
|
|
||||||
export const preloadUserTracking = () => {
|
export const preloadUserTracking = () => {
|
||||||
void serverClient().user.tracking()
|
void serverClient().user.tracking()
|
||||||
@@ -12,15 +15,25 @@ export const preloadUserTracking = () => {
|
|||||||
|
|
||||||
export default async function TrackingSDK({
|
export default async function TrackingSDK({
|
||||||
pageData,
|
pageData,
|
||||||
|
hotelInfo,
|
||||||
}: {
|
}: {
|
||||||
pageData: TrackingSDKPageData
|
pageData: TrackingSDKPageData
|
||||||
|
hotelInfo?: TrackingSDKHotelInfo
|
||||||
}) {
|
}) {
|
||||||
const userTrackingData = await serverClient().user.tracking()
|
const userTrackingData = await serverClient().user.tracking()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TrackingSDKClient pageData={pageData} userData={userTrackingData} />
|
<TrackingSDKClient
|
||||||
<RouterTransition pageData={pageData} userData={userTrackingData} />
|
pageData={pageData}
|
||||||
|
userData={userTrackingData}
|
||||||
|
hotelInfo={hotelInfo}
|
||||||
|
/>
|
||||||
|
<RouterTransition
|
||||||
|
pageData={pageData}
|
||||||
|
userData={userTrackingData}
|
||||||
|
hotelInfo={hotelInfo}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ query GetAccountPage($locale: String!, $uid: String!) {
|
|||||||
created_at
|
created_at
|
||||||
updated_at
|
updated_at
|
||||||
}
|
}
|
||||||
|
page_settings {
|
||||||
|
tracking_page_name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ query GetContentPage($locale: String!, $uid: String!) {
|
|||||||
created_at
|
created_at
|
||||||
updated_at
|
updated_at
|
||||||
}
|
}
|
||||||
|
page_settings {
|
||||||
|
tracking_page_name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ query GetHotelPage($locale: String!, $uid: String!) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
page_settings {
|
||||||
|
tracking_page_name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ query GetLoyaltyPage($locale: String!, $uid: String!) {
|
|||||||
created_at
|
created_at
|
||||||
updated_at
|
updated_at
|
||||||
}
|
}
|
||||||
|
page_settings {
|
||||||
|
tracking_page_name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,9 @@ export const accountPageSchema = z.object({
|
|||||||
heading: z.string().nullable(),
|
heading: z.string().nullable(),
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
url: z.string(),
|
url: z.string(),
|
||||||
|
page_settings: z.object({
|
||||||
|
tracking_page_name: z.string().nullable(),
|
||||||
|
}),
|
||||||
system: systemSchema.merge(
|
system: systemSchema.merge(
|
||||||
z.object({
|
z.object({
|
||||||
created_at: z.string(),
|
created_at: z.string(),
|
||||||
|
|||||||
@@ -191,11 +191,16 @@ export const accountPageQueryRouter = router({
|
|||||||
|
|
||||||
const tracking: TrackingSDKPageData = {
|
const tracking: TrackingSDKPageData = {
|
||||||
pageId: validatedAccountPage.data.account_page.system.uid,
|
pageId: validatedAccountPage.data.account_page.system.uid,
|
||||||
lang: validatedAccountPage.data.account_page.system.locale as Lang,
|
domainLanguage: validatedAccountPage.data.account_page.system
|
||||||
|
.locale as Lang,
|
||||||
publishedDate: validatedAccountPage.data.account_page.system.updated_at,
|
publishedDate: validatedAccountPage.data.account_page.system.updated_at,
|
||||||
createdDate: validatedAccountPage.data.account_page.system.created_at,
|
createdDate: validatedAccountPage.data.account_page.system.created_at,
|
||||||
channel: TrackingChannelEnum["scandic-friends"],
|
channel: TrackingChannelEnum["scandic-friends"],
|
||||||
pageType: `member${parsedtitle}page`,
|
pageType: `member${parsedtitle}page`,
|
||||||
|
pageName:
|
||||||
|
validatedAccountPage.data.account_page.page_settings.tracking_page_name,
|
||||||
|
siteSections:
|
||||||
|
validatedAccountPage.data.account_page.page_settings.tracking_page_name, // Always the same as pageName for this page
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import {
|
|||||||
shortcutsRefsSchema,
|
shortcutsRefsSchema,
|
||||||
shortcutsSchema,
|
shortcutsSchema,
|
||||||
} from "../schemas/blocks/shortcuts"
|
} from "../schemas/blocks/shortcuts"
|
||||||
|
import { textColsRefsSchema, textColsSchema } from "../schemas/blocks/textCols"
|
||||||
import { tempImageVaultAssetSchema } from "../schemas/imageVault"
|
import { tempImageVaultAssetSchema } from "../schemas/imageVault"
|
||||||
import {
|
import {
|
||||||
contentRefsSchema as sidebarContentRefsSchema,
|
contentRefsSchema as sidebarContentRefsSchema,
|
||||||
@@ -31,7 +32,6 @@ import {
|
|||||||
import { systemSchema } from "../schemas/system"
|
import { systemSchema } from "../schemas/system"
|
||||||
|
|
||||||
import { ContentPageEnum } from "@/types/enums/contentPage"
|
import { ContentPageEnum } from "@/types/enums/contentPage"
|
||||||
import { textColsRefsSchema, textColsSchema } from "../schemas/blocks/textCols"
|
|
||||||
|
|
||||||
// Block schemas
|
// Block schemas
|
||||||
export const contentPageCards = z
|
export const contentPageCards = z
|
||||||
@@ -58,9 +58,11 @@ export const contentPageShortcuts = z
|
|||||||
})
|
})
|
||||||
.merge(shortcutsSchema)
|
.merge(shortcutsSchema)
|
||||||
|
|
||||||
export const contentPageTextCols = z.object({
|
export const contentPageTextCols = z
|
||||||
__typename: z.literal(ContentPageEnum.ContentStack.blocks.TextCols),
|
.object({
|
||||||
}).merge(textColsSchema)
|
__typename: z.literal(ContentPageEnum.ContentStack.blocks.TextCols),
|
||||||
|
})
|
||||||
|
.merge(textColsSchema)
|
||||||
|
|
||||||
export const blocksSchema = z.discriminatedUnion("__typename", [
|
export const blocksSchema = z.discriminatedUnion("__typename", [
|
||||||
contentPageCards,
|
contentPageCards,
|
||||||
@@ -113,6 +115,9 @@ export const contentPageSchema = z.object({
|
|||||||
updated_at: z.string(),
|
updated_at: z.string(),
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
|
page_settings: z.object({
|
||||||
|
tracking_page_name: z.string().nullable(),
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -63,11 +63,14 @@ export const contentPageQueryRouter = router({
|
|||||||
|
|
||||||
const tracking: TrackingSDKPageData = {
|
const tracking: TrackingSDKPageData = {
|
||||||
pageId: contentPage.data.content_page.system.uid,
|
pageId: contentPage.data.content_page.system.uid,
|
||||||
lang: contentPage.data.content_page.system.locale as Lang,
|
domainLanguage: contentPage.data.content_page.system.locale as Lang,
|
||||||
publishedDate: contentPage.data.content_page.system.updated_at,
|
publishedDate: contentPage.data.content_page.system.updated_at,
|
||||||
createdDate: contentPage.data.content_page.system.created_at,
|
createdDate: contentPage.data.content_page.system.created_at,
|
||||||
channel: TrackingChannelEnum["static-content-page"],
|
channel: TrackingChannelEnum["static-content-page"],
|
||||||
pageType: "staticcontentpage",
|
pageType: "staticcontentpage",
|
||||||
|
pageName: contentPage.data.content_page.page_settings.tracking_page_name,
|
||||||
|
siteSections:
|
||||||
|
contentPage.data.content_page.page_settings.tracking_page_name, // Always the same as pageName for this page
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -22,5 +22,8 @@ export const hotelPageSchema = z.object({
|
|||||||
hotel_page_id: z.string(),
|
hotel_page_id: z.string(),
|
||||||
title: z.string(),
|
title: z.string(),
|
||||||
url: z.string(),
|
url: z.string(),
|
||||||
|
page_settings: z.object({
|
||||||
|
tracking_page_name: z.string().nullable(),
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -178,6 +178,9 @@ export const loyaltyPageSchema = z.object({
|
|||||||
updated_at: z.string(),
|
updated_at: z.string(),
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
|
page_settings: z.object({
|
||||||
|
tracking_page_name: z.string().nullable(),
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
.transform((data) => {
|
.transform((data) => {
|
||||||
return {
|
return {
|
||||||
@@ -187,6 +190,7 @@ export const loyaltyPageSchema = z.object({
|
|||||||
preamble: data.preamble,
|
preamble: data.preamble,
|
||||||
sidebar: data.sidebar ? data.sidebar : [],
|
sidebar: data.sidebar ? data.sidebar : [],
|
||||||
system: data.system,
|
system: data.system,
|
||||||
|
pageSettings: data.page_settings,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -176,11 +176,13 @@ export const loyaltyPageQueryRouter = router({
|
|||||||
|
|
||||||
const loyaltyTrackingData: TrackingSDKPageData = {
|
const loyaltyTrackingData: TrackingSDKPageData = {
|
||||||
pageId: loyaltyPage.system.uid,
|
pageId: loyaltyPage.system.uid,
|
||||||
lang: loyaltyPage.system.locale as Lang,
|
domainLanguage: loyaltyPage.system.locale as Lang,
|
||||||
publishedDate: loyaltyPage.system.updated_at,
|
publishedDate: loyaltyPage.system.updated_at,
|
||||||
createdDate: loyaltyPage.system.created_at,
|
createdDate: loyaltyPage.system.created_at,
|
||||||
channel: TrackingChannelEnum["scandic-friends"],
|
channel: TrackingChannelEnum["scandic-friends"],
|
||||||
pageType: "loyaltycontentpage",
|
pageType: "loyaltycontentpage",
|
||||||
|
pageName: loyaltyPage.pageSettings.tracking_page_name,
|
||||||
|
siteSections: loyaltyPage.pageSettings.tracking_page_name, // Always the same as pageName for this page
|
||||||
}
|
}
|
||||||
getLoyaltyPageSuccessCounter.add(1, metricsVariables)
|
getLoyaltyPageSuccessCounter.add(1, metricsVariables)
|
||||||
console.info(
|
console.info(
|
||||||
|
|||||||
@@ -5,11 +5,20 @@ import { create } from "zustand"
|
|||||||
interface TrackingStoreState {
|
interface TrackingStoreState {
|
||||||
hasRun: boolean
|
hasRun: boolean
|
||||||
setHasRun: () => void
|
setHasRun: () => void
|
||||||
|
initialStartTime: number
|
||||||
|
setInitialPageLoadTime: (time: number) => void
|
||||||
|
getPageLoadTime: () => number
|
||||||
}
|
}
|
||||||
|
|
||||||
const useTrackingStore = create<TrackingStoreState>((set) => ({
|
const useTrackingStore = create<TrackingStoreState>((set, get) => ({
|
||||||
hasRun: false,
|
hasRun: false,
|
||||||
|
initialStartTime: Date.now(),
|
||||||
|
setInitialPageLoadTime: (time) => set({ initialStartTime: time }),
|
||||||
setHasRun: () => set(() => ({ hasRun: true })),
|
setHasRun: () => set(() => ({ hasRun: true })),
|
||||||
|
getPageLoadTime: () => {
|
||||||
|
const { initialStartTime } = get()
|
||||||
|
return (Date.now() - initialStartTime) / 1000
|
||||||
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
export default useTrackingStore
|
export default useTrackingStore
|
||||||
|
|||||||
@@ -13,9 +13,14 @@ export type TrackingSDKPageData = {
|
|||||||
pageId: string
|
pageId: string
|
||||||
createdDate: string
|
createdDate: string
|
||||||
publishedDate: string
|
publishedDate: string
|
||||||
lang: Lang
|
domainLanguage: Lang
|
||||||
pageType: string
|
pageType: string
|
||||||
channel: TrackingChannel
|
channel: TrackingChannel
|
||||||
|
siteVersion?: "new-web"
|
||||||
|
pageName: string | null
|
||||||
|
domain?: string
|
||||||
|
siteSections: string | null
|
||||||
|
pageLoadTime?: number // Page load time in seconds
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum LoginTypeEnum {
|
export enum LoginTypeEnum {
|
||||||
@@ -35,16 +40,59 @@ export type TrackingSDKUserData = {
|
|||||||
loginAction?: "login success"
|
loginAction?: "login success"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type TrackingSDKHotelInfo = {
|
||||||
|
hotelID?: string
|
||||||
|
arrivalData?: Date
|
||||||
|
departureDate?: Date
|
||||||
|
noAdults?: number
|
||||||
|
noChildren?: number
|
||||||
|
ageOfChildren?: string // "10", "2,5,10"
|
||||||
|
//rewardNight?: boolean
|
||||||
|
//bookingCode?: string
|
||||||
|
//bookingCodeAvailability?: boolean
|
||||||
|
leadTime?: number // Number of days from booking date until arrivalDate
|
||||||
|
noOfRoom?: number
|
||||||
|
//bonuscheque?: boolean
|
||||||
|
childBedPreference?: string
|
||||||
|
duration?: number // Number of nights to stay
|
||||||
|
availableResults?: number // Number of hotels to choose from after a city search
|
||||||
|
bookingTypeofDay?: string // Weekend or weekday
|
||||||
|
searchTerm?: string
|
||||||
|
roomPrice?: string
|
||||||
|
rateCode?: string
|
||||||
|
rateCodeCancellationRule?: string
|
||||||
|
rateCodeName?: string // Scandic Friends - full flex inkl. frukost
|
||||||
|
rateCodeType?: string // regular, promotion etc
|
||||||
|
revenueCurrencyCode?: string // SEK, DKK, NOK, EUR
|
||||||
|
roomTypeCode?: string
|
||||||
|
roomTypePosition?: number // Which position the room had in the list of available rooms
|
||||||
|
roomTypeName?: string
|
||||||
|
bedType?: string
|
||||||
|
bedTypePosition?: number // Which position the bed type had in the list of available bed types
|
||||||
|
breakfastOption?: string // "no breakfast" or "breakfast buffet"
|
||||||
|
bnr?: string // Booking number
|
||||||
|
analyticsrateCode?: string // flex, save, change
|
||||||
|
specialRoomType?: string // allergy room, pet-friendly, accesibillity room
|
||||||
|
//modifyValues?: string // <price:<value>,roomtype:value>,bed:<value,<breakfast:value>
|
||||||
|
}
|
||||||
|
|
||||||
export type TrackingSDKProps = {
|
export type TrackingSDKProps = {
|
||||||
pageData: TrackingSDKPageData
|
pageData: TrackingSDKPageData
|
||||||
userData: TrackingSDKUserData
|
userData: TrackingSDKUserData
|
||||||
|
hotelInfo?: TrackingSDKHotelInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TrackingSDKData = TrackingSDKPageData & {
|
export type TrackingSDKData = TrackingSDKPageData & {
|
||||||
pathName: string
|
pathName: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type TrackingPosition =
|
||||||
|
| "top menu"
|
||||||
|
| "hamburger menu"
|
||||||
|
| "join scandic friends sidebar"
|
||||||
|
|
||||||
// Old tracking setup types:
|
// Old tracking setup types:
|
||||||
|
// TODO: Remove this when we delete "current site"
|
||||||
export type TrackingProps = {
|
export type TrackingProps = {
|
||||||
pageData: {
|
pageData: {
|
||||||
pageId: string
|
pageId: string
|
||||||
@@ -73,8 +121,3 @@ export type SiteSectionObject = {
|
|||||||
sitesection5: string
|
sitesection5: string
|
||||||
sitesection6: string
|
sitesection6: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TrackingPosition =
|
|
||||||
| "top menu"
|
|
||||||
| "hamburger menu"
|
|
||||||
| "join scandic friends sidebar"
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { TrackingPosition, TrackingSDKData } from "@/types/components/tracking"
|
|||||||
|
|
||||||
export function trackClick(name: string) {
|
export function trackClick(name: string) {
|
||||||
if (typeof window !== "undefined" && window.adobeDataLayer) {
|
if (typeof window !== "undefined" && window.adobeDataLayer) {
|
||||||
|
console.log("TRACKING: Tracking click", name)
|
||||||
window.adobeDataLayer.push({
|
window.adobeDataLayer.push({
|
||||||
event: "linkClick",
|
event: "linkClick",
|
||||||
cta: {
|
cta: {
|
||||||
@@ -13,6 +14,7 @@ export function trackClick(name: string) {
|
|||||||
|
|
||||||
export function trackPageViewStart() {
|
export function trackPageViewStart() {
|
||||||
if (typeof window !== "undefined" && window.adobeDataLayer) {
|
if (typeof window !== "undefined" && window.adobeDataLayer) {
|
||||||
|
console.log("TRACKING: Tracking pageViewStart")
|
||||||
window.adobeDataLayer.push({
|
window.adobeDataLayer.push({
|
||||||
event: "pageViewStart",
|
event: "pageViewStart",
|
||||||
})
|
})
|
||||||
@@ -21,6 +23,7 @@ export function trackPageViewStart() {
|
|||||||
|
|
||||||
export function trackLoginClick(position: TrackingPosition) {
|
export function trackLoginClick(position: TrackingPosition) {
|
||||||
if (typeof window !== "undefined" && window.adobeDataLayer) {
|
if (typeof window !== "undefined" && window.adobeDataLayer) {
|
||||||
|
console.log("TRACKING: Tracking loginStart, position", position)
|
||||||
const loginEvent = {
|
const loginEvent = {
|
||||||
event: "loginStart",
|
event: "loginStart",
|
||||||
login: {
|
login: {
|
||||||
@@ -33,26 +36,20 @@ export function trackLoginClick(position: TrackingPosition) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createSDKPageObject(trackingData: TrackingSDKData) {
|
export function createSDKPageObject(
|
||||||
|
trackingData: TrackingSDKData
|
||||||
|
): TrackingSDKData {
|
||||||
const [lang, ...segments] = trackingData.pathName
|
const [lang, ...segments] = trackingData.pathName
|
||||||
.split("/")
|
.split("/")
|
||||||
.filter((seg: string) => seg)
|
.filter((seg: string) => seg)
|
||||||
|
|
||||||
const joinedSegments = segments.join("|")
|
const joinedSegments = segments.join("|")
|
||||||
|
|
||||||
const { host: domain } = window.location
|
return {
|
||||||
const page_obj = {
|
...trackingData,
|
||||||
pageType: trackingData.pageType,
|
domain: window.location.host,
|
||||||
pageName: joinedSegments,
|
pageName: trackingData.pageName ?? joinedSegments,
|
||||||
pageId: trackingData.pageId,
|
siteSections: trackingData.siteSections ?? joinedSegments,
|
||||||
channel: trackingData.channel,
|
domainLanguage: trackingData.domainLanguage ?? lang,
|
||||||
siteSection: joinedSegments,
|
|
||||||
domain,
|
|
||||||
siteversion: "new-web",
|
|
||||||
domainlanguage: trackingData.lang ? trackingData.lang : lang,
|
|
||||||
createDate: trackingData.createdDate,
|
|
||||||
publishDate: trackingData.publishedDate,
|
|
||||||
// sessionid: "<unique identifier of session>", // base on what?
|
|
||||||
}
|
}
|
||||||
return page_obj
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user