Merged in feature/LOY-415-sj-widget (pull request #3074)

feat(LOY-415): Add SJ widget

* feat(LOY-415): Add SJ widget
can be added as dynamic content to Content Pages

* feat(LOY-415): init SJ widget with a useEffect instead due to onLoad only being called the first time

* make sure to only initialize the SJ widget once and handle navigation


Approved-by: Erik Tiekstra
This commit is contained in:
Joakim Jäderberg
2025-11-05 13:05:15 +00:00
parent 6e91d538c2
commit 645a99a844
4 changed files with 59 additions and 0 deletions

View File

@@ -22,6 +22,7 @@ import SignupFormWrapper from "@/components/Blocks/DynamicContent/SignupFormWrap
import NextStay from "@/components/Blocks/DynamicContent/Stays/NextStay"
import PreviousStays from "@/components/Blocks/DynamicContent/Stays/Previous"
import UpcomingStays from "@/components/Blocks/DynamicContent/Stays/Upcoming"
import { SJWidget } from "@/components/SJWidget"
import JobylonFeed from "./JobylonFeed"
@@ -84,6 +85,8 @@ function DynamicContentBlocks(props: DynamicContentProps) {
preamble={dynamic_content.subtitle}
/>
)
case DynamicContentEnum.Blocks.components.sj_widget:
return <SJWidget />
default:
return null
}

View File

@@ -0,0 +1,50 @@
"use client"
import Script from "next/script"
import { useEffect, useRef, useState } from "react"
import useLang from "@/hooks/useLang"
const SJSupportedLangs = ["en", "sv"] as const
export function SJWidget() {
const lang = useLang()
const [scriptInitialized, setScriptInitialized] = useState(
!!window.SJ?.widget?.init
)
const componentInitialized = useRef(false)
useEffect(() => {
const initWidget = () => {
if (componentInitialized.current === true) return
if (!window.SJ?.widget?.init) return
window.SJ.widget.init({
micrositeId: "12952d0f-c70f-452c-9598-6586a64c7b60",
language: isSJSupportedLang(lang) ? lang : "en",
})
componentInitialized.current = true
}
initWidget()
}, [lang, scriptInitialized])
return (
<>
<Script
src="https://www.sj.se/microsite-widget/microsite-widget.min.js"
strategy="lazyOnload"
onLoad={() => setScriptInitialized(true)}
/>
<div id="sj-widget">&nbsp;</div>
</>
)
}
function isSJSupportedLang(
lang: string
): lang is (typeof SJSupportedLangs)[number] {
return SJSupportedLangs.includes(lang as (typeof SJSupportedLangs)[number])
}

View File

@@ -29,4 +29,9 @@ interface Window {
right?: string
}
}
SJ?: {
widget?: {
init?: (args: { micrositeId: string; language: "en" | "sv" }) => void
}
}
}

View File

@@ -27,6 +27,7 @@ export namespace DynamicContentEnum {
sas_transfer_points: "sas_transfer_points",
sas_tier_comparison: "sas_tier_comparison",
manage_cookie_consent: "manage_cookie_consent",
sj_widget: "sj_widget",
unknown: "unknown",
} as const