Open fabriziospadaro opened 5 months ago
Hey @fabriziospadaro! I'm here to help you out with any bugs, questions, or contributions you have. Let's tackle this together!
To resolve the error iframe doesn't exist. createIframe must be called before doInIframe
, you need to ensure that the createIframe
method is called before the doInIframe
method. This error occurs because the doInIframe
method requires the iframe to be created and ready before it can execute its instructions.
Here is a simplified example of how you can ensure that createIframe
is called before doInIframe
:
// Ensure that createIframe is called first
const cal = new Cal('your-namespace', []);
cal.createIframe({
calLink: 'your-cal-link',
queryObject: {},
calOrigin: 'your-cal-origin'
});
// Now you can safely call doInIframe
cal.doInIframe({
method: 'yourMethod',
arg: 'yourArgument'
});
In the context of using @calcom/embed-react
, make sure that the iframe is created during the component's lifecycle before any operations that require the iframe are performed. For example, you can use the useEffect
hook in a React component to ensure the iframe is created when the component mounts:
import React, { useEffect } from 'react';
import { Cal } from '@calcom/embed-react';
const YourComponent = () => {
useEffect(() => {
const cal = new Cal('your-namespace', []);
cal.createIframe({
calLink: 'your-cal-link',
queryObject: {},
calOrigin: 'your-cal-origin'
});
// Now you can safely call doInIframe
cal.doInIframe({
method: 'yourMethod',
arg: 'yourArgument'
});
}, []);
return (
<div>
{/* Your component JSX */}
</div>
);
};
export default YourComponent;
Additionally, ensure that the iframe is properly initialized and set up. According to the embed-iframe-init.ts
file from Cal.com, the EmbedInitIframe
function is responsible for setting up the iframe and ensuring it is ready for interaction. This function checks for the namespace in the query parameters or window.name
, sets the isEmbed
flag, and applies CSS variables for the theme. This initialization is crucial for the iframe's readiness.
By ensuring that createIframe
is called before doInIframe
and that the iframe is properly initialized using the EmbedInitIframe
function, you can avoid the error and ensure that the iframe is properly set up before any operations are performed on it [1][2][3].
To continue talking to Dosu, mention @dosu.
I'm facing the same issue and I'm not able to solve. any help here?
@dosu the proposed solution is not working
@dosu @dosubot you left code that is irrelevant to the example provided. the snippet we are given as developers is as the OP mentioned:
useEffect(() => {
(async function () {
const cal = await getCalApi();
cal("ui", {
"theme": "light",
"styles": { "branding": { "brandColor": "#2B5ADC" } },
"hideEventTypeDetails": false,
"layout": "month_view",
});
})();
}, [])
there are no createIframe
or doInIframe
methods being used or provided in the snippet that cal.com gives us.
Any update for this? My sentry is going crazy 😮💨
To address the issue with the error message "iframe doesn't exist. createIframe must be called before doInIframe" in the context of using the @calcom/embed-react
package, it's important to ensure that the iframe is fully initialized before any operations are performed on it. The getCalApi
function is designed to handle this initialization process.
Here's a refined approach using the getCalApi
function:
Ensure Initialization: The getCalApi
function should be called to initialize the Cal API, which will handle the iframe setup. Make sure this is done before any UI operations.
Check for Readiness: Use the event-driven approach to ensure the iframe is ready. The package listens for the __iframeReady
event to confirm the iframe is ready for operations.
Here's how you can adjust your code:
import Cal, { getCalApi } from "@calcom/embed-react";
import { useEffect } from "react";
export default function CalWidget({ calLink }) {
useEffect(() => {
(async function () {
const cal = await getCalApi();
// Ensure the iframe is ready before performing UI operations
cal.on("__iframeReady", () => {
cal("ui", {
"theme": "light",
"styles": { "branding": { "brandColor": "#2B5ADC" } },
"hideEventTypeDetails": false,
"layout": "month_view",
});
});
})();
}, []);
return (
<Cal
id="book"
onScrollCapture={(e) => {
e.stopPropagation();
}}
calLink={calLink}
/>
);
}
This approach ensures that the UI operations are only executed once the iframe is fully initialized and ready, preventing the error from occurring.
To continue talking to Dosu, mention @dosu.
@dosu The correct api to use should be:
cal("on", {
action: "__iframeReady",
callback: (e) => {
cal("ui",
{
"theme": "light",
"styles": {
"branding": { "brandColor": "#2B5ADC" },
},
"layout": "month_view",
});
}
});
but this still doesn't fix the issue.
To address the issue with the error message "iframe doesn't exist. createIframe must be called before doInIframe" when using the @calcom/embed-react
package, it's crucial to ensure that the iframe is fully initialized before performing any operations on it. The __iframeReady
event is key to confirming the iframe's readiness.
Here's how you can adjust your code to ensure the iframe is ready before executing UI operations:
import Cal, { getCalApi } from "@calcom/embed-react";
import { useEffect } from "react";
export default function CalWidget({ calLink }) {
useEffect(() => {
(async function () {
const cal = await getCalApi();
// Use the correct API to listen for the iframe readiness
cal("on", {
action: "__iframeReady",
callback: () => {
cal("ui", {
"theme": "light",
"styles": {
"branding": { "brandColor": "#2B5ADC" },
},
"layout": "month_view",
});
}
});
})();
}, []);
return (
<Cal
id="book"
onScrollCapture={(e) => {
e.stopPropagation();
}}
calLink={calLink}
/>
);
}
This setup ensures that the UI configuration is applied only after the __iframeReady
event is triggered, indicating that the iframe is fully initialized and ready for interaction. If the issue persists, double-check that the getCalApi
function is correctly initializing the API and that the event listener is properly set up to handle the __iframeReady
event.
To continue talking to Dosu, mention @dosu.
I was getting this error both in dev and the built server but with all functionality working. Looking at the iframe after rendering, I see the the following:
<iframe class="cal-embed" name="cal-embed=" .../>
with the name attribute looking like there's something missing on the name=
.
Not even sure this is the relevant code but it looks like it should be set to namespace.
So I added the namespace parameter to my code and the error went away:
useEffect(() => {
(async function () {
const cal = await getCalApi({ namespace: "nynamespace" });
cal("ui", {
theme: "light",
styles: {
branding: { brandColor: "white" },
},
});
})();
}, []);
Buuuuuuut the iframe still has name="cal-embed="
.
@dosu what do you think?
Bug Report: iframe doesn't exist.
createIframe
must be called beforedoInIframe
Issue Summary
When embedding an iframe in a Next.js page, an error occurs after building the page:
iframe doesn't exist. createIframe must be called before doInIframe
. This issue does not occur during development (npm run dev
). Note that the iframe embed still works, and all the functionalities are preserved.Steps to Reproduce
@calcom/embed-react
.Use the following code snippet in your component:
npm run dev
and verify that the page works as expected.npm run build
and then start the server usingnpm start
.Actual Results
iframe doesn't exist. createIframe must be called before doInIframe
is displayed.Expected Results
npm run dev
).CAL-3893