Merged in fix/LOY-222-find-my-booking-urls-for-prod (pull request #1817)

Fix(LOY-222): Find my booking url handling

* fix(LOY-222): adapt findMyBooking url based on HIDE_FOR_NEXT_RELEASE

* feat(LOY-222): add current web paths for findMyBooking in multiple languages

* refactor(LOY-222): better env and new url constructions

* refactor(LOY-222): decouple env var handling from getCurrentWebUrl

* fix(LOY-222): update findMyBooking URL construction to use baseUrl

* fix(LOY-222): simplify findMyBooking URL handling for new web urls

* fix(LOY-222): Update Finnish path for hotel reservation lookup

* refactor(LOY-222): rename PUBLIC_URL to NEXT_PUBLIC_PUBLIC_URL for consistency


Approved-by: Christian Andolf
Approved-by: Linus Flood
This commit is contained in:
Chuma Mcphoy (We Ahead)
2025-04-22 07:03:23 +00:00
parent ba2198b77f
commit 27aef3982e
13 changed files with 82 additions and 20 deletions

View File

@@ -43,9 +43,9 @@ NODE_OPTIONS="--openssl-legacy-provider"
// OPENSSL_MODULES="/var/lang/lib/ossl-modules" to enable legacy encryption support.
OPENSSL_MODULES="/var/lang/lib/ossl-modules"
PUBLIC_URL="http://localhost:3000"
AUTH_URL="$PUBLIC_URL/api/web/auth"
NEXTAUTH_URL="$PUBLIC_URL/api/web/auth"
NEXT_PUBLIC_PUBLIC_URL="http://localhost:3000"
AUTH_URL="$NEXT_PUBLIC_PUBLIC_URL/api/web/auth"
NEXTAUTH_URL="$NEXT_PUBLIC_PUBLIC_URL/api/web/auth"
GOOGLE_STATIC_MAP_KEY=""
GOOGLE_STATIC_MAP_SIGNATURE_SECRET=""

View File

@@ -20,7 +20,7 @@ CYPRESS_CURITY_PASSWORD="test"
CYPRESS_BASE_URL="test"
DEPLOY_PRIME_URL="test"
NEXTAUTH_SECRET="test"
PUBLIC_URL="test"
NEXT_PUBLIC_PUBLIC_URL="test"
NEXTAUTH_URL="test"
REVALIDATE_SECRET="test"
SEAMLESS_LOGIN_DA="test"

View File

@@ -13,9 +13,10 @@ import styles from "./emptyUpcomingStays.module.css"
export default async function EmptyUpcomingStaysBlock() {
const intl = await getIntl()
const lang = getLang()
const baseUrl = env.PUBLIC_URL || "https://www.scandichotels.com"
const href = env.HIDE_FOR_NEXT_RELEASE
? getCurrentWebUrl("/", lang)
? getCurrentWebUrl({ path: "/", lang, baseUrl })
: `/${lang}`
return (

View File

@@ -13,9 +13,10 @@ import styles from "./emptyUpcomingStays.module.css"
export default async function EmptyUpcomingStaysBlock() {
const intl = await getIntl()
const lang = getLang()
const baseUrl = env.PUBLIC_URL || "https://www.scandichotels.com"
const href = env.HIDE_FOR_NEXT_RELEASE
? getCurrentWebUrl("/", lang)
? getCurrentWebUrl({ path: "/", lang, baseUrl })
: `/${lang}`
return (

View File

@@ -4,9 +4,10 @@
import { usePathname } from "next/navigation"
import { useIntl } from "react-intl"
import { findMyBooking } from "@/constants/routes/findMyBooking"
import { findMyBookingCurrentWebPath } from "@/constants/routes/findMyBooking"
import { logout } from "@/constants/routes/handleAuth"
import { myPages } from "@/constants/routes/myPages"
import { env } from "@/env/client"
import useDropdownStore from "@/stores/main-menu"
import Image from "@/components/Image"
@@ -16,6 +17,7 @@ import SkeletonShimmer from "@/components/SkeletonShimmer"
import Link from "@/components/TempDesignSystem/Link"
import useLang from "@/hooks/useLang"
import { trackClick } from "@/utils/tracking"
import { getCurrentWebUrl } from "@/utils/url"
import BookingButton from "../BookingButton"
@@ -38,6 +40,7 @@ export function MainMenu({
const intl = useIntl()
const lang = useLang()
const pathname = usePathname()
const baseUrl = env.NEXT_PUBLIC_PUBLIC_URL || "https://www.scandichotels.com"
const isThreeStaticPagesPathnames = [
"/de/sponsoring",
@@ -157,7 +160,11 @@ export function MainMenu({
<li className={styles.mobileLinkRow}>
<Link
className={styles.mobileLinkButton}
href={findMyBooking[lang]}
href={getCurrentWebUrl({
path: findMyBookingCurrentWebPath[lang],
lang,
baseUrl,
})}
>
{intl.formatMessage({
defaultMessage: "Find booking",

View File

@@ -6,13 +6,18 @@ import { useIntl } from "react-intl"
import { useMediaQuery } from "usehooks-ts"
import { customerService } from "@/constants/currentWebHrefs"
import { findMyBooking } from "@/constants/routes/findMyBooking"
import {
findMyBooking,
findMyBookingCurrentWebPath,
} from "@/constants/routes/findMyBooking"
import { env } from "@/env/client"
import useDropdownStore from "@/stores/main-menu"
import { IconName } from "@/components/Icons/iconName"
import LanguageSwitcher from "@/components/LanguageSwitcher"
import { useHandleKeyUp } from "@/hooks/useHandleKeyUp"
import useLang from "@/hooks/useLang"
import { getCurrentWebUrl } from "@/utils/url"
import HeaderLink from "../../HeaderLink"
import TopLink from "../../TopLink"
@@ -70,6 +75,15 @@ export default function MobileMenu({
defaultMessage: "Open menu",
})
const baseUrl = env.NEXT_PUBLIC_PUBLIC_URL || "https://www.scandichotels.com"
const findMyBookingUrl = env.NEXT_PUBLIC_HIDE_FOR_NEXT_RELEASE
? getCurrentWebUrl({
path: findMyBookingCurrentWebPath[lang],
lang,
baseUrl,
})
: findMyBooking[lang]
return (
<>
<button
@@ -90,7 +104,7 @@ export default function MobileMenu({
{children}
<footer className={styles.footer}>
<HeaderLink
href={findMyBooking[lang]}
href={findMyBookingUrl}
iconName={IconName.Search}
onClick={() => toggleDropdown(DropdownTypeEnum.HamburgerMenu)}
>

View File

@@ -1,4 +1,8 @@
import { findMyBooking } from "@/constants/routes/findMyBooking"
import {
findMyBooking,
findMyBookingCurrentWebPath,
} from "@/constants/routes/findMyBooking"
import { env } from "@/env/server"
import { getHeader } from "@/lib/trpc/memoizedRequests"
import { auth } from "@/auth"
@@ -9,6 +13,7 @@ import Caption from "@/components/TempDesignSystem/Text/Caption"
import { getIntl } from "@/i18n"
import { getLang } from "@/i18n/serverContext"
import { isValidSession } from "@/utils/session"
import { getCurrentWebUrl } from "@/utils/url"
import HeaderLink from "../HeaderLink"
import TopLink from "../TopLink"
@@ -28,6 +33,14 @@ export default async function TopMenu() {
}
const lang = getLang()
const baseUrl = env.PUBLIC_URL || "https://www.scandichotels.com"
const findMyBookingUrl = env.HIDE_FOR_NEXT_RELEASE
? getCurrentWebUrl({
path: findMyBookingCurrentWebPath[lang],
lang,
baseUrl,
})
: findMyBooking[lang]
return (
<div className={styles.topMenu}>
@@ -37,7 +50,7 @@ export default async function TopMenu() {
<LanguageSwitcher type="desktopHeader" />
<Caption type="regular" color="textMediumContrast" asChild>
<HeaderLink href={findMyBooking[lang]} iconName={IconName.Search}>
<HeaderLink href={findMyBookingUrl} iconName={IconName.Search}>
{intl.formatMessage({
defaultMessage: "Find booking",
})}

View File

@@ -88,7 +88,7 @@ export async function MyStay({ refId }: { refId: string }) {
const baseUrl = env.PUBLIC_URL || "https://www.scandichotels.com"
const promoUrl = env.HIDE_FOR_NEXT_RELEASE
? new URL(getCurrentWebUrl("/", lang))
? new URL(getCurrentWebUrl({ path: "/", lang, baseUrl }))
: new URL(`${baseUrl}/${lang}/`)
promoUrl.searchParams.set("hotel", hotel.operaId)

View File

@@ -12,3 +12,13 @@ export const findMyBooking = {
no: "/no/hotelreservation/get-booking",
sv: "/sv/hotelreservation/hitta-bokning",
}
/** @type {import('@/types/routes').LangRoute} */
export const findMyBookingCurrentWebPath = {
da: "/hotelreservation/hent-booking",
de: "/hotelreservation/mein-bereich",
en: "/hotelreservation/get-booking",
fi: "/varaa-hotelli/hae-varaus",
no: "/hotelreservation/get-booking",
sv: "/hotelreservation/hitta-bokning",
}

View File

@@ -13,6 +13,7 @@ export const env = createEnv({
.refine((s) => s === "true" || s === "false")
// transform to boolean
.transform((s) => s === "true"),
NEXT_PUBLIC_PUBLIC_URL: z.string().optional(),
},
emptyStringAsUndefined: true,
runtimeEnv: {
@@ -23,5 +24,6 @@ export const env = createEnv({
process.env.NEXT_PUBLIC_SENTRY_CLIENT_SAMPLERATE,
NEXT_PUBLIC_HIDE_FOR_NEXT_RELEASE:
process.env.NEXT_PUBLIC_HIDE_FOR_NEXT_RELEASE,
NEXT_PUBLIC_PUBLIC_URL: process.env.NEXT_PUBLIC_PUBLIC_URL,
},
})

View File

@@ -231,7 +231,7 @@ export const env = createEnv({
AUTH_URL: process.env.AUTH_URL,
NODE_ENV: process.env.NODE_ENV,
PRINT_QUERY: process.env.PRINT_QUERY,
PUBLIC_URL: process.env.PUBLIC_URL,
PUBLIC_URL: process.env.NEXT_PUBLIC_PUBLIC_URL,
REVALIDATE_SECRET: process.env.REVALIDATE_SECRET,
SITEMAP_SYNC_SECRET: process.env.SITEMAP_SYNC_SECRET,
SALESFORCE_PREFERENCE_BASE_URL: process.env.SALESFORCE_PREFERENCE_BASE_URL,

View File

@@ -75,7 +75,13 @@ async function updateStaysBookingUrl(
// Construct Booking URL.
const bookingUrl = env.HIDE_FOR_NEXT_RELEASE
? new URL(getCurrentWebUrl(myBookingPath[lang], lang))
? new URL(
getCurrentWebUrl({
path: myBookingPath[lang],
lang,
baseUrl,
})
)
: new URL(myStay[lang], baseUrl)
// Add search parameters.

View File

@@ -1,5 +1,4 @@
import { Lang } from "@/constants/languages"
import { env } from "@/env/server"
import type { RoomPackageCodeEnum } from "@/types/components/hotelReservation/selectRate/roomFilter"
import type {
@@ -192,12 +191,21 @@ export function getTldForLanguage(lang: Lang): string {
/**
* Constructs a URL with the correct TLD (top-level domain) based on lang, for current web.
* @param path - The path to append to the URL
* @param lang - The language to use for TLD
* @param params - Object containing path, lang, and baseUrl
* @param params.path - The path to append to the URL
* @param params.lang - The language to use for TLD
* @param params.baseUrl - The base URL to use (e.g. https://www.scandichotels.com)
* @returns The complete URL with language-specific TLD
*/
export function getCurrentWebUrl(path: string, lang: Lang): string {
const baseUrl = env.PUBLIC_URL || "https://www.scandichotels.com" // Fallback for ephemeral environments (e.g. deploy previews).
export function getCurrentWebUrl({
path,
lang,
baseUrl = "https://www.scandichotels.com", // Fallback for ephemeral environments (e.g. deploy previews).
}: {
path: string
lang: Lang
baseUrl?: string
}): string {
const tld = getTldForLanguage(lang)
const url = new URL(path, baseUrl)