You definitely need to use window.addEventListener
and window.removeEventListener
. I also recommend using connectedCallback instead of constructor (though it should work either way).
import { LightningElement } from "lwc";
export default class App extends LightningElement {
message = 'none received (yet)'
connectedCallback() {
window.addEventListener('message', this.receiveMessage);
}
disconnectedCallback() {
window.removeEventListener('message', this.receiveMessage);
}
receiveMessage = (event) => {
this.message = event.data
}
}
import { LightningElement, api } from "lwc";
export default class Child extends LightningElement {
sendMessage() {
window.postMessage('hello world', '*');
}
}
Note that arrow functions keep their this
reference to the class. If you use a normal function, you instead must use bind instead.
#receiveMessageCallback;
connectedCallback() {
this.#receiveMessageCallback = this.receiveMessage.bind(this);
window.addEventListener('message', this.#receiveMessageCallback);
}
disconnectedCallback() {
window.removeEventListener('message', this.#receiveMessageCallback);
}
We need to store the original event handler (#receiveMessageCallback
), otherwise we will leak memory when the component unloads.
Demo.