diff --git a/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/MeetingsAndConferences/index.tsx b/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/MeetingsAndConferences/index.tsx index ee7c62be7..5f7e1fb92 100644 --- a/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/MeetingsAndConferences/index.tsx +++ b/apps/scandic-web/components/ContentType/HotelPage/SidePeeks/MeetingsAndConferences/index.tsx @@ -2,6 +2,8 @@ import ButtonLink from "@scandic-hotels/design-system/ButtonLink" import SidePeek from "@scandic-hotels/design-system/SidePeek" import { Typography } from "@scandic-hotels/design-system/Typography" +import { env } from "@/env/server" + import { getIntl } from "@/i18n" import { appendSlugToPathname } from "@/utils/appendSlugToPathname" @@ -21,6 +23,7 @@ export default async function MeetingsAndConferencesSidePeek({ heading, }: MeetingsAndConferencesSidePeekProps) { const intl = await getIntl() + const shouldInert = env.SEO_INERT const { seatingText, roomText } = await getConferenceRoomTexts(meetingRooms) const visibleImages = meetingFacilities?.heroImages.slice(0, 2) const meetingPageHref = await appendSlugToPathname(meetingPageUrl) @@ -33,6 +36,7 @@ export default async function MeetingsAndConferencesSidePeek({ id: "common.close", defaultMessage: "Close", })} + shouldInert={shouldInert} >
diff --git a/apps/scandic-web/env/server.ts b/apps/scandic-web/env/server.ts index ae1cf11e8..e3f36661c 100644 --- a/apps/scandic-web/env/server.ts +++ b/apps/scandic-web/env/server.ts @@ -107,6 +107,11 @@ export const env = createEnv({ // transform to boolean .transform((s) => s === "true") .default("false"), + SEO_INERT: z + .string() + .refine((s) => s === "1" || s === "0") + .transform((s) => s === "1") + .default("0"), }, emptyStringAsUndefined: true, runtimeEnv: { @@ -162,5 +167,6 @@ export const env = createEnv({ HOTEL_BRANDING: process.env.HOTEL_BRANDING, CHATBOT_LIVE_LANGS: process.env.CHATBOT_LIVE_LANGS, NEW_STAYS_ON_MY_PAGES: process.env.NEW_STAYS_ON_MY_PAGES, + SEO_INERT: process.env.SEO_INERT, }, }) diff --git a/packages/design-system/lib/components/SidePeek/SelfControlled/SidePeekSEO.tsx b/packages/design-system/lib/components/SidePeek/SelfControlled/SidePeekSEO.tsx deleted file mode 100644 index 4ba5b7638..000000000 --- a/packages/design-system/lib/components/SidePeek/SelfControlled/SidePeekSEO.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import type { SidePeekSelfControlledProps } from './sidePeek' - -// Sidepeeks generally have important content that should be indexed by search engines. -// The content is hidden behind a modal, but it is still important for SEO. -// This component is used to provide SEO information for the sidepeek content. -export default function SidePeekSEO({ - title, - children, -}: React.PropsWithChildren>) { - return ( -
-

{title}

- {children} -
- ) -} diff --git a/packages/design-system/lib/components/SidePeek/SelfControlled/index.tsx b/packages/design-system/lib/components/SidePeek/SelfControlled/index.tsx index 074d000d4..d1c4f4c31 100644 --- a/packages/design-system/lib/components/SidePeek/SelfControlled/index.tsx +++ b/packages/design-system/lib/components/SidePeek/SelfControlled/index.tsx @@ -11,7 +11,7 @@ import { IconButton } from '../../IconButton' import { MaterialIcon } from '../../Icons/MaterialIcon' import { Typography } from '../../Typography' -import SidePeekSEO from './SidePeekSEO' +import SidePeekSEO from '../SidePeekSEO' import styles from './sidePeekSelfControlled.module.css' diff --git a/packages/design-system/lib/components/SidePeek/SidePeekSEO.tsx b/packages/design-system/lib/components/SidePeek/SidePeekSEO.tsx index 56341c847..4e6048bab 100644 --- a/packages/design-system/lib/components/SidePeek/SidePeekSEO.tsx +++ b/packages/design-system/lib/components/SidePeek/SidePeekSEO.tsx @@ -1,5 +1,6 @@ interface SidePeekSEOProps { title: string + shouldInert?: boolean } // Sidepeeks generally have important content that should be indexed by search engines. @@ -7,10 +8,15 @@ interface SidePeekSEOProps { // This component is used to provide SEO information for the sidepeek content. export default function SidePeekSEO({ title, + shouldInert = false, children, }: React.PropsWithChildren) { return ( -
+ // Both inert and sr-only to ensure that the content is not focusable + // or visible to screen readers but still available for SEO. + // The other possible options, such as aria-hidden and the hidden attribute, + // are less suitable for SEO purposes. +

{title}

{children}
diff --git a/packages/design-system/lib/components/SidePeek/index.tsx b/packages/design-system/lib/components/SidePeek/index.tsx index 0959f9f13..e7925472e 100644 --- a/packages/design-system/lib/components/SidePeek/index.tsx +++ b/packages/design-system/lib/components/SidePeek/index.tsx @@ -20,6 +20,7 @@ interface SidePeekProps { openInRoot?: boolean handleClose?: (isOpen: boolean) => void closeLabel: string + shouldInert?: boolean } export default function SidePeek({ @@ -30,6 +31,7 @@ export default function SidePeek({ isOpen, openInRoot = false, closeLabel, + shouldInert, }: React.PropsWithChildren) { const rootDiv = useRef(null) const headerRef = useRef(null) @@ -116,7 +118,9 @@ export default function SidePeek({
- {children} + + {children} + ) }