I have a small chat app that I want to be like a chatbot on any other website but I do not want to use iframe for it. I checked dialogflow messenger and it does not seem to be using iframe but uses shadow dom to render the messenger.
class ChatWidgetSDK extends HTMLElement {
static observedAttributes = ["height", "width"];
constructor() {
super();
const shadow = this.attachShadow({ mode: "open" });
// Default settings
this.settings = {
buttonColor: "#007bff",
buttonText: "💬",
chatUrl: "http://localhost:8080",
width: "300px",
height: "400px",
position: { bottom: "20px", right: "20px" },
};
// Create chat button
this.chatButton = document.createElement("button");
this.chatButton.id = "chat-button";
this.chatButton.innerHTML = this.settings.buttonText;
// Create chat modal
this.chatModal = document.createElement("div");
this.chatModal.id = "chat-modal";
this.chatModal.innerHTML = `
<iframe
id="chat-iframe"
src="${this.settings.chatUrl}"
style="width: 100%; height: 100%; border: none;"
></iframe>
`;
this.chatModal.style.display = "none"; // Initially hidden
// Apply styles
this.applyStyles();
// Attach elements
shadow.appendChild(this.chatButton);
shadow.appendChild(this.chatModal);
// Attach event listeners
this.attachEventListeners();
}
applyStyles() {
const style = document.createElement("style");
style.textContent = `
#chat-button {
position: fixed;
bottom: ${this.settings.position.bottom};
right: ${this.settings.position.right};
width: 60px;
height: 60px;
border-radius: 50%;
background-color: ${this.settings.buttonColor};
color: #fff;
border: none;
cursor: pointer;
font-size: 24px;
z-index: 1000;
}
#chat-modal {
display: none;
position: fixed;
bottom: calc(${this.settings.position.bottom} + 70px);
right: ${this.settings.position.right};
width: ${this.settings.width};
height: ${this.settings.height};
border: none;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
z-index: 1000;
background: #fff;
overflow: hidden;
}
`;
this.shadowRoot.appendChild(style);
}
// For open and close of the chat modal
attachEventListeners() {
this.chatButton.addEventListener("click", () => {
if (this.chatModal.style.display === "none") {
this.chatModal.style.display = "block";
} else {
this.chatModal.style.display = "none";
}
});
}
openChat() {
this.chatModal.style.display = "block";
}
closeChat() {
this.chatModal.style.display = "none";
}
// Is used to add custom settings to the given param
attributeChangedCallback(name, oldValue, newValue) {
if (oldValue !== newValue) {
this.settings[name] = newValue;
this.applyStyles();
}
}
}
// Define the custom element
customElements.define("chat-widget-sdk", ChatWidgetSDK);
this is what am doing currently but it uses iframe to render the app but I would like to do it without the iframe, so is there a way to do this?. Any suggestions or solutions that I can use to do this?