diff --git a/components/Webviews/LinkToOverview/index.tsx b/components/Webviews/LinkToOverview/index.tsx index 4cb0536ed..8e0a57820 100644 --- a/components/Webviews/LinkToOverview/index.tsx +++ b/components/Webviews/LinkToOverview/index.tsx @@ -5,13 +5,17 @@ import { overview } from "@/constants/routes/webviews" import Link from "@/components/TempDesignSystem/Link" import { getIntl } from "@/i18n" import { getLang } from "@/i18n/serverContext" +import { webviewSearchParams } from "@/utils/webviews" import styles from "./linkToOverview.module.css" export default async function LinkToOverview() { const { formatMessage } = await getIntl() + const searchParams = webviewSearchParams() + + const overviewHref = `${overview[getLang()]}?${searchParams.toString()}` return ( - + {" "} {formatMessage({ id: "Go back to overview" })} diff --git a/middlewares/webView.ts b/middlewares/webView.ts index 0536e87c0..fa54e5892 100644 --- a/middlewares/webView.ts +++ b/middlewares/webView.ts @@ -21,6 +21,29 @@ export const middleware: NextMiddleware = async (request) => { const { nextUrl } = request const lang = findLang(nextUrl.pathname) + const loginTypeHeader = request.headers.get("loginType") + const loginTypeSearchParam = nextUrl.searchParams.get("loginType") + + const adobeMc = nextUrl.searchParams.get("adobe_mc") + + const headers = getDefaultRequestHeaders(request) + + // LoginType is passed from the mobile app as a header and needs to be passed around with each subsequent + // request within webviews due to tracking. We set the loginType as a header and pass it along to future + // requests, and to read it from TRPC side (which is where the tracking object is created). + // The value is appended to all webview links as a search param, just like adobe_mc. + const loginType = loginTypeHeader || loginTypeSearchParam + if (loginType) { + headers.set("loginType", loginType) + } + + // adobe_mc (Experience Cloud ID) needs to be passed around as a search param, which will be read + // from the URL by the tracking SDK. Adobe_mc is passed from the mobile app as a searchParam, and + // then passed to nextjs as a header. In the RSC, the adobe_mc is appended as a searchParam on each webview link. + if (adobeMc) { + headers.set("adobe_mc", adobeMc) + } + // If user is redirected to /lang/webview/refresh/, the webview token is invalid and we remove the cookie if (refreshWebviews.includes(nextUrl.pathname)) { return NextResponse.rewrite( @@ -44,7 +67,6 @@ export const middleware: NextMiddleware = async (request) => { `Unable to resolve CMS entry for locale "${lang}": ${pathNameWithoutLang}` ) } - const headers = getDefaultRequestHeaders(request) headers.set("x-uid", uid) const webviewToken = request.cookies.get("webviewToken") diff --git a/server/context.ts b/server/context.ts index 2c4c235ee..f96e5cff5 100644 --- a/server/context.ts +++ b/server/context.ts @@ -44,6 +44,7 @@ export function createContext() { const cookie = cookies() const webviewTokenCookie = cookie.get("webviewToken") + const loginType = h.get("loginType") return createContextInner({ auth: async () => { @@ -53,7 +54,12 @@ export function createContext() { return null } - return session || ({ token: { access_token: webToken } } as Session) + return ( + session || + ({ + token: { access_token: webToken, loginType }, + } as Session) + ) }, lang: h.get("x-lang") as Lang, pathname: h.get("x-pathname")!, diff --git a/utils/tracking.ts b/utils/tracking.ts index d6bacd8a7..1f4d0f388 100644 --- a/utils/tracking.ts +++ b/utils/tracking.ts @@ -1,7 +1,7 @@ import { TrackingPosition } from "@/types/components/tracking" export function trackClick(name: string) { - if (window.adobeDataLayer) { + if (typeof window !== "undefined" && window.adobeDataLayer) { window.adobeDataLayer.push({ event: "linkClick", cta: { @@ -11,8 +11,16 @@ export function trackClick(name: string) { } } +export function trackPageViewStart() { + if (typeof window !== "undefined" && window.adobeDataLayer) { + window.adobeDataLayer.push({ + event: "pageViewStart", + }) + } +} + export function trackLoginClick(position: TrackingPosition) { - if (window.adobeDataLayer) { + if (typeof window !== "undefined" && window.adobeDataLayer) { const loginEvent = { event: "loginStart", login: { diff --git a/utils/webviews.ts b/utils/webviews.ts index e6c28b90d..735600cbb 100644 --- a/utils/webviews.ts +++ b/utils/webviews.ts @@ -1,13 +1,32 @@ +import "server-only" + +import { headers } from "next/headers" + import { Lang } from "@/constants/languages" import { webviews } from "@/constants/routes/webviews" +export function webviewSearchParams() { + const searchParams = new URLSearchParams() + const loginType = headers().get("loginType") + if (loginType) { + searchParams.set("loginType", loginType) + } + + const adobeMc = headers().get("adobe_mc") + if (adobeMc) { + searchParams.set("adobe_mc", adobeMc) + } + return searchParams +} + export function modWebviewLink(url: string, lang: Lang) { + const searchParams = webviewSearchParams() const urlWithoutLang = url.replace(`/${lang}`, "") const webviewUrl = `/${lang}/webview${urlWithoutLang}` if (webviews.includes(webviewUrl) || url.startsWith("/webview")) { - return webviewUrl + return `${webviewUrl}?${searchParams.toString()}` } else { - return url + return `${url}?${searchParams.toString()}` } }