import type { GetServerSidePropsContext } from "next"; import { isNotFoundError } from "next/dist/client/components/not-found"; import { getURLFromRedirectError, isRedirectError } from "next/dist/client/components/redirect"; import { notFound, redirect } from "next/navigation"; import { WebAppURL } from "@calcom/lib/WebAppURL"; export type EmbedProps = { isEmbed?: boolean; }; export default function withEmbedSsrAppDir>( getData: (context: GetServerSidePropsContext) => Promise ) { return async (context: GetServerSidePropsContext): Promise => { const { embed, layout } = context.query; try { const props = await getData(context); return { ...props, isEmbed: true, }; } catch (e) { if (isRedirectError(e)) { const destinationUrl = getURLFromRedirectError(e); let urlPrefix = ""; // Get the URL parsed from URL so that we can reliably read pathname and searchParams from it. const destinationUrlObj = new WebAppURL(destinationUrl); // If it's a complete URL, use the origin as the prefix to ensure we redirect to the same domain. if (destinationUrl.search(/^(http:|https:).*/) !== -1) { urlPrefix = destinationUrlObj.origin; } else { // Don't use any prefix for relative URLs to ensure we stay on the same domain urlPrefix = ""; } const destinationQueryStr = destinationUrlObj.searchParams.toString(); // Make sure that redirect happens to /embed page and pass on embed query param as is for preserving Cal JS API namespace const newDestinationUrl = `${urlPrefix}${destinationUrlObj.pathname}/embed?${ destinationQueryStr ? `${destinationQueryStr}&` : "" }layout=${layout}&embed=${embed}`; redirect(newDestinationUrl); } if (isNotFoundError(e)) { notFound(); } throw e; } }; }