Merged in feat/SW-1472-destination-tracking (pull request #1474)

Feat/SW-1472 destination tracking

* feat(SW-1472): Added default tracking for destination overview page

* feat(SW-1472): Added default tracking for destination country/city page

* feat(SW-1472): moved tracking functions to different files for better overview

* feat(SW-1472): added destination page tracking


Approved-by: Fredrik Thorsson
Approved-by: Matilda Landström
This commit is contained in:
Erik Tiekstra
2025-03-06 10:15:33 +00:00
parent 47785aa07a
commit 230b56b3bd
25 changed files with 502 additions and 373 deletions

View File

@@ -19,10 +19,6 @@ import {
import { systemSchema } from "../schemas/system"
import type { ImageVaultAsset } from "@/types/components/imageVault"
import {
TrackingChannelEnum,
type TrackingSDKPageData,
} from "@/types/components/tracking"
import { Country } from "@/types/enums/country"
import { DestinationCountryPageEnum } from "@/types/enums/destinationCountryPage"
@@ -47,82 +43,60 @@ export const blocksSchema = z.discriminatedUnion("__typename", [
destinationCountryPageContent,
])
export const destinationCountryPageSchema = z
.object({
destination_country_page: z.object({
title: z.string(),
destination_settings: z.object({
country: z.nativeEnum(Country),
location: mapLocationSchema,
}),
export const destinationCountryPageSchema = z.object({
destination_country_page: z.object({
title: z.string(),
destination_settings: z.object({
country: z.nativeEnum(Country),
location: mapLocationSchema,
}),
heading: z.string(),
preamble: z.string(),
experiences: z
.object({
destination_experiences: z.array(z.string()),
})
.transform(({ destination_experiences }) => destination_experiences),
images: z
.array(z.object({ image: tempImageVaultAssetSchema }))
.transform((images) =>
images
.map((image) => image.image)
.filter((image): image is ImageVaultAsset => !!image)
),
has_sidepeek: z.boolean().default(false),
sidepeek_button_text: z.string().default(""),
sidepeek_content: z.object({
heading: z.string(),
preamble: z.string(),
experiences: z
.object({
destination_experiences: z.array(z.string()),
})
.transform(({ destination_experiences }) => destination_experiences),
images: z
.array(z.object({ image: tempImageVaultAssetSchema }))
.transform((images) =>
images
.map((image) => image.image)
.filter((image): image is ImageVaultAsset => !!image)
),
has_sidepeek: z.boolean().default(false),
sidepeek_button_text: z.string().default(""),
sidepeek_content: z.object({
heading: z.string(),
content: z.object({
json: z.any(),
embedded_itemsConnection: z.object({
edges: z.array(
z.object({
node: linkUnionSchema.transform((data) => {
const link = transformPageLink(data)
if (link) {
return link
}
return data
}),
})
),
}),
content: z.object({
json: z.any(),
embedded_itemsConnection: z.object({
edges: z.array(
z.object({
node: linkUnionSchema.transform((data) => {
const link = transformPageLink(data)
if (link) {
return link
}
return data
}),
})
),
}),
}),
blocks: discriminatedUnionArray(blocksSchema.options).nullable(),
system: systemSchema.merge(
z.object({
created_at: z.string(),
updated_at: z.string(),
})
),
}),
trackingProps: z.object({
url: z.string(),
}),
})
.transform((data) => {
const countryPageData = data.destination_country_page
const system = countryPageData.system
const trackingUrl = data.trackingProps.url
const tracking: TrackingSDKPageData = {
pageId: system.uid,
domainLanguage: system.locale,
publishDate: system.updated_at,
createDate: system.created_at,
channel: TrackingChannelEnum["destination-page"],
pageType: "staticcontentpage",
pageName: trackingUrl,
siteSections: trackingUrl,
siteVersion: "new-web",
}
return {
destinationCountryPage: countryPageData,
tracking,
}
})
blocks: discriminatedUnionArray(blocksSchema.options).nullable(),
system: systemSchema.merge(
z.object({
created_at: z.string(),
updated_at: z.string(),
})
),
}),
trackingProps: z.object({
url: z.string(),
}),
})
export const countryPageUrlsSchema = z
.object({

View File

@@ -6,10 +6,9 @@ import { request } from "@/lib/graphql/request"
import { notFound } from "@/server/errors/trpc"
import {
contentStackBaseWithServiceProcedure,
contentStackUidWithServiceProcedure,
contentstackExtendedProcedureUID,
router,
} from "@/server/trpc"
import { toApiLang } from "@/server/utils"
import { generateTag } from "@/utils/generateTag"
@@ -28,6 +27,10 @@ import {
} from "./telemetry"
import { generatePageTags, getCityPages } from "./utils"
import {
TrackingChannelEnum,
type TrackingSDKPageData,
} from "@/types/components/tracking"
import { ApiCountry } from "@/types/enums/country"
import type {
GetDestinationCountryPageData,
@@ -35,9 +38,8 @@ import type {
} from "@/types/trpc/routers/contentstack/destinationCountryPage"
export const destinationCountryPageQueryRouter = router({
get: contentStackUidWithServiceProcedure.query(async ({ ctx }) => {
const { lang, uid, serviceToken } = ctx
const apiLang = toApiLang(lang)
get: contentstackExtendedProcedureUID.query(async ({ ctx }) => {
const { lang, uid } = ctx
getDestinationCountryPageRefsCounter.add(1, { lang, uid })
console.info(
@@ -156,8 +158,9 @@ export const destinationCountryPageQueryRouter = router({
)
return null
}
const country =
validatedResponse.data.destinationCountryPage.destination_settings.country
const destinationCountryPage =
validatedResponse.data.destination_country_page
const country = destinationCountryPage.destination_settings.country
getDestinationCountryPageSuccessCounter.add(1, { lang, uid: `${uid}` })
console.info(
@@ -167,9 +170,25 @@ export const destinationCountryPageQueryRouter = router({
})
)
const system = destinationCountryPage.system
const pageName = `hotels|${country}`
const tracking: TrackingSDKPageData = {
pageId: system.uid,
domainLanguage: system.locale,
publishDate: system.updated_at,
createDate: system.created_at,
channel: TrackingChannelEnum.hotels,
pageType: "countrypage",
pageName,
siteSections: pageName,
siteVersion: "new-web",
}
return {
...validatedResponse.data,
destinationCountryPage,
translatedCountry: ApiCountry[lang][country],
tracking,
}
}),
cityPages: contentStackBaseWithServiceProcedure