Merged in feat/trackingsdk-client (pull request #1420)
feat: trackingsdk as client component * feat: trackingsdk as client component * Cleanup * Merge changes from feat/trackingsdk-client * revert yarn.lock * Added lcpTime and wait with tracking until we have the values Approved-by: Joakim Jäderberg
This commit is contained in:
@@ -42,9 +42,7 @@ export default async function MyPages({}: PageArgs<
|
|||||||
<p>{intl.formatMessage({ id: "No content published" })}</p>
|
<p>{intl.formatMessage({ id: "No content published" })}</p>
|
||||||
)}
|
)}
|
||||||
</main>
|
</main>
|
||||||
<Suspense fallback={null}>
|
<TrackingSDK pageData={tracking} />
|
||||||
<TrackingSDK pageData={tracking} />
|
|
||||||
</Suspense>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,9 +19,7 @@ export default async function ProfilePage({}: PageArgs<LangParams>) {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Profile />
|
<Profile />
|
||||||
<Suspense fallback={null}>
|
<TrackingSDK pageData={accountPage.tracking} />
|
||||||
<TrackingSDK pageData={accountPage.tracking} />
|
|
||||||
</Suspense>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,9 +30,7 @@ export default function HotelReservationPage({ params }: PageArgs<LangParams>) {
|
|||||||
return (
|
return (
|
||||||
<div className={styles.page}>
|
<div className={styles.page}>
|
||||||
New booking flow! Please report errors/issues in Slack.
|
New booking flow! Please report errors/issues in Slack.
|
||||||
<Suspense fallback={null}>
|
<TrackingSDK pageData={pageTrackingData} />
|
||||||
<TrackingSDK pageData={pageTrackingData} />
|
|
||||||
</Suspense>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import Header from "@/components/Header"
|
|||||||
import StorageCleaner from "@/components/HotelReservation/EnterDetails/StorageCleaner"
|
import StorageCleaner from "@/components/HotelReservation/EnterDetails/StorageCleaner"
|
||||||
import SitewideAlert from "@/components/SitewideAlert"
|
import SitewideAlert from "@/components/SitewideAlert"
|
||||||
import { ToastHandler } from "@/components/TempDesignSystem/Toasts"
|
import { ToastHandler } from "@/components/TempDesignSystem/Toasts"
|
||||||
import { preloadUserTracking } from "@/components/TrackingSDK"
|
|
||||||
import AdobeSDKScript from "@/components/TrackingSDK/AdobeSDKScript"
|
import AdobeSDKScript from "@/components/TrackingSDK/AdobeSDKScript"
|
||||||
import GTMScript from "@/components/TrackingSDK/GTMScript"
|
import GTMScript from "@/components/TrackingSDK/GTMScript"
|
||||||
import RouterTracking from "@/components/TrackingSDK/RouterTracking"
|
import RouterTracking from "@/components/TrackingSDK/RouterTracking"
|
||||||
@@ -31,7 +30,6 @@ export default async function RootLayout({
|
|||||||
bookingwidget: React.ReactNode
|
bookingwidget: React.ReactNode
|
||||||
}
|
}
|
||||||
>) {
|
>) {
|
||||||
preloadUserTracking()
|
|
||||||
const { defaultLocale, locale, messages } = await getIntl()
|
const { defaultLocale, locale, messages } = await getIntl()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import TokenRefresher from "@/components/Auth/TokenRefresher"
|
|||||||
import CookieBotConsent from "@/components/CookieBot"
|
import CookieBotConsent from "@/components/CookieBot"
|
||||||
import StorageCleaner from "@/components/HotelReservation/EnterDetails/StorageCleaner"
|
import StorageCleaner from "@/components/HotelReservation/EnterDetails/StorageCleaner"
|
||||||
import { ToastHandler } from "@/components/TempDesignSystem/Toasts"
|
import { ToastHandler } from "@/components/TempDesignSystem/Toasts"
|
||||||
import { preloadUserTracking } from "@/components/TrackingSDK"
|
|
||||||
import AdobeSDKScript from "@/components/TrackingSDK/AdobeSDKScript"
|
import AdobeSDKScript from "@/components/TrackingSDK/AdobeSDKScript"
|
||||||
import GTMScript from "@/components/TrackingSDK/GTMScript"
|
import GTMScript from "@/components/TrackingSDK/GTMScript"
|
||||||
import RouterTracking from "@/components/TrackingSDK/RouterTracking"
|
import RouterTracking from "@/components/TrackingSDK/RouterTracking"
|
||||||
@@ -28,7 +27,6 @@ export default async function RootLayout({
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
preloadUserTracking()
|
|
||||||
const { defaultLocale, locale, messages } = await getIntl()
|
const { defaultLocale, locale, messages } = await getIntl()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -90,9 +90,7 @@ export default async function DestinationCityPage({
|
|||||||
/>
|
/>
|
||||||
</HotelDataContainer>
|
</HotelDataContainer>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
<Suspense fallback={null}>
|
<TrackingSDK pageData={tracking} />
|
||||||
<TrackingSDK pageData={tracking} />
|
|
||||||
</Suspense>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,9 +76,7 @@ export default async function DestinationCountryPage() {
|
|||||||
</aside>
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
<CountryMap country={destination_settings.country} />
|
<CountryMap country={destination_settings.country} />
|
||||||
<Suspense fallback={null}>
|
<TrackingSDK pageData={tracking} />
|
||||||
<TrackingSDK pageData={tracking} />
|
|
||||||
</Suspense>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,9 +40,7 @@ export default async function DestinationOverviewPage() {
|
|||||||
<HotelsSection destinations={destinationsData} />
|
<HotelsSection destinations={destinationsData} />
|
||||||
</aside>
|
</aside>
|
||||||
)}
|
)}
|
||||||
<Suspense fallback={null}>
|
<TrackingSDK pageData={tracking} />
|
||||||
<TrackingSDK pageData={tracking} />
|
|
||||||
</Suspense>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,9 +50,7 @@ export default async function LoyaltyPage() {
|
|||||||
) : null}
|
) : null}
|
||||||
</MaxWidth>
|
</MaxWidth>
|
||||||
</section>
|
</section>
|
||||||
<Suspense fallback={null}>
|
<TrackingSDK pageData={tracking} />
|
||||||
<TrackingSDK pageData={tracking} />
|
|
||||||
</Suspense>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,9 +59,7 @@ export default async function StartPage() {
|
|||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</main>
|
</main>
|
||||||
<Suspense fallback={null}>
|
<TrackingSDK pageData={content.tracking} />
|
||||||
<TrackingSDK pageData={content.tracking} />
|
|
||||||
</Suspense>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,9 +78,7 @@ export default function StaticPage({
|
|||||||
) : null}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<Suspense fallback={null}>
|
<TrackingSDK pageData={tracking} />
|
||||||
<TrackingSDK pageData={tracking} />
|
|
||||||
</Suspense>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ export default function ReceiptRoom({
|
|||||||
</div>
|
</div>
|
||||||
<div className={styles.entry}>
|
<div className={styles.entry}>
|
||||||
<Body>{intl.formatMessage({ id: "Breakfast buffet" })}</Body>
|
<Body>{intl.formatMessage({ id: "Breakfast buffet" })}</Body>
|
||||||
{booking.rateDefinition.breakfastIncluded ?? breakfastPkgIncluded ? (
|
{(booking.rateDefinition.breakfastIncluded ?? breakfastPkgIncluded) ? (
|
||||||
<Body color="red">{intl.formatMessage({ id: "Included" })}</Body>
|
<Body color="red">{intl.formatMessage({ id: "Included" })}</Body>
|
||||||
) : null}
|
) : null}
|
||||||
{breakfastPkgSelected ? (
|
{breakfastPkgSelected ? (
|
||||||
|
|||||||
@@ -53,9 +53,9 @@
|
|||||||
var(--Spacing-x2);
|
var(--Spacing-x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.img {
|
.img {
|
||||||
min-width: 306px;
|
min-width: 306px;
|
||||||
}
|
}
|
||||||
.roomDetails {
|
.roomDetails {
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,13 +159,11 @@ export default async function BookingConfirmation({
|
|||||||
</SidePanel>
|
</SidePanel>
|
||||||
</aside>
|
</aside>
|
||||||
</Confirmation>
|
</Confirmation>
|
||||||
<Suspense fallback={null}>
|
<TrackingSDK
|
||||||
<TrackingSDK
|
pageData={initialPageTrackingData}
|
||||||
pageData={initialPageTrackingData}
|
hotelInfo={initialHotelsTrackingData}
|
||||||
hotelInfo={initialHotelsTrackingData}
|
paymentInfo={paymentInfo}
|
||||||
paymentInfo={paymentInfo}
|
/>
|
||||||
/>
|
|
||||||
</Suspense>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,12 +155,7 @@ export async function SelectHotelMapContainer({
|
|||||||
cityCoordinates={cityCoordinates}
|
cityCoordinates={cityCoordinates}
|
||||||
bookingCode={bookingCode ?? ""}
|
bookingCode={bookingCode ?? ""}
|
||||||
/>
|
/>
|
||||||
<Suspense fallback={null}>
|
<TrackingSDK pageData={pageTrackingData} hotelInfo={hotelsTrackingData} />
|
||||||
<TrackingSDK
|
|
||||||
pageData={pageTrackingData}
|
|
||||||
hotelInfo={hotelsTrackingData}
|
|
||||||
/>
|
|
||||||
</Suspense>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,44 +49,65 @@ export default function RouterTransition({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!hasRun && !hasRunInitial.current) {
|
if (!hasRun && !hasRunInitial.current) {
|
||||||
const handleLoad = () => {
|
|
||||||
const perfObserver = new PerformanceObserver((observedEntries) => {
|
|
||||||
const entry = observedEntries.getEntriesByType("navigation")[0]
|
|
||||||
|
|
||||||
if (entry) {
|
|
||||||
const trackingData = {
|
|
||||||
...pageData,
|
|
||||||
sessionId,
|
|
||||||
pathName,
|
|
||||||
pageLoadTime: entry.duration / 1000,
|
|
||||||
}
|
|
||||||
const pageObject = createSDKPageObject(trackingData)
|
|
||||||
trackPageView({
|
|
||||||
event: "pageView",
|
|
||||||
pageInfo: pageObject,
|
|
||||||
userInfo: userData,
|
|
||||||
hotelInfo: hotelInfo,
|
|
||||||
paymentInfo,
|
|
||||||
})
|
|
||||||
perfObserver.disconnect()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
perfObserver.observe({
|
|
||||||
type: "navigation",
|
|
||||||
buffered: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
// If the page is already loaded, execute immediately
|
|
||||||
if (document.readyState === "complete") {
|
|
||||||
handleLoad()
|
|
||||||
} else {
|
|
||||||
// Otherwise wait for the load event
|
|
||||||
window.addEventListener("load", handleLoad)
|
|
||||||
return () => window.removeEventListener("load", handleLoad)
|
|
||||||
}
|
|
||||||
|
|
||||||
hasRunInitial.current = true
|
hasRunInitial.current = true
|
||||||
setHasRun()
|
setHasRun()
|
||||||
|
|
||||||
|
const getPageLoadTime = () => {
|
||||||
|
return new Promise<number>((resolve) => {
|
||||||
|
const observer = new PerformanceObserver((entries) => {
|
||||||
|
const navEntry = entries.getEntriesByType("navigation")[0]
|
||||||
|
if (navEntry) {
|
||||||
|
observer.disconnect()
|
||||||
|
resolve(navEntry.duration / 1000)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
observer.observe({ type: "navigation", buffered: true })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getLCPTime = () => {
|
||||||
|
return new Promise<number>((resolve) => {
|
||||||
|
const observer = new PerformanceObserver((entries) => {
|
||||||
|
const lastEntry = entries.getEntries().pop()
|
||||||
|
if (lastEntry) {
|
||||||
|
observer.disconnect()
|
||||||
|
resolve(lastEntry.startTime / 1000)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
observer.observe({ type: "largest-contentful-paint", buffered: true })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const trackPerformance = async () => {
|
||||||
|
const [pageLoadTime, lcpTime] = await Promise.all([
|
||||||
|
getPageLoadTime(),
|
||||||
|
getLCPTime(),
|
||||||
|
])
|
||||||
|
|
||||||
|
const trackingData = {
|
||||||
|
...pageData,
|
||||||
|
sessionId,
|
||||||
|
pathName,
|
||||||
|
pageLoadTime,
|
||||||
|
lcpTime,
|
||||||
|
}
|
||||||
|
const pageObject = createSDKPageObject(trackingData)
|
||||||
|
|
||||||
|
trackPageView({
|
||||||
|
event: "pageView",
|
||||||
|
pageInfo: pageObject,
|
||||||
|
userInfo: userData,
|
||||||
|
hotelInfo,
|
||||||
|
paymentInfo,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.readyState === "complete") {
|
||||||
|
trackPerformance()
|
||||||
|
} else {
|
||||||
|
window.addEventListener("load", trackPerformance)
|
||||||
|
return () => window.removeEventListener("load", trackPerformance)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
pathName,
|
pathName,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { getUserTracking } from "@/lib/trpc/memoizedRequests"
|
"use client"
|
||||||
|
|
||||||
import RouterTransition from "@/components/TrackingSDK/RouterTransition"
|
import RouterTransition from "@/components/TrackingSDK/RouterTransition"
|
||||||
|
import { trpc } from "@/lib/trpc/client"
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
TrackingSDKHotelInfo,
|
TrackingSDKHotelInfo,
|
||||||
@@ -8,11 +9,7 @@ import type {
|
|||||||
TrackingSDKPaymentInfo,
|
TrackingSDKPaymentInfo,
|
||||||
} from "@/types/components/tracking"
|
} from "@/types/components/tracking"
|
||||||
|
|
||||||
export const preloadUserTracking = () => {
|
export default function TrackingSDK({
|
||||||
void getUserTracking()
|
|
||||||
}
|
|
||||||
|
|
||||||
export default async function TrackingSDK({
|
|
||||||
pageData,
|
pageData,
|
||||||
hotelInfo,
|
hotelInfo,
|
||||||
paymentInfo,
|
paymentInfo,
|
||||||
@@ -21,7 +18,12 @@ export default async function TrackingSDK({
|
|||||||
hotelInfo?: TrackingSDKHotelInfo
|
hotelInfo?: TrackingSDKHotelInfo
|
||||||
paymentInfo?: TrackingSDKPaymentInfo
|
paymentInfo?: TrackingSDKPaymentInfo
|
||||||
}) {
|
}) {
|
||||||
const userTrackingData = await getUserTracking()
|
const { data: userTrackingData, isPending } =
|
||||||
|
trpc.user.userTrackingInfo.useQuery()
|
||||||
|
|
||||||
|
if (isPending || !userTrackingData) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RouterTransition
|
<RouterTransition
|
||||||
|
|||||||
@@ -33,9 +33,7 @@ export default async function AccountPage() {
|
|||||||
<Blocks content={accountPage.content} />
|
<Blocks content={accountPage.content} />
|
||||||
</MaxWidth>
|
</MaxWidth>
|
||||||
|
|
||||||
<Suspense fallback={null}>
|
<TrackingSDK pageData={tracking} />
|
||||||
<TrackingSDK pageData={tracking} />
|
|
||||||
</Suspense>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,9 +29,7 @@ export default async function AboutScandicFriends() {
|
|||||||
</MaxWidth>
|
</MaxWidth>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<Suspense fallback={null}>
|
<TrackingSDK pageData={tracking} />
|
||||||
<TrackingSDK pageData={tracking} />
|
|
||||||
</Suspense>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,10 +64,6 @@ export const getMembershipCards = cache(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
export const getUserTracking = cache(async function getMemoizedUserTracking() {
|
|
||||||
return serverClient().user.tracking()
|
|
||||||
})
|
|
||||||
|
|
||||||
export const getHotelsByCSFilter = cache(async function getMemoizedHotels(
|
export const getHotelsByCSFilter = cache(async function getMemoizedHotels(
|
||||||
input: GetHotelsByCSFilterInput
|
input: GetHotelsByCSFilterInput
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -357,7 +357,7 @@ export const userQueryRouter = router({
|
|||||||
const membershipLevel = getMembership(verifiedData.data.memberships)
|
const membershipLevel = getMembership(verifiedData.data.memberships)
|
||||||
return membershipLevel
|
return membershipLevel
|
||||||
}),
|
}),
|
||||||
tracking: safeProtectedProcedure.query(async function ({ ctx }) {
|
userTrackingInfo: safeProtectedProcedure.query(async function ({ ctx }) {
|
||||||
const notLoggedInUserTrackingData: TrackingSDKUserData = {
|
const notLoggedInUserTrackingData: TrackingSDKUserData = {
|
||||||
loginStatus: "Non-logged in",
|
loginStatus: "Non-logged in",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,4 +16,4 @@ export interface ConfirmationProps extends BookingConfirmation {
|
|||||||
|
|
||||||
export interface BookingConfirmationAlertsProps {
|
export interface BookingConfirmationAlertsProps {
|
||||||
booking: BookingConfirmationSchema
|
booking: BookingConfirmationSchema
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ export type TrackingSDKPageData = {
|
|||||||
domain?: string
|
domain?: string
|
||||||
siteSections: string
|
siteSections: string
|
||||||
pageLoadTime?: number // Page load time in seconds
|
pageLoadTime?: number // Page load time in seconds
|
||||||
|
lcpTime?: number // Largest contentful paint time in seconds
|
||||||
sessionId?: string | null
|
sessionId?: string | null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user