Skip to content

Commit fa0a18b

Browse files
fix: Allow backgroundSlotsFetch option to disable slots fetching during prerender (calcom#21999)
* fix: Allow noBackgroundSlotsFetch option to disable slots fetching during prerender * Update packages/embeds/embed-core/src/embed-iframe.ts Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com> --------- Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
1 parent 80e2118 commit fa0a18b

3 files changed

Lines changed: 30 additions & 12 deletions

File tree

packages/embeds/embed-core/src/embed-iframe.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,9 @@ function main() {
594594
return;
595595
}
596596

597+
const willSlotsBeFetched = url.searchParams.get("cal.skipSlotsFetch") !== "true";
598+
log(`Slots will ${willSlotsBeFetched ? "" : "NOT "}be fetched`);
599+
597600
window.addEventListener("message", (e) => {
598601
const data: Message = e.data;
599602
if (!data) {
@@ -631,7 +634,7 @@ function main() {
631634
if (url.searchParams.get("preload") !== "true" && window?.isEmbed?.()) {
632635
initializeAndSetupEmbed();
633636
} else {
634-
log(`Preloaded scenario - Skipping initialization and setup`);
637+
log(`Preloaded scenario - Skipping initialization and setup as only assets need to be loaded`);
635638
}
636639
}
637640

@@ -679,6 +682,7 @@ function actOnColorScheme(colorScheme: string | null | undefined) {
679682

680683
/**
681684
* Apply configurations to the preloaded page and then ask parent to show the embed
685+
* If there is a need to fetch the slots, then the slots would be fetched and then only this function call would complete
682686
* url has the config as params
683687
*/
684688
async function connectPreloadedEmbed({

packages/embeds/embed-core/src/embed.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,26 +1215,26 @@ describe("Cal", () => {
12151215
expect(result).toBe("noAction");
12161216
});
12171217

1218-
it("should return connect-no-slots-fetch when reuseFully is true and slots are not stale", () => {
1218+
it("should return connect-no-slots-fetch when backgroundSlotsFetch is true and slots are not stale", () => {
12191219
const result = calInstance.getNextActionForModal({
12201220
...baseArgs,
12211221
stateData: {
12221222
...baseArgs.stateData,
12231223
prerenderOptions: {
1224-
reuseFully: true,
1224+
backgroundSlotsFetch: true,
12251225
},
12261226
},
12271227
});
12281228
expect(result).toBe("connect-no-slots-fetch");
12291229
});
12301230

1231-
it("should return connect when reuseFully is true but slots are stale", () => {
1231+
it("should return connect when backgroundSlotsFetch is true but slots are stale", () => {
12321232
const result = calInstance.getNextActionForModal({
12331233
...baseArgs,
12341234
stateData: {
12351235
...baseArgs.stateData,
12361236
prerenderOptions: {
1237-
reuseFully: true,
1237+
backgroundSlotsFetch: true,
12381238
},
12391239
previousEmbedRenderStartTime: Date.now() - EMBED_MODAL_IFRAME_SLOT_STALE_TIME - 1,
12401240
embedRenderStartTime: Date.now(),

packages/embeds/embed-core/src/embed.ts

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ type ModalPrerenderOptions = {
5555
slotsStaleTimeMs?: number;
5656
iframeForceReloadThresholdMs?: number;
5757
reuseFully?: boolean;
58+
// Default value is true right now but it would change soon
59+
backgroundSlotsFetch?: boolean;
5860
};
5961

6062
type ModalStateData = {
@@ -598,7 +600,7 @@ export class Cal {
598600
return "fullReload";
599601
}
600602

601-
if (prerenderOptions?.reuseFully && !areSlotsStale) {
603+
if (prerenderOptions?.backgroundSlotsFetch && !areSlotsStale) {
602604
return "connect-no-slots-fetch";
603605
}
604606

@@ -986,6 +988,7 @@ class CalApi {
986988
const isHeadlessRouterPath = calLinkUrlObject ? isRouterPath(calLinkUrlObject.toString()) : false;
987989

988990
if (__prerender && this.cal.modalBox) {
991+
log("Destroying previous prerendered modalbox");
989992
// If we are re-prerendering, we destroy the previous modalbox, allowing user to prerender as many times as they want
990993
this.cal.modalBox.remove();
991994
}
@@ -999,9 +1002,18 @@ class CalApi {
9991002
const containerEl = document.body;
10001003
this.cal.isPrerendering = !!__prerender;
10011004
if (__prerender) {
1002-
// TODO: Make `reuseFully` a configurable param as well later.
1003-
// If someone's preloading the headless router path, we must reuse the iframe fully as is as Router would redirect to a Booking Page and that should be shown as is
1004-
this.prerenderOptions = { ...prerenderOptions, reuseFully: isHeadlessRouterPath };
1005+
// While prerendering headless router path, we by default want to fetch slots in background(for the time being)
1006+
// For other prerenderings, we don't want to fetch slots in background - Keeping the behaviour same as before
1007+
const DEFAULT_BACKGROUND_SLOTS_FETCH = isHeadlessRouterPath ? true : false;
1008+
const backgroundSlotsFetch =
1009+
typeof prerenderOptions.backgroundSlotsFetch === "undefined"
1010+
? DEFAULT_BACKGROUND_SLOTS_FETCH
1011+
: prerenderOptions.backgroundSlotsFetch;
1012+
1013+
this.prerenderOptions = {
1014+
...prerenderOptions,
1015+
backgroundSlotsFetch,
1016+
};
10051017
// Add prerender query param
10061018
config.prerender = "true";
10071019

@@ -1010,7 +1022,7 @@ class CalApi {
10101022
config["cal.queueFormResponse"] = "true";
10111023
}
10121024

1013-
if (!this.prerenderOptions?.reuseFully) {
1025+
if (!backgroundSlotsFetch) {
10141026
// When prerendering, we don't want to preload slots as they might be outdated anyway by the time they are used
10151027
// Also, when used with Headless Router attributes setup, we might endup fetching slots for a lot of people, which would be a waste and unnecessary load on Cal.com resources
10161028
config["cal.skipSlotsFetch"] = "true";
@@ -1045,9 +1057,11 @@ class CalApi {
10451057
isConnectionInitiated,
10461058
prerenderOptions: this.prerenderOptions ?? null,
10471059
};
1060+
const lastLoadedUrlObject = this.cal.getLastLoadedLinkInframe();
1061+
const lastLoadedPathIsRouter = lastLoadedUrlObject?.pathname?.includes("/router");
10481062

1049-
// If we want to reuse fully then we shouldn't submit response again
1050-
if (isHeadlessRouterPath && !this.prerenderOptions?.reuseFully) {
1063+
// TODO: This branch needs to be removed as we don't want to support this use case anymore.
1064+
if (isHeadlessRouterPath && !lastLoadedPathIsRouter) {
10511065
// Immediately take it to loading state. Either through connect or through loadInIframe, it would later be updated
10521066
existingModalEl.setAttribute("state", "loading");
10531067

0 commit comments

Comments
 (0)